prepareForSegue не вызывается, когда я нажимаю кнопку без использования performSegueWithIdentifier

на основе курса iOS Стэнфорда я играю с модальными контроллерами представления. В демо у них есть кнопка, которая запускает модальное представление, и при нажатии на нее вызывается функция prepareForSegue. Я имитировал код и реализацию в своем проекте с той лишь разницей, что моя демонстрация находится на раскадровке iPhone, а их-на iPad.

Я заметил, что, хотя мой контроллер модального вида подходит, он не вызывает prepareForSegue до этого. Я искал Стэнфордский проект, чтобы увидеть, где они могут зарегистрировать любое поведение segue перед вызовом prepareForSegue, но нет никаких доказательств. Может кто-нибудь пролить свет на это. Я искал переполнение стека, и все, что я нашел, было то, что пользователям не хватало реализации вызова performSegueWithIdentifier. Однако в демо-версии Стэнфорда они никогда этого не делают.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier hasPrefix:@"Create Label"]) {
        AskerViewController *asker = (AskerViewController *)segue.destinationViewController;
        asker.question = @"What do you want your label to say?";
        asker.answer = @"Label Text";
        asker.delegate = self;
    }

}

вот пример раскадровки there: enter image description here

вот пример моего раскадровка: enter image description here

в отладчике когда я останавливаюсь в демонстрационном коде Стэнфорда, стек вызовов показывает, что раскадровка выполняет действие segue, что мне нужно настроить в моей раскадровке для достижения того же результата? enter image description here

10 ответов


Ну, как оказалось, мой контроллер вида, где кнопка вызывает модальное представление, не имел правильного класса, в котором реализован prepareForSegue. Это был UIViewController по умолчанию вместо моего пользовательского класса.

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


при подключении автоматического сегмента для представления таблицы, в дополнение к ответу Amro (не назначая соответствующий подкласс), есть еще два случая, когда prepareForSegue может не вызываться. Убедитесь, что вы:

  1. подключил segue из ячейки прототипа представления таблицы,не контроллер представления таблицы.

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

Hooking up automatic segues

[нажмите на изображение, чтобы увеличить]


для других с этой проблемой, если вы сейчас используете Swift 3, имеющий следующую функцию не будет бросать ошибки, как это правильный синтаксис, но он не будет работать, потому что это функция Swift 2:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // code
}

вы должны обновить функцию Swift 3 "prepare", чтобы она работала для сегментов:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

будет ли его модальный или Push Segue ниже кода всегда называться

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"Create Label"]) {
        SignUpViewController *asker = segue.destinationViewController;
    }
}

в моем случае это произошло потому, что мой контроллер расширял другой контроллер (Eureka Form View Controller = FormViewController), который реализовал функцию performSegue следующим образом:

open override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

моя функция была реализована так:

func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

чтобы решить эту проблему, я просто добавил переопределить перед:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

вуаля!


у меня была аналогичная проблема с UICollectionViewCell как источник segue.
Кажется, что для раскадровки segue to work (without performSegueWithIdentifier) требуется, чтобы у вас был пользовательский подкласс UICollectionViewCell, и используйте его как Class на CollectionViewCell на раскадровку.


в моем случае я не устанавливал модуль под именем класса в раскадровке контроллера вида, который содержит segue. Он был установлен в none, и как только я щелкнул в поле модуля, он установил правильный проект / модуль и решил проблему.


У меня была аналогичная проблема.

мыслительный процесс был такой:

  1. убедитесь, что у вас есть правильная подпись метода. Он изменился в Swift 3.
  2. затем убедитесь, что способ, которым вы подключили кнопку (или что-то, что запускает segue), совпадает с тем, как вы подключили segue в раскадровке. Иногда вы вызываете кнопку, но не правильно подключили сегмент от этой кнопки к целевому viewcontroller.
  3. будь уверена идентификатор segue правильный. Хотя это не причина, по которой prepareForSegue не вызывается, это только причина, по которой конкретный сегмент не вызывается.

В моем случае, у меня есть базовый класс для просмотра контроллеры в моем проекте. Этот базовый класс имеет реализацию prepareForSegue() который не вызывался в каждом случае. Проблема заключалась в том, что в одном из моих контроллеров представления, который наследует от базового класса и переопределяет его prepareForSegue() реализация, я забыл позвонить super.prepareForSegue().


во-первых, вы должны выбрать на вашей кнопке + ctrl перетащить элемент для просмотра контроллера выберите сегмент выбора .Позже вы должны правильно назвать идентификатор segue.

Не подключать к одному контроллеру вид контроллера вид. импорт базе UIKit.рамки для этого Тогда этот метод будет вызван.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"identifierName"])
    {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        ExampleViewController *destViewController = segue.destinationViewController;
    }
}