Xebia Blog

A szegue-k használatának egyik hátránya a storyboardokban az, hogy gyakran még mindig kódot kell írni az adatok továbbításához a forrás nézetvezérlőből a cél nézetvezérlőbe. A prepareForSegue(_:sender:) metódus a megfelelő hely erre. Néha manuálisan kell elindítani egy segue-t a performSegueWithIdentifier(_:sender:) hívásával, és ott általában tudod, hogy milyen adatokat kell átadni. Hogyan kerülhetjük el, hogy a forrás nézetvezérlőnkben extra állapotváltozókat adjunk hozzá csak az adatok átadásához? Egy egyszerű trükk az, hogy használjuk a feladó paramétert, amely mindkét metódusnak megvan.

Frissítés:
Kérlek, ne feledd, hogy ez egy anti-patternnek számít, ahogy azt néhány olvasó alább kommentálta, ez a bejegyzés a segues lehetőségeinek felfedezésére szolgál, ami nem jelenti azt, hogy mindig ezt kell használnod. Csak akkor használd, ha szükséges, vagy ha más lehetőség nem áll rendelkezésre.

A feladó paramétert a storyboardok általában a szegue-t kiváltó UI-elem megjelölésére használják, például egy UIButton megnyomásakor, vagy egy UITableViewCell kiválasztásakor, amely a szegue-t kiváltja. Ez lehetővé teszi, hogy a prepareForSegue:sender: paraméterben meghatározzuk, hogy mi váltotta ki a szegue-t, és ez alapján (és természetesen a szegue azonosítója alapján) elvégezzünk néhány műveletet és konfiguráljuk a cél nézetvezérlőt, vagy akár azt is meghatározhatjuk, hogy egyáltalán ne hajtsa végre a szegue-t a false visszatérésével a shouldPerformSegueWithIdentifier(_:sender:) paraméterben.

Ha a Storyboardban lévő UI-elemről nem lehet elindítani a segue-t, akkor helyette a performSegueWithIdentifier(_:sender:) funkciót kell használni a manuális indításhoz. Ez akkor fordulhat elő, ha nem közvetlen felhasználói interakciónak kell kiváltania valamilyen kódban létrehozott vezérlőelem műveletét. Lehet, hogy egy gomb megnyomásakor szeretne valamilyen további logikát végrehajtani, és utána végrehajtani a szegue-t. Bármilyen helyzetről is legyen szó, a feladó argumentumot a saját hasznodra fordíthatod. Bármit átadhatsz a prepareForSegue(_:sender:) vagy a shouldPerformSegueWithIdentifier(_:sender:) paraméterben, amire szükséged lehet.

Mutatunk néhány példát.

Screen Shot 2015-05-08 at 23.25.37

Itt van két nagyon egyszerű nézetvezérlő. Az elsőben három különböző színű gomb van. Ha bármelyik gombra koppintunk, akkor a kiválasztott szín neve felkerül egy címkére, és ez nyomja meg a második nézetvezérlőt. A lenyomott nézetvezérlő a háttérszínét a megérintett gomb által képviselt színre állítja be. Ehhez egy UIColor objektumot kell átadnunk a cél nézetvezérlőnek.

Noha ezt úgy is meg lehetne oldani, hogy a gomboktól közvetlenül a cél nézetvezérlőhöz 3 különböző szegue-t hozunk létre, mi úgy döntöttünk, hogy a gombok megérintését mi magunk kezeljük, és a szegue-t kézzel váltjuk ki.

Az alábbi kódhoz hasonlót találhatunk ki ennek megvalósítására:

class ViewController: UIViewController {

@IBOutlet weak var label:

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()
performSegueWithIdentifier(“ShowColor”, sender: sender)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: 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
}

}

Hoztunk létre egy állapotváltozót tappedColor néven, hogy nyomon kövessük a továbbítandó színt. Ezt minden egyes action metódusban beállítjuk a performSegueWithIdentifier(“ShowColor”, sender: sender) hívása előtt, majd újra kiolvassuk a prepareForSegue(_:sender:)-ben, hogy át tudjuk adni a cél nézetvezérlőnek.

Az action metódusokban a tapped UIButtons lesz beállítva feladó argumentumként, és mivel ez az a tényleges elem, ami az akciót kezdeményezte, van értelme, hogy ezt állítsuk be feladónak a segue végrehajtásakor. Tehát ezt tesszük a fenti kódban. De mivel valójában nem használjuk a feladót a szegue előkészítésekor, helyette akár közvetlenül is átadhatjuk a színt. Íme a ViewController egy új változata, amely pontosan ezt teszi:

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
}
}
}

}

Ez lehetővé teszi, hogy megszabaduljunk az extra tappedColor változótól.

Ez azonban úgy tűnhet (és talán így is van), hogy visszaélünk a sender paraméterrel, ezért óvatosan és csak ott használjuk, ahol szükséges. Legyünk tisztában a következményekkel; ha egy másik kód vagy a Storyboard valamelyik eleme ugyanazt a segue-t váltja ki (azaz ugyanazzal az azonosítóval), akkor a feladó lehet, hogy csak egy UI-elem lesz a várt objektum helyett, ami váratlan eredményekhez és talán még összeomláshoz is vezet, ha a feladót erőltetve olyanná alakítjuk, ami nem az.

A mintakódot egy Xcode projekt formájában a https://github.com/lammertw/SegueColorSample oldalon találja.

Szeretne többet megtudni erről a témáról?
Nézze meg alább tanácsadási szolgáltatásainkat, képzési ajánlatainkat és karrierlehetőségünket, vagy lépjen kapcsolatba velünk a [email protected]

címen.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.