Xebia Blog

Yksi segujen käyttämisen huonoista puolista storyboardeissa on se, että joudut usein kirjoittamaan koodia tietojen välittämiseksi lähteenäkymäohjaimelta määränpäänäkymäohjaimelle. Metodi prepareForSegue(_:sender:) on oikea paikka tehdä tämä. Joskus sinun on käynnistettävä segue manuaalisesti kutsumalla performSegueWithIdentifier(_:sender:) -metodia, ja siellä tiedät yleensä, mitä tietoja sinun on siirrettävä eteenpäin. Miten voimme välttää lisäämästä ylimääräisiä tilamuuttujia lähdenäkymäohjaimeemme vain tietojen välittämistä varten? Yksinkertainen temppu on käyttää lähettäjäparametria, joka on molemmilla metodeilla.

Päivitys:
Pitäkää mielessä, että tätä pidetään anti-patternina, kuten jotkut lukijat kommentoivat alla, tämän postauksen tarkoituksena on tutkia seguesin mahdollisuuksia, mikä ei tarkoita, että sitä pitäisi aina käyttää. Käytä sitä vain silloin, kun se on tarkoituksenmukaista tai kun muuta vaihtoehtoa ei ole käytettävissä.

Tarinoissa käytetään yleensä sender-parametria osoittamaan seguen laukaiseva UI-elementti, esimerkiksi UIButton, kun sitä painetaan, tai UITableViewCell, joka laukaisee seguen valitsemalla sen. Näin voit määrittää, mikä laukaisi seguen kohdassa prepareForSegue:sender:, ja sen (ja tietysti seguen tunnisteen) perusteella tehdä joitakin toimia ja konfiguroida määränpäänäkymän ohjaimen tai jopa määrittää, että segua ei pitäisi suorittaa lainkaan, palauttamalla false kohdassa shouldPerformSegueWithIdentifier(_:sender:).

Jos seguen käynnistäminen Storyboardin UI-elementistä ei ole mahdollista, sen sijaan on käytettävä performSegueWithIdentifier(_:sender:) -toimintoa sen käynnistämiseksi manuaalisesti. Näin saattaa käydä, kun käyttäjän suoran vuorovaikutuksen ei pitäisi laukaista jonkin koodissa luodun ohjaimen toimintaa. Ehkä haluat suorittaa jonkin lisälogiikan, kun painiketta painetaan, ja sen jälkeen suorittaa seguen. Oli tilanne mikä tahansa, voit käyttää lähettäjä-argumenttia hyödyksesi. Voit välittää prepareForSegue(_:sender:) tai shouldPerformSegueWithIdentifier(_:sender:) -kohdassa mitä ikinä tarvitsetkin.

Katsotaanpa muutamia esimerkkejä.

Screen Shot 2015-05-08 klo 23.25.37

Tässä meillä on kaksi hyvin yksinkertaista näkymäohjainta. Ensimmäisessä on kolme painiketta eri väreille. Kun napauttaa mitä tahansa painiketta, valitun värin nimi laitetaan tarraan ja se työntää toista view-ohjainta. Työnnetty näkymäohjain asettaa taustavärikseen napautetun painikkeen edustaman värin. Tätä varten meidän on välitettävä UIColor-olio kohde-näkymäohjaimelle.

Vaikka tämä voitaisiin hoitaa luomalla kolme erillistä segua painikkeista suoraan kohde-näkymäohjaimeen, päätimme käsitellä painikkeen napauttamisen itse ja laukaista segun manuaalisesti.

Voi olla, että saattaisit keksiä jotakin seuraavan kaltaista koodia tämän toteuttamiseksi:

class ViewController: UIViewController {

@IBOutlet weak var label: UILabel!

var tappedColor: UIColor?

@IBAction func tappedRed(sender: AnyObject) {
label.text = ”Tapped Red”
tappedColor = UIColor.redColor()
performSegueWithIdentifier(”ShowColor”, sender: sender)
}

@IBAction func tappedGreen(sender: AnyObject) {
label.text = ”Tapped Green”
tappedColor = UIColor.greenColor()
performSegueWithIdentifier(”ShowColor”, sender: sender)
}

@IBAction func tappedBlue(sender: AnyObject) {
label.text = ”Tapped Blue”
tappedColor = UIColor.blueColor()
suoritaSegueWithIdentifier(”ShowColor”, lähettäjä: lähettäjä)
}

override func prepareForSegue(segue: UIStoryboardSegue, lähettäjä: AnyObject?) {
if segue.identifier == ”ShowColor” {
if let colorViewController = segue.destinationViewController as? ColorViewController {
colorViewController.color = tappedColor
}
}
}
}

}

class ColorViewController: UIViewController {

var color: UIColor?

override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = color
}

}

Loimme tilamuuttujan nimeltä tappedColor pitämään kirjaa siitä, mikä väri pitää välittää. Se asetetaan jokaisessa toimintametodissa ennen performSegueWithIdentifier(”ShowColor”, sender: sender) -kutsua ja luetaan sitten uudelleen prepareForSegue(_:sender:) -kutsussa, jotta voimme välittää sen eteenpäin määränpäänä olevalle näkymäohjaimelle.

Toimintametodeille asetetaan lähettäjäargumentiksi naputetut UIButtons-painikkeet (tapped UIButtons), ja koska se on varsinainen elementti, joka on aloittanut toiminnon suorittamisen, on mielekästä määritellä kyseinen elementti lähettäjäksi, kun seguetta suoritetaan. Näin siis tehdään yllä olevassa koodissa. Mutta koska emme itse asiassa käytä lähettäjää, kun valmistelemme erottelua, voimme yhtä hyvin välittää värin suoraan sen sijaan. Tässä on uusi versio ViewControllerista, joka tekee juuri näin:

class ViewController: UIViewController {

@IBOutlet weak var label: UILabel!

@IBAction func tappedRed(sender: AnyObject) {
label.text = ”Tapped Red”
performSegueWithIdentifier(”ShowColor”, sender: UIColor.redColor())
}

@IBAction func tappedGreen(sender: AnyObject) {
label.text = ”Tapped Green”
performSegueWithIdentifier(”ShowColor”, sender: UIColor.greenColor())
}

@IBAction func tappedBlue(sender: AnyObject) {
label.text = ”Tapped Blue”
performSegueWithIdentifier(”ShowColor”, sender: UIColor.blueColor())
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == ”ShowColor” {
if let colorViewController = segue.destinationViewController as? ColorViewController {
colorViewController.color = sender as? UIColor
}
}
}

}

Tämän avulla pääsemme eroon ylimääräisestä tappedColor-muuttujastamme.

Se saattaa kuitenkin vaikuttaa siltä (ja ehkä onkin), että sender-parametria käytetään väärin, joten käytä sitä varovasti ja vain tarvittaessa. Ole tietoinen seurauksista; jos jokin muu koodi tai jokin elementti Storyboardissa laukaisee saman seguen (eli samalla tunnisteella), lähettäjä saattaa olla vain käyttöliittymäelementti odotetun objektin sijaan, mikä johtaa odottamattomiin tuloksiin ja ehkä jopa kaatumisiin, kun pakotat lähettäjän johonkin, mitä se ei ole.

Löydät esimerkkikoodin Xcode-projektin muodossa osoitteesta https://github.com/lammertw/SegueColorSample.

Haluatko tietää lisää tästä aiheesta?
Katsele alla olevia konsultointipalvelujamme, koulutustarjouksiamme ja uramahdollisuuksiamme tai ota yhteyttä osoitteeseen [email protected]

.

Vastaa

Sähköpostiosoitettasi ei julkaista.