2009-07-23 4 views
0

Я хотел бы представить несколько модальных представлений в последовательности (например, показать страницу подтверждения после выбора изображения из подборщика изображений). Моя проблема заключается в том, что анимация увольнения и презентации в последующих шагах без задержки всегда приводит к сбою приложения с EXC_BAD_ACCESS.Несколько модальных представлений Crash App

Я предполагаю, что проблема заключается в том, что CoreAnimation не проводит различия между двумя переходами и не может правильно определить, закончился или нет первый.

Моя работа до сих пор заключается в том, чтобы ввести задержка в 1 секцию, которая, похоже, решает проблему. Тем не менее, я думаю, что это делает код немного хрупким. Есть ли другой способ?

Это ошибка в UIKit, и я должен представить отчет об ошибке?

Пример кода

Вот простой случай, воспроизвести аварии:

  1. Создать новый вид на основе проекта с помощью следующего класса как реализации основного контроллера

  2. Хит «отменить» при отображении изображения.

Ожидаемое поведение: вид сборщика уволен и представлен снова из-за последующего вызова в viewDidAppear.

Фактическое поведение: он падает со следами стека, представленными ниже.

Код:


#import "SampleViewController.h" 

@implementation SampleViewController 

- (void)showModal { 
    UIImagePickerController *picker = [[UIImagePickerController alloc] init]; 
    [self presentModalViewController:picker animated:YES]; 
    // [picker release]; 
} 

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    [self showModal]; // this line crashes the app 
    // the following works as desired 
    // [self performSelector:@selector(showModal) withObject:nil afterDelay:1]; 
} 

@end 

Краш Стек след:

 
#0 0x30b43212 in -[UIWindowController transitionViewDidComplete:fromView:toView:] 
#1 0x3095828e in -[UITransitionView notifyDidCompleteTransition:] 
#2 0x3091af0d in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] 
#3 0x3091ad7c in -[UIViewAnimationState animationDidStop:finished:] 
#4 0x00b54331 in run_animation_callbacks 
#5 0x00b54109 in CA::timer_callback 
#6 0x302454a0 in CFRunLoopRunSpecific 
#7 0x30244628 in CFRunLoopRunInMode 
#8 0x32044c31 in GSEventRunModal 
#9 0x32044cf6 in GSEventRun 
#10 0x309021ee in UIApplicationMain 
#11 0x00002794 in main at main.m:14 

ответ

8

Скорее всего, вы должны позволить контекстную анимации закончить. Как вы уже обнаружили

[self performSelector: @selector (showModal) withObject: nil afterDelay: 1];

работы, но, очевидно, имея задержку не хорошо, так что это:

[self performSelector:@selector(showModal) withObject:nil afterDelay:0.0]; 

При использовании afterDelay: 0.0 не напрямую вызывать селектор, вместо этого он ставит в очередь на вызов на вашем runloop , который позволяет всем вашим состояниям (пулам авторесурсов, контекстам анимации и т. д.) uwnind правильно, а затем немедленно вызывает ваш вызов, когда runloop начинает обработку событий.

Тот вопрос, который может Круп, чтобы пользователи могли получить UIEvents поднятием, нажав на экран, но вы можете исправить это с помощью вызова этого, прежде чем вы анимация начинается

[[UIApplication sharedApplication] beginIgnoringInteractionEvents]; 

и это только у вас есть Окончательные модальный на экране

[[UIApplication sharedApplication] endIgnoringInteractionEvents]; 

Как правило, вы хотите провести взаимодействие пользовательского интерфейса во время анимации быстрых переходов в любом случае.

+0

использование 0.0 как задержка решает проблему! Благодаря! – notnoop

+1

+1 для предложения 'beginIgnoringInteractionEvents'. Никогда не знал об этом раньше. – chakrit

Смежные вопросы