Подтвердить что ты не робот

Представление контроллера модального вида сразу после отклонения другого

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

 [self dismissModalViewControllerAnimated:YES];

 UIImagePickerController *picker = [[UIImagePickerController alloc] init];
 picker.delegate = self;
 picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
 [self presentModalViewController:picker animated:YES];

Первый модальный VC слайд вниз, но новый picker никогда не появляется. Любая идея о том, что происходит?

4b9b3361

Ответ 1

Как и другие анимированные вещи, dismissModalViewControllerAnimated не блокируется, пока контроллер представления не исчезнет. Вместо этого он "отменяет" увольнение контроллера вида. Возможно, вам придется использовать обратный вызов в viewDidDisappear для модального контроллера 1, который вызывает нечто вроде modalViewControllerDisappeared в родительском контроллере представления. В этом методе вы представляете modal controller 2. В противном случае, что сказал Robot K.

Ответ 2

Август 2012 Обновление:

iOS 5 и более ввели более безопасные API-интерфейсы для выполнения действий после того, как модалы анимировали/вне места с использованием блоков завершения:

[self presentViewController:myModalVC animated:YES completion:^{}];
[self dismissViewControllerAnimated:YES completion:^{}];

До августа 2012 г. Ответ:

Я столкнулся с аналогичной проблемой при отклонении модальной формы, а затем быстро и быстро представлял модальные два. Иногда модальные два показывали после того, как модальный был уволен, а иногда модальные два вообще не появлялись, и это меня очень огорчило.

Похоже на состояние гонки для меня...

Положив 1 + вторую задержку на вызывающего метода, который представил модальный два, showModalTwo, сделал модальные два появлялись каждый раз после того, как модальный был уволен:

- (void)didDismissModalOne {
    [self performSelector:@selector(showModalTwo:) 
               withObject:someNumber 
               afterDelay:1.0f];
}

Это подтвердило подозрение, что между увольнением модального и представлением модальных двух было какое-то расы. Однако откладывание задержки на вызывающем абоненте является неэлегантным и не гарантирует, что состояние гонки не будет появляться при других обстоятельствах.

Проблема

Оказывается, что UIViewController имеет общедоступное свойство modalViewController, которое устанавливается, когда presentModalViewController:animated: вызывается и срывается при вызове dismissModalViewControllerAnimated:. Уловка заключается в том, что он не прерывается синхронно, поэтому можно создать гонку между удалением старого значения modalViewController и настройкой нового значения следующим образом.

  • Присутствует модальная. myViewController.modalViewController теперь указывает на модальный
  • Откажитесь от модального. Начался фоновый процесс для сбрасывания myViewController.modalViewController, но myViewController.modalViewController все еще указывает на модальный
  • Присутствует модальный два, myViewController.modalViewController] теперь указывает на модальные два
  • Авария обратного вызова системы, установка myViewController.modalViewController на nil, это прерывает процесс анимации модальных двух, и результат не видит пользователь.

Гонка начинается на шаге 2 и проявляется на шаге 4.

Решение

Мое решение состояло в том, чтобы поставить условие охраны на метод, который представил модальный два, чтобы гарантировать, что myViewControoler.modalViewController был nil, прежде чем пытаться представить модальные два.

-(void)showModalTwo:(NSNumber *)aParameter {

    if (self.modalViewController) {        
            [self performSelector:@selector(showModalTwo:)
                       withObject:aParameter 
                       afterDelay:0.1f];
            return;
    }
    // You can now present the second modal safely.
}

Работал как шарм. Более элегантное решение может включать тайм-аут.

Сообщение script

Мне действительно не понравился вопрос опроса этого решения. @Nimrod предлагает в принятом ответе на этот вопрос, что вы можете безопасно инициировать презентацию модальных двух из метода viewDidDisappear: модального. Мне понравился звук этого подхода, основанного на событиях, но после полной реализации в моем случае использования я подтвердил, что условие гонки сохранялось при представлении модальных двух, используя обратный вызов внутри viewDidDisappear:. Единственный способ быть абсолютно уверенным в том, что модальные два будут представлены, - это опрос внутри родительского контроллера представления, пока вы не убедитесь, что self.modalViewController - nil. Тогда и только тогда это "безопасно", чтобы поп модальные два.

Ответ 3

[self dismissViewControllerAnimated:YES completion:^{
    //Present the new MVC 

}];

Примечание. Доступно iOS 5.0 и далее.

Ответ 4

[self dismissModalViewControllerAnimated:NO];

 UIImagePickerController *picker = [[UIImagePickerController alloc] init];
 picker.delegate = self;
 picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
 [self presentModalViewController:picker animated:YES];

Ответ 5

Что происходит, так это то, что контроллер вида удаляет ссылку на контроллер модального представления после того, как анимация увольнения завершена, что происходит после вызова этого кода, поэтому он не думает, что у него есть новый контроллер представления для представления модально.

Как я справился с этим, нужно установить didDismissModalVC ivar на YES после вызова dismissModalViewController. Затем в моем методе viewDidAppear: я проверяю значение ivar и присутствует, а затем новый контроллер модального представления. (Вспоминая также вернуть значение NO, чтобы я не застрял на вечном увольнении контроллеров modal view.)

Ответ 6

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

Протокол определения контроллера родительского представления:

@protocol ParentViewControllerDelegate
- (void)showModalTwo;
@end

Я реализую этот протокол в родительском контроллере представления, чтобы показать второй контроллер модального представления и создать свойство делегата @property id<ParentViewControllerDelegate> delegate; на первом модульном контроллере представления.

Показать первый контроллер модального представления с родительского контроллера:

TheFirstModalViewController *controller = ...
controller.delegate = self;
[self presentViewController:controller animated:YES completion:nil];
...

В режиме viewDidDisappear: первого модального контроллера просмотра просто вызовите delegate.showModalTwo:, чтобы отобразить второй вид модальности из родительского контроллера представления.

Надеюсь на эту помощь.

Ответ 7

В Swift:

  • Используйте функцию rejectViewController для отклонения первого представленного представления.
  • Используйте функцию rejectViewController блок завершения для вызова функции в mainVC. Эта функция должна вызывать второй VC.

Ваш диспетчер rejectView должен выглядеть следующим образом:

var presentingVC_Delegate: mainLists_PopoverDelegation!

@IBAction fund button_Pressed (sender: AnyObject) {
    self.dismissViewControllerAnimated(true, completion: { finished in
        self.presentingVC_Delegate.presentOtherVC()
        print("DismissVC completion block says hello")
    })
}

В тех случаях, когда в mainVC есть присутствующие другие версии:

func presentSettingsVC () {
    self.performSegueWithIdentifier("present_OtherVC", sender: nil)
}

Ответ 8

Здесь мой подход, который, кажется, хорошо работает на iOS 10. Мои обстоятельства несколько отличаются, но должны работать в большинстве ситуаций. Я представляю начальный viewController как popover, который требует, чтобы модальный viewController был представлен немедленно.

Во-первых, в исходном viewController viewDidLoad просто скройте его:

   view.isHidden = true

Затем на нем viewWillAppear, представить модальный viewController, unanimated и не скрывать представление при завершении:

   present(yourModalViewController, animated: false) { [unowned self]
       self.view.isHidden = false
    }

Вы, вероятно, захотите управлять своим состоянием с помощью Bool, чтобы последующие вызовы viewWillAppear не отображали модальный код, но вы получаете идею.