2013-07-18 5 views
23

Я создал пользовательский сегмент, который представляет контроллер представления внутри контейнера, который очень похож на собственные модальные контроллеры Apple (я реализовал его как подкласс UIViewController).-segueForUnwindingToViewController: fromViewController: идентификатор: не был вызван

Теперь я пытаюсь создать пользовательский режим размотки, но я не могу получить способ -segueForUnwindingToViewController: fromViewController: identifier:.

Я также применил -viewControllerForUnwindSegueAction: fromViewController: withSender: на моем контейнере, поэтому я могу указать на правильный контроллер вида (тот, который представил этот модальный), но затем метод, который должен быть запрошен для моего пользовательского разматывания, не будет вызван нигде.

Прямо сейчас, единственный способ отклонить этот модаль - сделать это по методу -returned:.

Может ли кто-нибудь с успехом сделать это с помощью пользовательского режима размотки?


EDIT: Немного больше кода и контекст

Мой размотки-контроллер сконфигурирован в раскадровке, а не программно.

У меня есть эти фрагменты кода, связанные с раскруткой перетекает в моих контроллерах:

PresenterViewController.m

Я использую специальный метод, чтобы закрыть свои собственные модальности здесь (-dismissModalViewControllerWithCompletionBlock:).

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController 
             fromViewController:(UIViewController *)fromViewController 
               identifier:(NSString *)identifier { 
    return [[MyModalUnwindSegue alloc] initWithIdentifier:identifier 
                source:fromViewController 
               destination:toViewController]; 
} 

-(IBAction)returned:(UIStoryboardSegue *)segue { 
    if ([segue.identifier isEqualToString:@"InfoUnwindSegue"]) { 
     [self dismissModalViewControllerWithCompletionBlock:^{}]; 
    } 
} 

MyModalViewController.m

Здесь я использую только -viewControllerForUnwindSegueAction: fromViewController: withSender:, чтобы указать на контроллер представления, что я должен быть размотки к.

- (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action 
             fromViewController:(UIViewController *)fromViewController 
               withSender:(id)sender { 
    return self.myPresentingViewController; 
} 

поведение я ожидал, что MyModalViewController был призван указать на контроллере представления, который должен обрабатывать раскручивание, а затем этот вид контроллер был его метод -segueForUnwindingToViewController: fromViewController: identifier: вызывается перед -returned: вызывается.

Прямо сейчас -segueForUnwindingToViewController: fromViewController: identifier: никогда не вызывается.

Должен также сказать, что я уже пробовал разные конфигурации. Всюду, когда я возвращаю метод, он не вызывает вызова. Я читал, что я могу подклассифицировать контроллер навигации, а затем он вызван, но я не знаю, как он будет соответствовать моему решению.


EDIT 2: Дополнительная информация

Я проверил, что MyModalViewController имеет свой -segueForUnwindingToViewController: fromViewController: identifier: метод вызывается, когда я хочу, чтобы закрыть регулярный модальный контроллер представления, представленный им. Возможно, это потому, что он является самым большим UIViewController в иерархии.

После проверки этого я подклассифицировал UINavigationController и вместо этого использовал этот подкласс, чтобы содержать мой PresenterViewController. Я был очень удивлен, заметив, что его метод -segueForUnwindingToViewController: fromViewController: identifier: также называется.

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

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

Форумы Apple на данный момент не работают, поэтому нет возможности получить поддержку прямо сейчас. Если у кого-то есть больше информации о том, как это работает, пожалуйста, помогите! Я думаю, что отсутствие документации для этого является хорошим показателем того, насколько неустойчивым это все еще.

+0

Вы хотите просмотреть настоящее или уволить? –

+0

Вам нужно показать код, который вы уже пробовали. – rdelmar

+0

@rdelmar, здесь у вас есть. Скажите, хотите ли вы увидеть какой-либо конкретный код. –

ответ

5

Этот метод должен быть объявлен на родительском контроллере. Поэтому, если вы используете контроллер навигации с пользовательским segue, подкласс UINavigationController и определите этот метод на нем. Если вы предпочитаете определять его на одном из дочерних представлений UINavigationController, вы можете переопределить canPerformUnwindSegueAction: fromViewController: withSender в UINavigationController, чтобы он искал детей для обработчика.

Если вы используете встроенный вид (вид контейнера), определите его на родительском контроллере представления.

Просмотреть последние 10 минут WWDC 2012 Сессия 407 - Принятие раскадровки в вашем приложении, чтобы понять, почему это работает!

+0

Можете ли вы определить мое описание, в котором должен быть объявлен контроллер представления? Можете ли вы найти объяснение того, как это работает? По моему мнению, UINavigationController должен попросить своих детей разойтись, прежде чем давать свои собственные, поскольку он не был тем, кто звонил и создавал оригинальный сеанс. У вас есть другое объяснение, почему оно работает так? –

+1

Из вашего описания я не уверен на 100%. Но UINavigationController получает первые dibs, потому что, скорее всего, вы хотите расслабиться от корня, а оттуда более вероятно, что это будет один из более отдаленных контроллеров. Если вы только хотели создать резервную копию одного контроллера, вы, вероятно, не использовали бы разматывать segue, вы, вероятно, просто вызовете popViewController. В конечном счете, похоже, что оптимизация некоторых разработчиков фреймворков в Apple решила на –

11

Чтобы добавить к ответу от @Jeremy, я получил от модального UIViewController доступ к UIViewController, содержащемуся в UINavigationController, для правильной работы (например, как я это ожидал), используя следующее в моем подклассе UINavigationController.

// Pass to the top-most UIViewController on the stack. 
- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *) 
      toViewController fromViewController:(UIViewController *) 
      fromViewController identifier:(NSString *)identifier { 
    UIViewController *controller = self.topViewController; 
    return [controller segueForUnwindingToViewController:toViewController 
            fromViewController:fromViewController 
              identifier:identifier]; 
} 

.., а затем реализации segueForUnwindingToViewController, как обычно, в фактическом ViewController внутри UINavigationController.

+0

+1. Это помогло мне. Использование этого нового настраиваемого контроллера навигации в качестве основного навигационного контроллера моего приложения. Надеюсь, что больше ничего не сломается ... – Jonny

+0

Хм, это действительно испортило другие места вокруг моего приложения, поэтому я вернулся и пошел с другим решением. Не могу удалить мой +1 ;-) Во всяком случае, может быть полезно знать позже. – Jonny

+0

Честно говоря, вскоре после того, как я обнаружил вышеизложенное (что отлично сработало для меня), я полностью отказался от segues и сделал все в коде. Итак, так проще! Все отлично поработало! –

0

Если вы используете UINavigationController и ваш переход звонит pushViewController то для того, чтобы использовать пользовательские размотать Segue вам нужно подкласс UINavigationController и переопределить - (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier.

Скажите, что у меня есть обычная раскрутка, называемая CloseDoorSegue. Моя реализация подкласс UINavigationController может выглядеть примерно так:

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier { 

UIStoryboardSegue* theSegue; 

if ([identifier isEqualToString:@"CloseDoor"]) { 
    theSegue = [CloseBookSegue segueWithIdentifier:identifier source:fromViewController destination:toViewController performHandler:^(void){}]; 
} else { 
    theSegue = [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier]; 
} 

return theSegue; 

}

Установите ваш UINavigationController подкласс в классе навигации контроллера в раскадровке. Вам должно быть хорошо, если вы правильно настроили событие «Выход» с «CloseDoor» в качестве идентификатора. Также не забудьте вызвать «popViewControllerAnimated» в вашем режиме разговора вместо увольнения, чтобы поддерживать связь с механизмом push/pop UINavigationControllers.

0

iOS development Library С этим методом обсуждается библиотека разработки iOS. - segueForUnwindingToViewController: fromViewController: identifier: Убедитесь, что MyModalViewController является ролью контейнера, а не субконтроллером контейнера. Если есть что-то вроде [anotherVC addChildViewController:myModalViewController];, вы должны поместить метод segueForUnwindingToViewController в какой-то файл «AnotherVC.m».

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