2014-01-09 4 views
1

Я реализую пользовательский segue с использованием API-интерфейса контроллера, например.Пользовательский Segue без presentViewController не раскручивается правильно

@implementation CustomSegue 

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

    [sourceViewController addChildViewController:destinationViewController]; 
    destinationViewController.view.alpha = 0.0; 
    [sourceViewController.view addSubview:destinationViewController.view]; 
    [UIView animateWithDuration:0.3 animations:^{ 
     destinationViewController.view.alpha = 1.0; 
    } completion:^(BOOL finished) { 
     [destinationViewController didMoveToParentViewController:sourceViewController]; 
    }]; 
} 

@end 

иерархии Посмотреть контроллер тривиальна: sourceViewController → destinationViewController

Когда разматывать от destinationViewController к sourceViewController, приложение падает в [UIStoryboardUnwindSegueTemplate _perform:] за исключением Could not find a view controller to execute unwinding for <…>

я не выполнил заказ -[UIViewController viewControllerForUnwindSegueAction:fromViewController:withSender: или -[UIViewController canPerformUnwindSegueAction:fromViewController:withSender: что означает рамки возвращает правильные значения (хотя я его однажды выполнил, чтобы проверить).

При замене моего пользовательского кода addChildViewController:… с помощью presentViewController:… в segue он отлично работает: разматывание выполняется, как и ожидалось.

Вопрос: возможно ли создать пользовательский сегмент, который создает настраиваемую иерархию диспетчера представлений? Проект случай

Тест: https://bitbucket.org/zats/unwind/

+0

Не думайте, что это решит вашу проблему, но ... У вас действительно должен быть контроллер контейнера, который содержит исходный контроллер, а затем добавить контроллер назначения в контейнер. Затем выполните анимацию, затем удалите исходный контроллер. Немного странно добавлять контроллер назначения к контроллеру источника. Вот пример выполнения, который делает правильные обращения к правильным вещам и изменяет иерархию диспетчера представлений http://pastebin.com/Vk9JfcmP. Может быть, полезно? –

+0

на самом деле это не меняет того факта, что код сбой :) иерархия для меня не так важна в данный момент –

+0

Может быть, что коррумпированная иерархия вызывает проблемы, хотя ... –

ответ

0

Я думаю, что комментарий Джорджа Грина актуальна, и как у вас есть ваши контроллеры установить, является причиной аварии. Я думаю, что делать то, что вы хотите, вы должны добавить ZTSFirstViewController в качестве дочернего элемента в пользовательский контроллер контейнера, который будет выполнять разматывание, а (вперед) segue будет обменивать дочерние элементы этого настраиваемого контроллера контейнера (переключиться с ZTSFirstViewController на ZTSSecondViewController). Метод viewControllerForUnwindSegueAction:fromViewController:withSender: должен быть реализован в пользовательском контроллере контейнера (ViewController в моем примере). Я проверил это, добавив представление контейнера в IB в ViewController и изменив класс встроенного контроллера на ZTSFirstViewController. Я добавил segue из кнопки в ZTSFirstViewController в ZTSSecondViewController и подключил развязать сеанс от кнопки на этом контроллере. Метод unwind: находится в ZTSFirstViewController. Код в пользовательском Segue был это,

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

     if (!self.unwind) { 
      [sourceViewController.parentViewController addChildViewController:destinationViewController]; 
      destinationViewController.view.alpha = 0.0; 
      [sourceViewController.parentViewController.view addSubview:destinationViewController.view]; 
      [UIView animateWithDuration:0.3 animations:^{ 
       destinationViewController.view.alpha = 1.0; 
      } completion:^(BOOL finished) { 
       [destinationViewController didMoveToParentViewController:sourceViewController.parentViewController]; 
      }]; 
     } else { 
      [self.sourceViewController willMoveToParentViewController:nil]; 
      [UIView animateWithDuration:0.3 animations:^{ 
       sourceViewController.view.alpha = 0.0; 
      } completion:^(BOOL finished) { 
       [sourceViewController.view removeFromSuperview]; 
       [sourceViewController removeFromParentViewController]; 
      }]; 
     } 
    } 

Я держал этот SEGUE близко к реализации - это не на самом деле переключения контроллеров, он просто добавляет вторую в качестве второго ребенка и скрывает вид первый.

+0

Спасибо за ваш ответ rdelmar, я тоже попробовал. Думаю, я не правильно сформулировал свой вопрос, моя текущая настройка работает, если пользовательский segue заменен встроенными, что вызывает вопрос. Apple продемонстрировала в wwdc's на 2012 год (видео 407, последние 10 минут), как можно провести segues + разматывание с помощью корневого контроллера. Их настройка очень похожа: http://d.pr/i/eefI. Итак, если я не упустил что-то, вопрос все еще стоит: возможно ли иметь установку, в которой контроллер корневого представления добавляет контроллер детского представления через segue и удаляет его посредством разматывания. –

+0

@SashaZats, я займусь этим видео позже, когда у меня будет больше времени. В этой ситуации я не вижу никакого преимущества в использовании развязки.У родителя и ребенка уже есть ссылки друг на друга, поэтому отправка данных обратно родителям не проблема - одно из основных преимуществ использования отключений, я думаю, заключается в том, чтобы отправить данные обратно на удаленный контроллер, где его сложно настроить обычный шаблон делегата, или для возврата нескольких контроллеров, в которых вы продвинулись вперед, со смесью толканий и подарков. – rdelmar

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