2013-11-09 2 views
2

Теперь этот вопрос частично просил много, но никто не рассматривает, как (или когда) отправляются сообщения -viewWillDisappear & -viewDidDisappear. Практически в каждом примере используется следующая конструкция:UIView removeFromSuperview внутри анимации PROPERLY

[UIView animateWithDuration:0.5 
    delay:1.0 
    options: UIViewAnimationCurveEaseOut 
    animations:^{ 
     yourView.alpha = 0; 
    }completion:^(BOOL finished){ 
     [yourView removeFromSuperview]; // Called on complete 
    }]; 

Проблема в том, что эти сообщения будут отправляться при завершении анимации! Теперь, -addSubview можно анимировать (если положить внутри блока анимации), который отправит соответствующие сообщения (-viewWillAppear & -viewDidAppear) с правильной временной разницей. Таким образом, естественно, что в блоке анимации будет -removeFromSuperview. Это ПОЛУЧИТЬ сообщения правильно, но представление фактически удаляется мгновенно, делая анимацию ... Ну, это не будет оживлять, потому что ничего не осталось для анимации!

Является ли это намеренным яблоко, и если да, то почему? Как вы это делаете правильно?

Спасибо!

Редактировать.

Просто clearify, что я делаю: Я получил пользовательский SEGUE, вертикально оживляющий ребенка-ViewController вниз от верхней части, которая работает, как ожидается, со следующим кодом:

-(void)perform{ 
     UIViewController *srcVC = (UIViewController *) self.sourceViewController; 
     UIViewController *destVC = (UIViewController *) self.destinationViewController; 

     destVC.view.transform = CGAffineTransformMakeTranslation(0.0f, -destVC.view.frame.size.height); 
     [srcVC addChildViewController:destVC]; 
     [UIView animateWithDuration:0.5f 
         animations:^{ 
          destVC.view.transform = CGAffineTransformMakeTranslation(0.0f, 0.0f); 
          [srcVC.view addSubview:destVC.view]; 
         } 
         completion:^(BOOL finished){ 
          [destVC didMoveToParentViewController:srcVC]; 
         }]; 
    } 

Здесь будет в следующем порядке (благодаря -addSubview, находясь внутри анимации-блока):

  1. Добавить childView (автоматически вызывать -willMoveToParentViewController)
  2. -addSubview будет вызывать -viewWillAppear
  3. Когда анимация заканчивается, -addSubview будет вызывать -viewDidAppear
  4. вручную вызвать -didMoveToParentViewController внутри заканчивания-блок

выше точное ожидаемое поведение (так же, как встроенные переходы ведут) ,

С помощью следующего кода, чтобы сделать выше SEGUE, но в обратном направлении (с unwindSegue):

-(void)perform{ 
    UIViewController *srcVC = (UIViewController *) self.sourceViewController; 

    srcVC.view.transform = CGAffineTransformMakeTranslation(0.0f, 0.0f); 
    [srcVC willMoveToParentViewController:nil]; 
    [UIView animateWithDuration:5.5f 
        animations:^{ 
         srcVC.view.transform = CGAffineTransformMakeTranslation(0.0f, -srcVC.view.frame.size.height); 
        } 
        completion:^(BOOL finished){ 
         [srcVC.view removeFromSuperview]; // This can be done inside the animations-block, but will actually remove the view at the same time ´-viewWillDisappear´ is invoked, making no sense! 
         [srcVC removeFromParentViewController]; 
        }]; 
} 

поток будет выглядеть следующим образом:

  1. вручную вызвать -willMoveToParentView:nil уведомить, что он будет удалено
  2. Когда анимация закончится, оба -viewWillDisappear & -viewDidDisappear будут вызываться одновременно (неправильно!) и -removeFromParentViewController будет автоматически lly invoke -didMoveToParentViewController:nil.

И если я теперь двигаться -removeFromSuperview в к анимации-блока, события будут отправлены правильно, но вид удаляется, когда анимация начинается вместо того, когда анимация заканчивается (это та часть, которая не имеет никакого смысла, следуя примеру -addSubview).

+0

Что вы видите, что вы должны ожидать, так как вы удаляете вид мгновенно. В чем проблема с viewWillDisappear и viewDidDisappear, называемым один за другим? Что вы хотите сделать в этих методах, что это проблема? – rdelmar

+0

'yourView' выглядит как объект' UIView', а '-viewWillAppear',' -viewDidAppear', '-viewWillDisappear',' -viewDidDisappear' - это все методы экземпляра 'UIViewController', а не' UIView''s – staticVoidMan

+0

@ rdelmar В моем случае это UnwindSegue, который на '-viewWillDisappear' должен запускать «scrollUp» -анимацию одновременно, чтобы создать приятный эффект. Тем не менее, важно, чтобы сообщения отправлялись, когда вы ожидаете, что они будут работать логически для других кодеров. – helmesjo

ответ

1

Ваш вопрос об удалении контроллера просмотра, потому что, viewWillDisappear и viewDidDisappear - это метод контроля вида.

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

Если вы хотите удалить какое-либо свойство до этой точки, тогда в контроллере дочернего контроллера будет действовать метод willMoveToParentViewController:. Этот метод будет вызван перед блоком анимации. Вот пример кода:

//Prepare view for removeing. 
[self.childViewController willMoveToParentViewController:nil]; 
[UIView animateWithDuration:0.5 
         delay:1.0 
        options: UIViewAnimationOptionCurveEaseOut 
       animations:^{ 
        self.childViewController.view.alpha = 0; 
       }completion:^(BOOL finished){ 
        [self.childViewController.view removeFromSuperview]; 
        [self.childViewController didMoveToParentViewController:self]; 
       }]; 

Таким образом, поток будет:

  1. Первый willMoveToParentViewController: с нулевым параметром будет называться
  2. Animation блок запустится и вид установит это альфа свойство 0
  3. После завершения анимации завершающий блок начнет выполнять ...
  4. [self.childViewController.view removeFromSuperview]; будет называться сначала
  5. Тогда viewWillDissapear: в childViewController будет называться
  6. Тогда [self.childViewController didMoveToParentViewController:self];
  7. И в конце viewDidDissapear: в childViewController будет выполняться.

Pre запрос для этого потока является то, что вы вставляете childViewController с кодом, как это:

[self addChildViewController:self.childViewController];  
[self.view addSubview:self.childViewController.view]; 
[self.childViewController didMoveToParentViewController:self]; 
+0

Спасибо за ваш ответ! Да, эти сообщения отправляются экземпляру View Controller, но вызывается из-за изменений состояния, внесенных в UIView, поэтому я объяснил это таким образом. Я действительно выполняю UnwindSegue, который в основном представляет собой вертикальный слайд вверх (out).Ваше решение по-прежнему не решает проблему, потому что сообщения-viewWillDisappear' & '-viewDidDisappear'ы все еще вызываются одновременно (потому что, как вы говорите, они имеют отношение только к-removeFromSuperview). Так же, как я объяснил с помощью '-addSubview', мне нужно, чтобы эти события синхронизировались с анимацией. – helmesjo

+0

Вы пытались удалить вызов метода «-scrollUp» из «-viewWillDissapear:»? Возможно, вы можете отправить уведомление, чтобы запустить метод «-scrollUp», а не запускать его из «-viewWillDissapear:». Таким образом, вы не зависите от какого-либо метода, который у вас отсутствует. – Igor

+0

Конечно, это вариант, но я бы хотел как можно больше избегать этого, потому что я хочу сделать такие вещи, как эти генерализованные (так как, например, этот разворачивающий сеанс не только предназначен для использования в одном проекте). Это кажется мне странным, потому что, если поведение настолько специфично для «-addSubview», то «-removeFromSuperview» должно логически работать одинаково ... Если вы попробуете «-removeFromSuperview» внутри блока анимации, вы Посмотрим, что я имею в виду. Почему Apple делает это так, чтобы «-viewWillDisappear» вызывался правильно, но представление фактически удалено в тот же момент времени? – helmesjo

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