Przekazywanie danych w Swift
Szukałem odpowiedzi na to, ale znalazłem tylko odpowiedzi na segue.
Mam viewController1
z przyciskiem, który segreguje viewController2
. Nie ma do tego kodu, skonfigurowałem go przez Interface builder. Na viewController2
mam guzik, który się wyłącza z
self.dismissViewControllerAnimated(true, completion, nil)
Chcę przekazać ciąg znaków z viewController2
z powrotem do viewController1
, gdy Widok zostanie odrzucony. Jak mam to zrobić? Również używam swift.
Z góry dzięki!
3 answers
Istnieją dwa wspólne wzorce, z których oba eliminują potrzebę, aby viewcontroller2 wiedział wyraźnie o viewController1 (co jest Świetne dla utrzymania):
-
Utwórz protokół delegata Dla for viewcontroller2 i ustaw jako delegata viewController1. Gdy chcesz wysłać dane z powrotem do viewController1, niech viewController2 wyśle "delegat" DANE
Ustaw zamknięcie jako właściwość umożliwiającą przekazywanie danych. viewController1 zaimplementuj to zamknięcie na viewController2 podczas wyświetlania viewController2. Ilekroć viewController2 ma dane do przekazania z powrotem, wywoła zamknięcie. Czuję, że ta metoda jest bardziej "szybka" jak.
Oto przykładowy kod dla #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)
}
}
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-20 02:04:56
Użyłem kodu z pierwszej odpowiedzi w przejściu między kontrolerami bez preparedforsegue i też mi się udało. Oto przykładowy kod.
Pierwszy Kontroler Widoku:
@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
}
}
Drugi kontroler widoku:
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)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-21 11:28:36
(Swift 2.1, Xcode 7, iOS9) Jeśli nie chcesz, aby był ściśle sprzężony tylko między 2 kontrolerami ViewControllers, Można również użyć wzorca Notification Design Pattern (Post & Observe) , który służy głównie do przekazywania tego samego obiektu/informacji z jednego VC do wielu kontrolerów widoku.
Dla Twojego scenariusza : w VC2.swift:
@IBAction func BackBtn(sender: UIButton) {
NSNotificationCenter.defaultCenter().postNotificationName("ThisIsTheMessage", object: nil, userInfo:["ObjectBeingSent":yourObject])
}
I w 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
}
}
Powszechną praktyką jest:
- przekaż dane do przodu - > Użyj Preparedforsegue
- przekaż dane wstecz do poprzedniego kontrolera widoku - > protokół i delegacja
- Przekazywanie danych przez wiele kontrolerów widoku - > powiadomienia: Post i obserwuj (obserwuj we wszystkich kontrolerach widoku, w których używasz szczegółów obiektu)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-14 09:49:44