一、導(dǎo)語:
- 最近在研究Swift中返向傳值,其中遇到了一些問題,想把自己學(xué)習(xí)的經(jīng)過記錄下來,希望可以幫助那些需要學(xué)習(xí)閉包傳值和代理傳值的程序猿們。來吧!
- 需求:
- 三個界面:先創(chuàng)建三個視圖控制器:A(ViewController)、B(SecondViewController)、C(ThirdViewController);
- 改變A界面的title和背景色(閉包傳值):從A界面 -> B界面:只是推進B界面,什么都不用做,反過來從B -> A界面閉包傳值,傳值string、color分別改變A界面的title和背景色;
- 改變B界面的title和背景色(代理傳值)從B界面 -> C界面:只是推進C界面,什么都不用做,反過來從C -> B界面代理傳值,傳值string、color分別改變B界面的title和背景色;
- 效果gif動畫:
Untitled.gif
二、要了解什么是閉包?如何定義閉包?
- 閉包:閉包是功能性自包含模塊,可以在代碼中被傳遞和使用。 Swift 中的閉包與C和Objective-C中的blocks比較相似,有關(guān)閉包的更多知識請點擊Swift中文網(wǎng)http://c.biancheng.net/cpp/html/2285.html。
- 定義閉包:
- 定義閉包無須func關(guān)鍵字,無須指定函數(shù)名;
- 定義閉包需要額外使用in關(guān)鍵字;
- 定義閉包的第一個花括號要移到形參列表的圓括號之前。
- 閉包表達式: { (形參列表) -> 返回值類型 in
//零條到多條可執(zhí)行性語句
}
三、Swift中閉包傳值:
- 在B界面中要做以下工作:
//1.聲明閉包(定義閉包類型):關(guān)鍵字typealias類似于OC中typedef
typealias sendValueClosure = (_ string:String, _ textColor:UIColor) -> Void
//2.聲明一個閉包變量:
var myClosure : sendValueClosure!
//3.創(chuàng)建閉包方法(傳值):
func buttonClick()->Void{//此方法為點擊B界面中的Button返回到A界面
if myClosure != nil {
myClosure("你好!FirstVC_閉包傳值!",UIColor(red:CGFloat(CGFloat(arc4random())/CGFloat(RAND_MAX)),green:CGFloat(CGFloat(arc4random())/CGFloat(RAND_MAX)), blue:CGFloat(CGFloat(arc4random())/CGFloat(RAND_MAX)), alpha:1))
}
_ = self.navigationController?.popViewController(animated: true)
}
也可以這樣寫:
//1.聲明閉包(定義閉包類型):關(guān)鍵字typealias類似于OC中
typedef typealias sendValueClosure = (_ string:String, _ textColor:UIColor) -> Void
//2.聲明一個閉包變量:
var myClosure : sendValueClosure!
//3.創(chuàng)建閉包方法(傳值):
func buttonClick()->Void{//此方法為點擊B界面中的Button返回到A界面
if myClosure != nil {
myClosure("你好!FirstVC_閉包傳值!", UIColor(red:CGFloat(CGFloat(arc4random())/CGFloat(RAND_MAX)), green:CGFloat(CGFloat(arc4random())/CGFloat(RAND_MAX)), blue:CGFloat(CGFloat(arc4random())/CGFloat(RAND_MAX)), alpha:1))
}
_ = self.navigationController?.popViewController(animated: true) }
func initClosure(closure:sendValueClosure?) -> Void {
myClosure = closure
}
- 在A界面中要做以下工作:
func buttonClick() -> Void {//此方法是推進B界面并 let
secondVC = SecondViewController()//初始化B界面
secondVC.myClosure = {//B界面的閉包變量賦值
(string:String,color:UIColor) -> Void in self.view.backgroundColor = color self.title = string
}
self.navigationController?.pushViewController(secondVC, animated: true)
}
代碼也可以這樣寫:
func buttonClick() -> Void {//此方法是推進B界面并 let
secondVC = SecondViewController()//初始化B界面
secondVC.initClosure(closure:
someFunctionThatTakesAClosure)
self.navigationController?.pushViewController(secondVC, animated: true)
}
func someFunctionThatTakesAClosure(string:String,textColor:UIColor) -> Void {
self.view.backgroundColor = textColor self.title = string
}
四、代理傳值:
- Swift中的代理傳值和OC中的代理傳值很一樣,只是語言不同。誰有需求誰就是委托方,而另一方則是代理方即被委托的對象。
- C界面(代理方)中要做以下事情:
//1.制定協(xié)議和方法并遵守NSObjectProtocol protocol
ThirdViewControllerDelegate:NSObjectProtocol {
func passValueToSecondVC(_ string:String, color:UIColor)
}
//2.點擊此處返回B界面
@IBAction func popToSecondVC(_ sender: Any) {
if delegate != nil{
delegate.passValueToSecondVC("你好!SecondVC_代理傳值!", color: UIColor(red:CGFloat(CGFloat(arc4random())/CGFloat(RAND_MAX)), green:CGFloat(CGFloat(arc4random())/CGFloat(RAND_MAX)), blue:CGFloat(CGFloat(arc4random())/CGFloat(RAND_MAX)), alpha:1))
}
_ = self.navigationController?.popViewController(animated: true)
}
- B界面(委托方)要做以下事情:
//1.遵守協(xié)議ThirdViewControllerDelegate class SecondViewController: UIViewController,ThirdViewControllerDelegate
//2.設(shè)置代理
func button_0Click() -> Void {
let thirdVC = ThirdViewController()
thirdVC.delegate = self
self.navigationController?.pushViewController(thirdVC, animated: true)
}
//3.執(zhí)行代理方法
func passValueToSecondVC(_ string: String, color: UIColor) {
self.title = string
self.view.backgroundColor = color
}