Что такое Unwind segues и как вы их используете?

iOS 6 и Xcode 4.5 имеют новую функцию, называемую "Unwind Segue":

Unwind segues позволяет переходить к существующим экземплярам сцен в раскадровке

В дополнение к этой краткой записи в примечаниях к выпуску Xcode 4.5, UIViewController теперь, похоже, имеет несколько новых методов:

- (BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
- (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier

Как работают разматывающие сегменты и для чего их можно использовать?

Ответ 1

В двух словах

развернуть (иногда называемый exit segue) можно использовать для перехода назад через push, modal или popover segues (как если бы вы вытащили навигационный элемент из навигации бар, закрыл popover или уволил модально представленный контроллер представления). Кроме того, вы можете фактически разматывать не только одну, но и серию push/modal/popover segues, например. "верните" несколько шагов в своей навигационной иерархии с помощью одного режима размотки.

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

Objective-C:

- (IBAction)unwindToThisViewController:(UIStoryboardSegue *)unwindSegue
{
}

Swift:

@IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
}

Имя этого метода действий используется, когда вы создаете раскручивающийся сегмент в раскадровке. Кроме того, этот метод вызывается непосредственно перед выполнением разматывания. Вы можете получить контроллер представления источника из переданного параметра UIStoryboardSegue, чтобы взаимодействовать с контроллером представления, который инициировал segue (например, чтобы получить значения свойств модального контроллера представлений). В этом отношении метод имеет аналогичную функцию prepareForSegue: метода UIViewController.

Обновление iOS 8: Отладка также работает с адаптивными сегментами iOS 8, такими как Show and Show Detail.

Пример

У нас есть раскадровка с контроллером навигации и тремя контроллерами детского вида:

enter image description here

От контроллера Green View вы можете отменить (перейти назад) к контроллеру Red View. От Blue вы можете расслабиться до зеленого или красного цвета через зеленый. Чтобы включить разматывание, вы должны добавить специальные методы действий к красным и зеленым, например. вот метод действия в красном:

Objective-C:

@implementation RedViewController

- (IBAction)unwindToRed:(UIStoryboardSegue *)unwindSegue
{
}

@end

Swift:

@IBAction func unwindToRed(segue: UIStoryboardSegue) {
}

После того, как был добавлен метод действия, вы можете определить разматывание seegue в раскадровке, перетащив управление на значок Exit. Здесь мы хотим расслабиться от зеленого цвета при нажатии кнопки:

enter image description here

Вы должны выбрать действие, которое определено в контроллере представления, который вы хотите восстановить:

enter image description here

Вы также можете расслабиться от красного до синего (что находится "в двух шагах" в стеке навигации). Ключ выбирает правильное раскручивание.

Прежде чем выполнить разматывание segue, вызывается метод действия. В этом примере я определил разматывание красного на зеленый и синий. Мы можем получить доступ к источнику размотки в методе действий с помощью параметра UIStoryboardSegue:

Objective-C:

- (IBAction)unwindToRed:(UIStoryboardSegue *)unwindSegue
{
    UIViewController* sourceViewController = unwindSegue.sourceViewController;

    if ([sourceViewController isKindOfClass:[BlueViewController class]])
    {
        NSLog(@"Coming from BLUE!");
    }
    else if ([sourceViewController isKindOfClass:[GreenViewController class]])
    {
        NSLog(@"Coming from GREEN!");
    }
}

Swift:

@IBAction func unwindToRed(unwindSegue: UIStoryboardSegue) {
    if let blueViewController = unwindSegue.sourceViewController as? BlueViewController {
        println("Coming from BLUE")
    }
    else if let redViewController = unwindSegue.sourceViewController as? RedViewController {
        println("Coming from RED")
    }
}

Размотка также работает через комбинацию push/modal segues. Например. если бы я добавил еще один контроллер желтого представления с модальным сегментом, мы могли бы отталкиваться от Желтого вплоть до Red за один шаг:

enter image description here

Отматывание из кода

Когда вы определяете разматывание с помощью элемента управления, перетаскивая что-то в символ "Выход" контроллера вида, в контуре документа появляется новый сегмент:

enter image description here

Выбор сегмента и переход к инспектору атрибутов показывает свойство "Идентификатор". Используйте это, чтобы дать уникальный идентификатор вашему сеансу:

enter image description here

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

Objective-C:

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

Swift:

performSegueWithIdentifier("UnwindToRedSegueID", sender: self)

Ответ 2

Что касается использования разматывания в StoryBoard...

Шаг 1)

Перейдите к коду для контроллера вида, к которому вы хотите расслабиться, и добавьте следующее:

Objective-C

- (IBAction)unwindToViewControllerNameHere:(UIStoryboardSegue *)segue {
    //nothing goes here
}

Обязательно также объявляйте этот метод в файле.h в Obj-C

стриж

@IBAction func unwindToViewControllerNameHere(segue: UIStoryboardSegue) {
    //nothing goes here
}

Шаг 2)

В раскадровке перейдите к представлению, которое вы хотите отключить, и просто перетащите сегмент с вашей кнопки или что-то еще до маленького оранжевого значка "EXIT" в правом верхнем углу исходного изображения.

enter image description here

Теперь должна быть возможность подключения к "- unindToViewControllerNameHere"

Чтобы он, ваш segue будет расслабляться при нажатии кнопки.

Ответ 3

Unwind segues используются для "возврата" к некоторому контроллеру представлений, из которого через несколько сегментов вы попали в "текущий" контроллер вида.

Представьте, что у вас есть что-то MyNavController с A в качестве его контроллера корневого представления. Теперь вы используете push-сег для B. Теперь контроллер навигации имеет A и B в массиве viewControllers, а B - видимый. Теперь вы представляете C по умолчанию.

С помощью разматывания вы можете открутить "назад" от C до B (т.е. отклонить представленный модально представленный контроллер представления), в основном "отменить" модальный сегмент. Вы можете даже полностью расслабиться до контроллера корневого представления A, отменив как модальный сегмент, так и кнопку push.

Развяжите сегменты, чтобы облегчить откат. Например, перед iOS 6 наилучшей практикой для отклонения представленных контроллеров представления было установить контроллер представления в качестве представленного делегата диспетчера представлений, затем вызвать свой пользовательский метод делегирования, который затем отклоняет presentedViewController. Звук громоздкий и сложный? Это было. Вот почему приятно разделить сеансы.

Ответ 4

Что-то, о чем я не упоминал в других ответах здесь, - это то, как вы справляетесь с разворачиванием, когда не знаете, откуда началось первоначальное segue, что для меня является еще более важным вариантом использования. Например, скажем, у вас есть диспетчер просмотра справки (H), который вы показываете модально из двух разных контроллеров представления ( A и B):

A H
B H

Как настроить разматывание, чтобы вернуться к правильному контроллеру? Ответ заключается в том, что вы объявляете отменное действие в A и B с тем же именем, например:

// put in AViewController.swift and BViewController.swift
@IBAction func unwindFromHelp(sender: UIStoryboardSegue) {
    // empty
}

Таким образом, развязка найдет любой контроллер вида (A или B), который инициирует сеанс и возвращается к нему.

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

Ответ 5

Swift iOS:

Шаг 1: определите этот метод в представлении контроллера MASTER. в котором вы хотите вернуться:

//pragma mark - Unwind Seques
@IBAction func goToSideMenu(segue: UIStoryboardSegue) {

    println("Called goToSideMenu: unwind action")

}

Шаг 2: (StoryBoard) Щелкните правой кнопкой мыши по кнопке SLAVE/CHILD EXIT и выберите "goToSideMenu". Как действие для подключения кнопки, на которую вы нажмете, чтобы вернуться к вам. Вид контроллера MASTER:

enter image description here Шаг 3. Создание и запуск...

Ответ 6

Например, если вы перемещаетесь из viewControllerB в viewControllerA, то в вашем viewControllerA ниже делегат будет вызывать и передавать данные.

@IBAction func unWindSeague (_ sender : UIStoryboardSegue) {
        if sender.source is ViewControllerB  {
            if let _ = sender.source as? ViewControllerB {
                self.textLabel.text = "Came from B = B->A , B exited"
            }
            
        }

}
  • Отследить исходный контроллер просмотра Seague (вам нужно подключить кнопку выхода к значку выхода VCs и подключить его к unindseague:

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

  • Завершить развязку Сигэда → Изменена TextLabel viewControllerA.

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