「在 A View 叫起B View做動作,成功或失敗各自有不同的行為,但這個行為得依賴A頁拿到得資料有所不同時應該…」陷入選擇性障礙,不知道該把邏輯放哪邊
「把想做的事情在叫起B View 的那個 Moment 一起決定吧!!!」天空中出現一道光,從光裡傳出了一個聲音說著…
最近時常用到這種需求,在這邊整理一下用法
比方說我有四個畫面:帳單清單( Bills )、確認繳費( Confirm )、繳費中( Processing )、繳費成功( Success )、繳費失敗( Fails )
使用者在帳單清單中選擇他想要繳的項目之一,這時候我把資料明細帶入( Confirm )
( Confirm )裡會有兩個Button,一個是確定,一個是取消,當使用者按下確定之後,會顯示一段( Processing )的過場動畫
接著依照繳費成功或失敗的結果顯示對應的畫面
作法一:把實際上繳費的行為寫在( Confirm ),如果成功就顯示( Success );失敗就顯示( Fails )
優點:邏輯單純,好讀好理解。
缺點,畫面和邏輯綁太緊,彈性不夠。
作法二:在( Bills )把流程寫好,把該做的事放到各自對應的畫面預留的Function裡。
優點:流程有彈性,調整畫面邏輯比較方便。
缺點:架構上比較複雜,會花比較多的時間理解流程與設計精神。
因為這篇文章主要是針對 Closure ,所以會比較接近作法二的情況
比較關鍵的程式如下:
在 BillsViewController 裡面的某個按鈕去叫起( Confirm ),並指定這個按鈕要做的事情:
let ConfirmVC : ConfirmViewController = UIStoryboard.init(name: kAlertStoryboard, bundle: nil).instantiateViewController(withIdentifier: "ConfirmVC") as! ConfirmViewController
ConfirmVC.billData = BillData
ConfirmVC.actionButtonHandler = {
ConfirmVC.dismiss(animated: true, completion: nil)
self.beginPaymentFlow(BillData: BillData)
}
ConfirmVC.cancelButtonHandler = {
ConfirmVC.dismiss(animated: true, completion: nil)
}
self.presentOverCurrentContextViewController(ConfirmVC, animated: true, completion:nil)
當然,在 ConfirmViewController 裡面早已定義好相對應的 Handler 參數讓外頭塞 function:
var billData : Bill?
var actionButtonHandler : (() -> ())?
var cancelButtonHandler : (() -> ())?
@IBAction func actionButtonOnTapped(_ sender: Any) {
self.actionButtonHandler!()
}
@IBAction func cancelButtonOnTapped(_ sender: Any) {
self.cancelButtonHandler!()
}
如果 Function 還要傳值進去的話也可以寫成這樣:
宣告:
var actionButtonHandler : ((String, Int) -> ())?
那麼定義的時候就變為:
ConfirmVC.actionButtonHandler = { (name : String, age : Int)->() in
print(name)
print(age);
}
叫用的時候自然就變成:
self.actionButtonHandler!("John",30)
以上,日後忘記了就來這邊回憶一下吧