iOS: закрытие и представление ModalViewController без доступа к его родительскому ViewController

Предыстория: я хотел бы закрыть modalView, который я представил ранее, и сразу представить тот же самый viewController, который я только что закрыл, с новой информацией.

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

Возможная зацепка. Я экспериментировал с несколькими вещами:

1.) Пытаюсь получить доступ к родительскому ViewController, что на данный момент не знаю как.

2.) Как только доступ к родителю получен, я могу просто применить следующий код:

UIViewController* toPresentViewController = [[UIViewController alloc] init];
    [self dismissViewControllerAnimated:YES completion:^{
        [parentViewControllerAccessor presentModalViewController:toPresentViewController animated:YES];
}];

Теоретически это должно работать, учитывая доступ к родительскому viewController. Я открыт для других способов сделать это.

Предположение. У вас нет разрешения на изменение какого-либо кода в родительском ViewController.


person Byte    schedule 11.06.2012    source источник


Ответы (4)


Ваш код выглядит так, как будто он должен работать. Если вы используете iOS 5, есть свойство UIViewController с именем presentingViewController.

@property(nonatomic, readonly) UIViewController *presentingViewController;

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

Примечание. В iOS 4 parentViewController будет установлен на представляющий контроллер, поэтому, если вы поддерживаете iOS 4 и 5, вам нужно будет сначала проверить версию ОС, чтобы решить, к какому свойству получить доступ. В iOS 5 Apple исправила это, так что parentViewController теперь используется исключительно для родителя содержащихся контроллеров представления (см. раздел Реализация контейнерного контроллера представления в документации UIViewController).

Редактировать: Относительно доступа к self.presentingViewController из блока: к моменту вызова блока (после закрытия модального контроллера представления) свойство presentingViewController может быть установлено равным нулю. Помните, что self.presentingViewController внутри блока дает значение свойства при выполнении блока, а не при его создании. Для защиты от этого сделайте следующее:

UIViewController* toPresentViewController = [[UIViewController alloc] init];
UIViewController* presentingViewController = self.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^
{
    [presentingViewController presentModalViewController:toPresentViewController animated:YES];
}];

Это необходимо не потому, что self пропало/отклонено (оно благополучно сохраняется блоком), а потому, что оно больше не представлено, поэтому его presentingViewController теперь равно нулю. Нет необходимости хранить presentingViewController где-либо еще, локальная переменная подойдет, потому что она будет сохранена блоком.

person jhabbott    schedule 11.06.2012
comment
Если я правильно понимаю, я должен изменить этот код: [parentViewControllerAccessor presentModalViewController:toPresentViewController animated:YES]; на [self.presentingViewController presentModalViewController:croppedPhotoVC animated:YES];. К сожалению, похоже, это не работает. Я что-то неправильно понимаю? - person Byte; 12.06.2012
comment
Это, вероятно, связано с тем, как блоки сохраняют объекты — он сохранит себя, но не контроллер представления представления, поэтому к тому времени, когда «я» будет отклонено, это свойство может быть установлено равным нулю. Установите для self.presentingViewController локальную переменную вне блока, а затем используйте эту переменную внутри блока. - person jhabbott; 12.06.2012
comment
К такому же выводу пришел и я. Возможно, мне придется создать статическую переменную для хранения, чтобы при удалении self метод все еще работал. Но это больше похоже на взлом. - person Byte; 12.06.2012
comment
Вам не нужно хранить его в статике, блок сохранит для вас локальную переменную. Я отредактировал свой ответ, чтобы показать вам, как это сделать. - person jhabbott; 13.06.2012

Вы можете сделать это с помощью уведомлений.

Например, запустите это уведомление из-за пределов модального представления, когда вы хотите, чтобы оно было закрыто:

[[NSNotificationCenter defaultCenter] postNotificationName:@"dismissModalView" 
                                                    object:nil 
                                                  userInfo:nil];

А затем обработайте это уведомление внутри вашего модального представления:

- (void)viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(dismissMe:)
                                                 name:@"dismissModalView" 
                                               object:nil];
}

- (void)dismissMe:(NSNotification)notification {
    // dismiss it here.
}
person melsam    schedule 11.06.2012
comment
А затем обработайте это уведомление внутри вашего модального представления: я не уверен, что это должно означать, я прямо сказал, что не могу трогать код предыдущего viewController, который представляет этот viewController. Разве, я что-то неправильно понимаю здесь? - person Byte; 12.06.2012

решение для ios5:

-(void)didDismissModalView:(id)sender {

   // Dismiss the modal view controller
   int sold=0;

   if(sold==0){

      //Cash_sold.delegate = self;
      // Cash_sold.user_amount.text=[NSString stringWithFormat:@"%d",somme];

      Cash_sold = [[CashSoldview alloc] initWithNibName:@"CashSoldview" bundle:nil];
      CGRect fram1 = CGRectMake(200,20,400,400);
      Cash_sold.view.superview.frame = fram1;
      Cash_sold.view.frame=fram1;
      Cash_sold.modalTransitionStyle= UIModalTransitionStyleCoverVertical;
      Cash_sold.modalPresentationStyle=UIModalPresentationFormSheet;

      UIViewController* presentingViewController = self.parentViewController;

      [self dismissViewControllerAnimated:YES completion:^
      {
         [presentingViewController presentModalViewController:Cash_sold animated:YES];
      }];     
   }
}
person hans    schedule 26.07.2012

Попробуйте следующий код:

[self dismissViewControllerAnimated:NO 
                         completion:^{
  // instantiate and initialize the new controller
  MyViewController *newViewController = [[MyViewController alloc] init];
  [[self presentingViewController] presentViewController:newViewController
                                                animated:NO
                                              completion:nil];
}];
person ennalax    schedule 26.07.2012