Xcode 6 Storyboard Unwind Segue с быстрым не подключением к выходу
При попытке подключить кнопку панели навигации к элементу Exit ViewController в Xcode 6 (не совсем уверен, что это проблема Xcode 6, но стоит упомянуть, поскольку она находится в бета-версии), она не находит функцию Swift в пользовательском класс.
![Button to Exit with whip]()
Функция, которую он должен найти:
@IBAction func unwindToList(segue: UIStoryboardSegue) {
}
Я сделал еще одну кнопку на экране, чтобы убедиться, что я могу получить IBAction, работающую с Swift, и что я правильно ее пишу. Это отлично работает:
@IBAction func test(sender: AnyObject) {
NSLog("Test")
}
Я видел этот вопрос, который похож на ту же проблему, но согласно ответам там это должно работать.
Xcode 6 находится в стадии бета-тестирования, и, конечно же, Swift является очень новым, но ему хотелось узнать, есть ли у кого-то это, прежде чем рассматривать его как потенциальную ошибку.
Ответы
Ответ 1
Это известная проблема с Xcode 6:
Отменить действия segue, объявленные в классах Swift, не распознаются Interface Builder
Чтобы обойти это, вам нужно:
- Измените
class MyViewController
на @objc(MyViewController) class MyViewController
-
Создайте заголовочный файл Objective-C с категорией для MyViewController, который переопределяет действие segue.
@interface MyViewController (Workaround)
- (IBAction)unwindToMyViewController: (UIStoryboardSegue *)segue;
@end
-
В раскадровке выберите экземпляр MyViewController, очистите его собственный класс, затем
верните его в MyViewController.
После этих шагов вы сможете снова подключить кнопки к элементу выхода.
Примечания к выпуску Xcode 6, стр. 10
Ответ 2
Вместо использования обходного решения Objective-C Xcode 6 Beta 4, который теперь может быть установлен, поддерживает соединение разворачиваемых секций в Interface Builder. Теперь вы можете обновить его из центра iOS Dev. Перетащите элемент управления и перетащите его из элемента пользовательского интерфейса, который вы хотите вызвать для перехода к значку выхода, и выберите функцию unwindToSegue, поставив следующий код в контроллер представления назначения.
@IBAction func unwindToSegue (segue : UIStoryboardSegue) {}
Ответ 3
Я смог наконец заставить его работать; xcode6 IB действительно хрупок прямо сейчас (слишком много аварий). Я должен был перезапустить IDE, прежде чем я смог подключить элемент кнопки панели навигации к элементу выхода. Я закончил пересоздание моего тестового проекта и следуя приведенному выше предложению (Xcode 6 Release Notes PDF, стр. 10), чтобы заставить его работать. Кроме того, при добавлении файла .h я старался выбрать цель проекта, которая по умолчанию была снята. Я также создал мой быстрый контроллер с помощью шаблона Cocoa Touch Class (vs empty swift file). Я использовал modal segue в своем навигационном контроллере.
ListTableViewController.h
#import <UIKit/UIKit.h>
@interface ListTableViewController
- (IBAction)unwindToList: (UIStoryboardSegue *)segue;
@end
ListTableViewController.swift
import UIKit
@objc(ListTableViewController) class ListTableViewController: UITableViewController {
@IBAction func unwindToList(s:UIStoryboardSegue) {
println("hello world");
}
}
надеюсь, что поможет
Ответ 4
В Xcode 6 Beta 4, который доступен для загрузки, поддерживается размотка segues и построитель интерфейсов. Я проверил его сам в небольшом проекте.
Ответ 5
В Swift 2.3 я обнаружил, что внешнее имя параметра должно быть "withUnwindSegue":
@IBAction func unwindToThisView(withUnwindSegue unwindSegue: UIStoryboardSegue) {
...
}
Ответ 6
Похоже, что Xcode 6.1 исправил эту проблему. Теперь вы можете настроить разматывание в Swift со следующим кодом:
@IBAction func unwindToList(segue: UIStoryboardSegue) {
// Nothing needed here, maybe a log statement
// print("\(segue)")
}
Этот метод, который может оставаться пустым, должен иметь подпись метода с типом UIStoryboardSegue, а не AnyObject или Interface Builder не увидит его.
Подробнее см. TechNote 2298
Ответ 7
У меня была та же проблема, также с Xcode Beta 4 в начале.. до тех пор, пока я не узнал, что я просто забыл добавить @IBOutlet для кнопок "Отмена" и "Сохранить" в соответствующем контроллере. После этого я мог бы подключать кнопки с помощью Exit-Icon:))
Ответ 8
Если вам всегда нужен тот же контроллер представления, с которым вы хотите расслабиться, вы всегда можете просто сделать:
self.navigationController?.popViewControllerAnimated(true)
Ответ 9
Возможно, вам захочется убедиться, что исходный пункт назначения контроллера, который вы пытаетесь восстановить, не встроен в объект Container. Xcode 6 этого не имеет.
Ответ 10
Ответы выше полагаются на ObjC, чтобы исправить проблему, я нашел чистое решение Swift. При добавлении обработчика segue в Swift мне удалось создать раскручивающийся сегмент в Interface Builder (Xcode 6.3), обработчик не вызывался.
@IBAction func unwindToParent(sender: UIStoryboardSegue) {
dismissViewControllerAnimated(true, completion: nil)
}
Итак, после копания canPerformUnwindSegueAction:fromViewController:withSender
из суперкласса возвращает false
. Поэтому я переопределил реализацию, и она работает:
override func canPerformUnwindSegueAction(action: Selector, fromViewController: UIViewController, withSender sender: AnyObject) -> Bool {
return action == Selector("unwindToParent:")
}
Обновление
Недопустимый код, поскольку я решил проблему без переопределения canPerformUnwindSegueAction:fromViewController:withSender
. Основная ошибка заключалась в том, чтобы провести различие между представлением viewcontroller и представленным диспетчером представлений.
Когда развязанный сеанс инициируется, он должен сначала найти ближайший контроллер представления в иерархии навигации, который реализует действие разматывания, указанное при создании сеанса размотки. Этот контроллер просмотра становится пунктом развязки. Если подходящий контроллер просмотра не найден, разматывающий сегмент прерывается.
источник: Техническая нота TN2298
Итак, определите @IBAction
в представлении viewcontroller, а не на представленном контроллере представления. Таким образом, segue будет иметь значащие значения для свойств destinationViewController
и sourceViewController
, являясь соответственно представляющим и представленным диспетчером представлений.
Ответ 11
Xcode --version 6.4
Swift 1.2
@IBAction func backButton (отправитель: AnyObject) { уклонениеПросмотрСообщение (true, завершение: ноль) }