Uma das desvantagens de usar seguimentos em storyboards é que você ainda precisa escrever código para passar dados do controlador de visualização de origem para o controlador de visualização de destino. O método prepareForSegue(_:sender:) é o lugar certo para fazer isso. s vezes você precisa acionar manualmente uma sequência chamando performSegueWithIdentifier(_:sender:), e é lá que você normalmente sabe quais dados você precisa passar. Como podemos evitar adicionar variáveis de estado extra no nosso controlador de visualização da fonte apenas para passar os dados? Um truque simples é usar o parâmetro do remetente que ambos os métodos têm.
Update:
Por favor tenha em mente que isto é considerado um anti-padrão, como comentado por alguns leitores abaixo, este post é para explorar as possibilidades de seguimentos, o que não significa que você deve sempre usá-lo. Use-o apenas quando apropriado ou quando nenhuma outra opção estiver disponível.
O parâmetro emissor é normalmente usado por storyboards para indicar o elemento UI que acionou a sequência, por exemplo um UIButton quando pressionado ou uma UITableViewCell que aciona a sequência selecionando-a. Isto permite que você determine o que acionou o segue no prepareForSegue:sender:, e com base nisso (e claro o identificador do segue) tome algumas ações e configure o controlador de visualização de destino, ou mesmo determine que ele não deve executar o segue retornando falso no shouldPerformSegueWithIdentifier(_:sender:).
Quando não é possível acionar o seguido de um elemento UI no Storyboard, você precisa usar performSegueWithIdentifier(_:sender:) para acionar manualmente. Isto pode acontecer quando nenhuma interação direta do usuário deve acionar a ação de algum controle que foi criado em código. Talvez você queira executar alguma lógica adicional ao pressionar um botão e depois disso executar a sequência. Qualquer que seja a situação, você pode usar o argumento do remetente em seu benefício. Você pode passar o que você precisar na preparaçãoForSegue(_:sender:) ou deve executarSegueWithIdentifier(_:sender:).
Demos uma olhada em alguns exemplos.
>
>
Aqui temos dois controladores de visualização muito simples. O primeiro tem três botões para cores diferentes. Ao tocar em qualquer um dos botões, o nome da cor selecionada será colocado em uma etiqueta e ele pressionará o segundo controlador de visualização. O controlador de vista empurrado irá definir sua cor de fundo para a cor representada pelo botão tocado. Para fazer isso, precisamos passar um objeto UIColor para o controlador da vista de destino.
Even embora isso possa ser feito criando 3 seguimentos distintos dos botões diretamente para o controlador da vista de destino, nós escolhemos manipular o botão tapar nós mesmos e o gatilho a seguir manualmente.
Você pode inventar algo como o seguinte código para fazer isso:
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”, remetente: remetente)
}
@IBAction func tappedGreen(sender: AnyObject) {
label.text = “Tapped Green”
tappedColor = UIColor.greenColor()
performSegueWithIdentifier(“ShowColor”, remetente: remetente)
}
@IBAction func tappedBlue(sender: AnyObject) {
label.text = “Tapped Blue”
tappedColor = UIColor.blueColor()
performSegueWithIdentifier(“ShowColor”, remetente: remetente)
}
override func prepareForSegue(segue: UIStoryboardSegue, remetente: 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
}
}
Criamos uma variável de estado chamada tappedColor para manter o controle da cor que precisa ser passada adiante. Ela é definida em cada um dos métodos de ação antes de chamar o performSegueWithIdentifier(“ShowColor”, remetente: sender) e então ler novamente no prepareForSegue(_:sender:) para que possamos passá-la para o controlador de visualização de destino.
Os métodos de ação terão os botões UIButtons tapped definidos como argumento do remetente, e como esse é o elemento real que iniciou a ação, faz sentido definir isso como o remetente ao executar a continuação. Então é isso que nós fazemos no código acima. Mas como na verdade não usamos o remetente quando preparamos a sequência, mais vale passarmos a cor diretamente. Aqui está uma nova versão do ViewController que faz exatamente isso:
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”, remetente: UIColor.greenColor())
>
>
@IBAction func tappedBlue(sender: AnyObject) {
label.text = “Tapped Blue”
performSegueWithIdentifier(“ShowColor”, remetente: UIColor.blueColor())
}
>
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == “ShowColor” {
if let colorViewController = segue.destinationViewController as? ColorViewController {
colorViewController.color = remetente como? UIColor
}
}
}
}
>
Isto permite-nos livrar-nos da nossa variável extra tappedColor.
Pode parecer (e talvez pareça) abusar do parâmetro do remetente, por isso use-o com cuidado e apenas onde apropriado. Esteja ciente das consequências; se algum outro código ou algum elemento em um Storyboard aciona a mesma sequência (ou seja, com o mesmo identificador), então o remetente pode ser apenas um elemento UI ao invés do objeto que você esperava, o que levará a resultados inesperados e talvez até mesmo a travamentos quando você forçar o remetente a lançar para algo que não é.
Pode encontrar o código de exemplo na forma de um projecto Xcode em https://github.com/lammertw/SegueColorSample.
Consulte os nossos serviços de consultoria, ofertas de formação e carreiras abaixo ou contacte-nos em [email protected]