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

307

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

tadasz
источник
33
Я считаю это актуальным вопросом - у меня был он сам. Вы можете выполнить процедуру раскручивания программным способом: 1. создавая переход вручную (перетаскивая ctrl из «Владелец файла» в «Выход»), 2. присваивая ему имя в IB, затем 3. выполняя обычную -performSegueWithIdentifier: sender: в своем коде.
Ян Мейер
6
Не должно было быть закрыто ИМО. Пользователи, которые проголосовали за закрытие этого вопроса, похоже, не имеют фона Obj-C / Cocoa Touch.
ЖЖ Уилсон
Ян: Как вы даете ему имя?
Сарфата
Я просто использую [self dismissViewControllerAnimated: YES завершение: ноль]; выйти программно. Я не знаю, это правильный путь или нет.
tangqiaoboy
1
sarfata: сначала вы создаете «переход с ручного раскручивания» путем нажатия Ctrl с помощью viewcontroller в «Exit». Затем вы можете найти последовательность в Outline документа.
Хагги

Ответы:

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

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

Введите имя Segue, чтобы расслабиться.

Тогда - (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender.с твоим переходом отождествляйся.

Вадим
источник
25
1) «Владелец файла» - разве это не старая терминология? У меня получилось управлять перетаскиванием из контроллера вида на значок выхода. 2) Хотя это должно быть очевидно, Xcode ищет объявление в интерфейсе IBAction, которое принимает аргумент UIStoryboardSegue; В докладе 407, посвященном сессии WWDC 2012, об этом не упоминалось и он не вставлялся в этот код. Без него значок «Выход» не активировался при перетаскивании элемента управления. 3) Очень круто, что в конце вашей большой красной стрелки в поле «Действие» вы можете нажать стрелку «туда»!
Tobinjim
71
Для тех, у кого, как и у меня, все еще есть проблемы с реализацией этого ответа, я собрал более подробное руководство и пример в этом репозитории: github.com/bradley/iOSUnwindSegueProgramatics (не пытаясь рекламировать себя, я просто ударился головой о стену в течение нескольких часов я вижу, как мне помогает рабочая установка.)
Брэдлигриффит
3
@bradleygriffith Вы удивительно супер круто. Спасибо за отличное прохождение!
Eli_Rozen
7
@bradleygriffith Я хотел бы, чтобы вы ответили на этот вопрос, чтобы я тоже мог это отметить! Ваш уникальный вклад заключался в установлении того, какой контроллер представления получает какой код . Не могу найти это нигде. Спасибо!
Аарон Вег
3
Ключевой момент для тех, кто все еще озадачен этим, заключается в том, что IBACTION должен быть в контроллере представления, к которому вы возвращаетесь, а не в том, в котором вы находитесь в данный момент. @Bradleygriffith излагает это на GitHub, но я этого не видел упоминается где-либо еще. Эта часть имеет решающее значение.
Аксева
163

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

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

// Objective C

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

    }

// Swift

 @IBAction func unwindToContainerVC(segue: UIStoryboardSegue) {

    }

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

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

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

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

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

// Цель C

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

// Swift

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

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

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

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

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

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

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

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

  1. Установите строку идентификатора Segue:

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

  1. Получите доступ к этому идентификатору из кода:
[self performSegueWithIdentifier:@"unwindIdentifier" sender:self];
декан
источник
4
Прежде всего, метод для размотки должен быть включен в UIViewController. Тогда ваше решение будет работать
Alex Cio
5
и вы должны установить идентификатор для этого нового перехода! Не забывай об этом.
kraag22
1
Можно ли программно создать соединение «выход» в контроллере представления исходного кода?
Эндрю Кирна
13

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

Ларри Гибсон
источник
6
Ларри, это совершенно правильный подход, если вы хотите вернуться к предыдущему контроллеру представления, т.е. к тому, который представил тот, который вы сейчас выходите. Возник вопрос, потому что новое в Xcode 4.5 - это возможность «раскрутиться» от одного контроллера представления где-то в порядке представления к гораздо более раннему контроллеру представления. См. Сессию 407 WWDC 2012 для деталей.
Tobinjim
11

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

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

Вишал Чодри
источник
6

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

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

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

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

Джейсон Крокер
источник
3

Обратно совместимое решение, которое будет работать для версий, предшествующих 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;
        }
    }
}
Джоэл Тепли
источник
2
Разматывать сегменты гораздо больше, чем просто возвращаться к определенному классу в стеке контроллера навигации.
Стив Мозер
2

SWIFT 4 :

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

    @IBAction func unwindToVC(segue: UIStoryboardSegue) {

    }

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

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

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

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

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

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

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

wm.p1us
источник
Можно ли программно создать соединение «выход» в контроллере представления исходного кода?
Эндрю Кирна
1

Swift 4.2, Xcode 10+

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

Учитывая то, что вы не можете настроить процесс раскрутки программно, самое простое исключительно программное решение - это вызвать:

navigationController?.popToRootViewController(animated: true)

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


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

navigationController?.popViewController(animated: true)

10623169
источник
1
это, как правило, больше, чем вы хотите - чтобы вспомнить, просто сделайте: [self.navigationController popViewControllerAnimated: YES];
Энди Вайнштейн
Действительно, я добавил это к своему ответу - спасибо @AndyWeinstein
10623169
0

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

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

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

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

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

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

Джон Верко
источник
3
Определенно неправильно. Вызовите executeSegueWithIdentifier откуда угодно.
smileBot
Не будет ли это просто выполнить раскрутку, как только загрузится представление? Вместо того, чтобы выполнять, когда вы хотите, например, после нажатия кнопки.
Пахнев
@Pahnev да, это будет. Я не знаю, как этот ответ получил какие-либо отзывы. Вызов performSegueWithIdentfierделает именно это: выполнение перехода от одного ViewController к другому
ezcoding
Совершенно неправильно. Это просто перемотало бы сразу при запуске.
Ли Проберт