Передача данных в Swift
Я искал ответ для этого, но нашел ответы только на segues.
У меня есть viewController1
с кнопкой, которая переходит к viewController2
. Для этого нет кода, я настроил его через интерфейс. На viewController2
У меня есть кнопка, которая отклоняет себя с помощью
self.dismissViewControllerAnimated(true, completion, nil)
Я хочу передать строку из viewController2
обратно в viewController1
, когда представление отклонено. Как мне это сделать? Кроме того, я использую быстрый.
Спасибо заранее!
Ответы
Ответ 1
Существует два общих шаблона, оба из которых устраняют необходимость в viewController2 явно знать о viewController1 (что отлично подходит для ремонтопригодности):
-
Создайте делегатский протокол для вашего viewController2 и установите viewController1 в качестве делегата. Всякий раз, когда вы хотите отправить данные обратно в viewController1, попросите viewController2 отправить "делегировать" данные
-
Установите закрытие как свойство, которое позволяет передавать данные. viewController1 будет реализовывать это закрытие на viewController2 при отображении viewController2. Всякий раз, когда viewController2 имеет данные для передачи назад, он вызывает закрытие. Я чувствую, что этот метод более "быстрый".
Вот пример кода для # 2:
class ViewController2 : UIViewController {
var onDataAvailable : ((data: String) -> ())?
func sendData(data: String) {
// Whenever you want to send data back to viewController1, check
// if the closure is implemented and then call it if it is
self.onDataAvailable?(data: data)
}
}
class ViewController1 : UIViewController {
func doSomethingWithData(data: String) {
// Do something with data
}
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
// When preparing for the segue, have viewController1 provide a closure for
// onDataAvailable
if let viewController = segue.destinationViewController as? ViewController2 {
viewController.onDataAvailable = {[weak self]
(data) in
if let weakSelf = self {
weakSelf.doSomethingWithData(data)
}
}
}
}
}
Ответ 2
Я использовал код из первого ответа при переходе между контроллерами БЕЗ подготовкиForSegue и работал у меня.
Здесь пример кода.
Первый контроллер просмотра:
@IBAction func dpAgendaClick(sender:UIBarButtonItem) {
///instantiating view controller with identifier
if let datePickerViewController = storyboard?.instantiateViewControllerWithIdentifier("DatePickerViewController")
as? DatePickerViewController {
///bring instantiated view controller to front
self.presentViewController(datePickerViewController, animated: true, completion: nil)
///wrapping the data returned
datePickerViewController.onDataFiltroAvailable = {[weak self]
(dataFiltro) in
if let weakSelf = self {
///use dataFiltro here
}
}
Второй контроллер просмотра:
var onDataFiltroAvailable: ((dataFiltro: String) -> ())?
///private var
var dataFiltro: String = ""
///the returning data is obtained on the datePickerChanged event
@IBAction func datePickerChanged(sender: UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
dateFormatter.dateFormat = "yyyy-MM-dd"
dataFiltro = dateFormatter.stringFromDate(datePicker.date)
}
///dismiss the controller on button click
@IBAction func dpOkClick(sender: UIButton) {
///"returning" the data
self.onDataFiltroAvailable?(dataFiltro: dataFiltro)
dismissViewControllerAnimated(true, completion: nil)
}
Ответ 3
(Swift 2.1, Xcode 7, iOS9)
Если вы не хотите, чтобы он был плотно соединен только между 2 ViewControllers,
Вы также можете использовать шаблон дизайна уведомлений (сообщение и наблюдение), который в основном используется для передачи одного объекта/информации с одного VC на несколько контроллеров просмотра.
Для вашего сценария:
В VC2.swift:
@IBAction func BackBtn(sender: UIButton) {
NSNotificationCenter.defaultCenter().postNotificationName("ThisIsTheMessage", object: nil, userInfo:["ObjectBeingSent":yourObject])
}
И в VC1.swift:
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("yourFunction:"), name: "ThisIsTheMessage", object: nil)
}
func yourFunction(theNotification : NSNotification) {
if let extractInfo = theNotification.userInfo {
//code to use the object sent from VC2, by extracting the object details
}
}
Общая практика:
- Передача данных вперед → Использование PrepareForSegue
- Передача данных назад в предыдущий контроллер просмотра → Протокол и делегирование
- Передача данных через несколько контроллеров просмотра → Уведомления: сообщение и наблюдение (см. во всех контроллерах View, в которых вы используете детали объекта)