Как программно выполнить переход Unwind?

Используя раскадровку, это очень просто. Вы просто перетаскиваете действие на «Выход». Но как мне вызвать это из моего кода?


person tadasz    schedule 20.09.2012    source источник
comment
Я считаю это правильным вопросом - у меня он был сам. Вы можете выполнить переход от раскрутки программно, 1. создав переход вручную (перетащите ctrl от владельца файла к выходу), 2. присвоив ему имя в IB, а затем 3. выполнив нормальный -performSegueWithIdentifier: sender: в вашем коде.   -  person Yang Meyer    schedule 03.10.2012
comment
Не надо было закрывать ИМО. Пользователи, проголосовавшие за закрытие этого вопроса, наверняка не имеют фона Obj-C / Cocoa Touch.   -  person LJ Wilson    schedule 23.10.2012
comment
Ян: Как вы дадите ему название?   -  person sarfata    schedule 31.10.2012
comment
Я просто использую [self dismissViewControllerAnimated: ДА, завершение: ноль]; чтобы выйти программно. Не знаю, верный это или нет.   -  person tangqiaoboy    schedule 03.11.2012
comment
DismissViewControllerAnimated: Завершение: должно быть отправлено контроллеру (представляющему контроллер), который представляет тот, который должен быть отклонен (представленный контроллер). Если сообщение отправляется тому, кого нужно отклонить, оно просто пересылается представляющему контроллеру. Но представляющий контролер должен знать, что он уволен. Таким образом, представленный контроллер либо уведомляет его через делегата (в iOS5), либо через переход (доступно в iOS6).   -  person huggie    schedule 21.11.2012
comment
sarfata: сначала вы создаете переход вручную, перетаскивая ctrl-контроллер из viewcontroller в Exit. Затем вы можете найти переход в структуре документа.   -  person huggie    schedule 21.11.2012
comment
Отличный ответ на этот вопрос дается здесь Возможно, это поможет вам еще немного :)   -  person The iOSDev    schedule 19.11.2013
comment
Я не понимаю этого, когда это переход, это означает, что есть раскадровка, а программно ее больше нет.   -  person Mohamad    schedule 04.04.2019


Ответы (10)


  1. Создайте переход вручную (ctrl -drag от владельца файла до выхода),
  2. Выберите его в меню левого контроллера под зеленой кнопкой ВЫХОД.

Выберите его в меню левого контроллера под зеленой кнопкой EXIT

Вставьте название перехода, чтобы расслабиться.

Затем - (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender. с вашим идентификатором segue.

person Vadim    schedule 03.11.2012
comment
1) Владелец файла - разве это не старая терминология? У меня сработало управление перетаскиванием с контроллера представления на его значок выхода. 2) Хотя это должно быть очевидно, Xcode ищет объявление в интерфейсе IBAction, которое принимает аргумент UIStoryboardSegue; в докладе о сеансе 407 WWDC 2012 об этом не упоминалось и не вставлялся этот код. Без него значок выхода не стал бы активным при перетаскивании на него с нажатой клавишей управления. 3) Довольно круто, что в конце вашей большой красной стрелки в поле «Действие» вы можете нажать стрелку «Перейти туда»! - person tobinjim; 09.12.2012
comment
Для тех, кто, как и я, все еще испытывает проблемы с реализацией этого ответа, я собрал более подробное пошаговое руководство и пример в этом репозитории: github.com/bradley/iOSUnwindSegueProgramatic (Не пытаясь рекламировать себя, я просто часами бился головой об стену и видел, что работающая настройка мне помогает.) - person bradleygriffith; 24.05.2013
comment
@bradleygriffith Ты потрясающе супер классный. Спасибо за отличное прохождение! - person Eli_Rozen; 21.12.2013
comment
Я пробовал это часами, даже копаясь в примере Брэдлигриффита, и у меня ничего не вышло. Насколько я могу судить, все настроено так же, как в примере проекта, но я всегда получаю SIGABRT - у приемника нет перехода с идентификатором. В конце концов, вызывая [self dismissViewControllerAnimated: ИСТИНА завершение: ноль]; работал, и это было намного проще сделать (не нужно было возиться с раскадровкой). См. Это - stackoverflow .com / questions / 14957774 / - person user1021430; 13.02.2014
comment
@bradleygriffith Я хотел бы, чтобы вы ответили на этот вопрос, чтобы я тоже мог это отметить! Ваш уникальный вклад заключался в установлении какой контроллер представления получает какой код. Нигде не нашел. Спасибо! - person Aaron Vegh; 08.09.2014
comment
Ключевым моментом для всех, кто все еще не понимает этого, является то, что IBACTION должен находиться в контроллере представления, к которому вы возвращаетесь, а не в том, в котором вы сейчас находитесь. @Bradleygriffith объясняет это на GitHub, но я этого не видел упоминается где-нибудь еще. Эта часть очень важна. - person Axeva; 04.12.2014
comment
Это полезно для передачи информации в действие разматывания (IBACTION). - person Drux; 10.02.2015
comment
@bradleygriffith Большое спасибо за это. Я должен ударить головой о том, что мне нужно определить этот метод раскрутки в классе контроллера представления, который мне нужно раскручивать, а не контроллер представления, из которого мы возвращаемся. - person haxpor; 06.09.2015
comment
Должно быть: 2. Выберите его в меню структуры документа под (оранжевой) кнопкой ВЫХОД. - person John Doe; 14.10.2015

Вот полный ответ с Objective C и Swift:

1) Создайте IBAction переход размотки в контроллере представления назначения (куда вы хотите перейти). Где угодно в файле реализации.

// Objective C

    - (IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue {

    }

// Swift

 @IBAction func unwindToContainerVC(segue: UIStoryboardSegue) {

    }

2) На контроллере исходного представления (контроллер, от которого вы переходите), ⌃ + перетащите из «Имя действия», чтобы выйти. Вы должны увидеть во всплывающем окне последовательность размотки, созданную на шаге 1. (Если вы его не видите, повторите шаг 1). Выберите unwindToContainerVC: из всплывающего окна или как вы назвали свой метод для подключения исходного контроллера к IBAction раскрутки.

введите описание изображения здесь

3) Выберите переход в схеме документа контроллера исходного представления раскадровки (он будет указан внизу) и присвойте ему идентификатор.

введите описание изображения здесь

4) Вызовите переход размотки, используя этот метод из контроллера представления source, подставив свое имя перехода.

// Цель C

[self performSegueWithIdentifier:@"unwindToContainerVC" sender:self];

// Быстрый

self.performSegueWithIdentifier("unwindToContainerVC", sender: self)

NB. Используйте свойство sourceViewController параметра segue в методе unwind для доступа к любым открытым свойствам исходного контроллера. Также обратите внимание, что фреймворк обрабатывает отключение исходного контроллера. Если вы хотите подтвердить это, добавьте к исходному контроллеру метод dealloc с сообщением журнала, которое должно срабатывать после его уничтожения. Если dealloc не срабатывает, у вас может быть цикл сохранения.

person smileBot    schedule 13.12.2014
comment
Моя программа не работает, даже не называется (IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue - person xhg; 09.02.2015
comment
это решение не работает, когда контроллер представления, к которому вы откручиваетесь, существует только в вашей раскадровке, он же не имеет кастомной реализации кода - person mnl; 02.04.2015
comment
@mnl не совсем уверен, что вы говорите, но он работает со сценами раскадровки или перьями. Если вы создаете сцену контроллера представления в коде, вы не будете использовать какие-либо методы, которые возвращают IB в своем имени, что в любом случае действительно недействительно, поскольку они служат для связи между кодом и IB. Это относится к вашему комментарию? - person smileBot; 02.04.2015
comment
Ваша фотография, показывающая ctrl+drag от ViewController до Exit, была невероятно полезной. Спасибо! - person kbpontius; 14.08.2015
comment
Для Swift 4.2 используйте: self.performSegue (withIdentifier: unwindToVC, sender: self) - person Reefwing; 08.01.2019

bradleygriffith ответ был отличным. Я сделал шаг 10 и сделал снимок экрана для упрощения. Это снимок экрана в Xcode 6.

  1. Удерживая нажатой клавишу «Control», перетащите от оранжевого значка к красному значку «Выход», чтобы создать раскрутку без каких-либо действий / кнопок в представлении.

введите описание изображения здесь

  1. Затем выберите unwind segue на боковой панели:

введите описание изображения здесь

  1. Задайте строку идентификатора перехода:

введите описание изображения здесь

  1. Доступ к этому идентификатору из кода:
[self performSegueWithIdentifier:@"unwindIdentifier" sender:self];
person Dean    schedule 06.08.2014
comment
Прежде всего, метод раскрутки должен быть включен в UIViewController. Тогда ваше решение будет работать - person Alex Cio; 16.10.2014
comment
и вы должны установить идентификатор для этого нового перехода! Не забывай об этом. - person kraag22; 28.11.2014
comment
Можно ли программно создать выходное соединение в контроллере исходного представления? - person Andrew Kirna; 31.05.2019

Я использовал [self dismissViewControllerAnimated: YES completion: nil];, который вернет вас к вызывающему ViewController.

person Larry Gibson    schedule 04.11.2012
comment
Ларри, это совершенно правильный подход, если вы хотите вернуться к предыдущему контроллеру представления, то есть к тому, который представлял тот, из которого вы сейчас выходите. Вопрос возник, потому что новое в Xcode 4.5 - это возможность разворачиваться от одного контроллера представления где-нибудь в порядке представления к гораздо более раннему контроллеру представления. См. Подробности в сеансе 407 WWDC 2012. - person tobinjim; 09.12.2012

Цитата из Технического примечания Apple о переходе по разворачиванию: чтобы добавить переход раскрутки, который будет запускаться только программно, удерживайте Ctrl + перетаскивание от значка контроллера представления сцены к его значку выхода, затем выберите действие раскрутки для нового перехода во всплывающем меню.

Ссылка на техническое примечание

person Vishal Chaudhry    schedule 06.11.2013

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

[self performSegueWithIdentifier:@"mySegueName" sender:self];

из ViewController вы также должны выбрать последовательность разматывания в Scene ViewController в раскадровке и в представлении свойств на RHS, чтобы поле Indentifier содержало имя, на которое вы ссылаетесь в коде («mySegueName» в приведенном выше примере ).

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

person Jason Crocker    schedule 18.03.2014

Решение с обратной совместимостью, которое будет работать для версий до ios6, для заинтересованных:

- (void)unwindToViewControllerOfClass:(Class)vcClass animated:(BOOL)animated {

    for (int i=self.navigationController.viewControllers.count - 1; i >= 0; i--) {
        UIViewController *vc = [self.navigationController.viewControllers objectAtIndex:i];
        if ([vc isKindOfClass:vcClass]) {
            [self.navigationController popToViewController:vc animated:animated];
            return;
        }
    }
}
person Joel Teply    schedule 23.12.2013
comment
Сегменты размотки делают гораздо больше, чем просто возвращаются к определенному классу в стеке контроллера навигации. - person Steve Moser; 24.07.2015

SWIFT 4:

1. Создайте @IBAction с внутренним контроллером, на который вы хотите расслабиться:

    @IBAction func unwindToVC(segue: UIStoryboardSegue) {

    }

2. В раскадровке, от контроллера, который вы хотите выйти (раскрутить), от Ctrl + перетащите от значка контроллера до знака выхода и выберите метод, который вы создали ранее:

введите здесь описание изображения

3. Теперь вы можете заметить, что в структуре документа появилась новая строка с заголовком «Unwind segue ....». Теперь вы должны щелкнуть эту строку и открыть инспектор атрибутов, чтобы установить идентификатор (в моем случае unwindSegueIdentifier).

введите здесь описание изображения

4. Почти готово! Теперь вам нужно открыть контроллер представления, от которого вы хотите расслабиться, и создать какой-нибудь метод, который будет выполнять переход. Например, вы можете добавить кнопку, связать ее с кодом с помощью @IBAction, после этого внутри этого IBAction добавить метод perfromSegue (withIdentifier: sender :) :

     @IBAction func unwindToSomeVCWithSegue(_ sender: UIButton) {
         performSegue(withIdentifier: "unwindSegueIdentifier", sender: nil)
     }

Так что это все, что вам нужно сделать!

person wm.p1us    schedule 10.09.2018
comment
Можно ли программно создать выходное соединение в контроллере исходного представления? - person Andrew Kirna; 31.05.2019

Swift 4.2, Xcode 10+

Для тех, кто задается вопросом, как это сделать с венчурными капиталистами, не настроенными с помощью раскадровки (те, кто ответят на этот вопрос, выполнив поиск "программно" + "развернуть переход").

Учитывая, что вы не можете программно настроить завершающий переход, простейшим исключительно программным решением является вызов:

navigationController?.popToRootViewController(animated: true)

который вернет все контроллеры представления в стеке к корневому контроллеру представления.


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

navigationController?.popViewController(animated: true)

person 10623169    schedule 02.04.2019
comment
это обычно больше, чем вы хотите - просто вернуть один: [self.navigationController popViewControllerAnimated: YES]; - person Andy Weinstein; 20.03.2020
comment
Действительно, я добавил это к своему ответу - спасибо @AndyWeinstein - person 10623169; 23.03.2020

К вашему сведению: для того, чтобы ответ @Vadim работал с действием ручной раскрутки seque, вызываемым из контроллера представления, вы должны поместить команду:

[self performSegueWithIdentifier:(NSString*) identifier sender:(id) sender];

внутри метода переопределенного класса viewDidAppear вот так:

-(void) viewDidAppear:(BOOL) animated
{
    [super viewDidAppear: animated];

    [self performSegueWithIdentifier:@"SomeSegueIdentifier" sender:self];
}

Если вы поместите его в другие методы ViewController, такие как viewDidLoad или viewWillAppear, он будет проигнорирован.

person John Verco    schedule 19.04.2013
comment
Однозначно неправильно. Вызовите performSegueWithIdentifier откуда угодно. - person smileBot; 07.10.2014
comment
Разве это не просто выполнило бы размотку, как только представление загружается? Вместо того, чтобы выполнять, когда ВЫ хотите, например, после нажатия кнопки. - person Pahnev; 19.12.2014
comment
@Pahnev да, было бы. Я не знаю, как этот ответ получил столько голосов. Вызов performSegueWithIdentfier делает именно это: выполнение перехода от одного ViewController к другому - person ezcoding; 28.09.2016
comment
Совершенно неправильно. Он просто перематывался сразу после запуска. - person Lee Probert; 08.11.2016