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


307

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


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 не срабатывает, возможно, у вас есть цикл сохранения.


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)
     }

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


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

1

Swift 4.2, Xcode 10+

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

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

navigationController?.popToRootViewController(animated: true)

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


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

navigationController?.popViewController(animated: true)


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

Совершенно неправильно. Это просто перемотало бы сразу при запуске.
— Ли Проберт
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.