初探Closure(一):利用Closure讓自訂XIB畫面與ViewController互動

Murphy
Apr 14, 2024

--

延續上一個自訂Xib畫面的專案 — 用XIB製作UIView,並導入ViewController

上次設計的畫面裡,有一個挑選日期的Button,我希望能做到按下Button後畫面以present的方式出現一個Date Picker,用以讓我選擇日期並將選擇的日期文字顯示在XIB的日期Button上

這要分成上下兩部份:
1. 按下XIB View上的日期按鈕後,讓畫面present到Date Picker的畫面

註:這邊Date Picker我是另開一個ViewController來顯示

2. 選擇日期後,XIB View上日期Button修改為選擇的日期

先用圖像釐清一下ViewController及XIB View及準備present的關係

讓我們先來研究狀況1吧!

一般來說,要做present動作是由ViewController執行的,但今天我想按下XIB View上的按鈕再present Date Picker畫面,我們可以使用Closure的方式達到這個效果

首先,我先在XIB View綁定的swift檔內宣告一個closure

//這是XIB View綁定的swift檔
class InputView: UIView {
var presentDatePickerClosure: ()->() = {}
}

接下來,我希望viewController可以幫我做到present畫面

//ViewController
class DetailViewController: UIViewController {

//XIB View
@IBOutlet weak var editView: InputView!

override func viewDidLoad() {
super.viewDidLoad()
//將closure要執行的內容寫進來:我要present DatePickerViewController
editView.presentDatePickerClosure = { [weak self] in
guard let selfVC = self else { return }
let datePickerSB = UIStoryboard(name: "your storyboard name", bundle: nil)

//因為將datePicker的viewController放在不同的storyboard,
//因此注意在抓ViewController時須將Class轉型
let datePickerVC = datePickerSB.instantiateViewController(withIdentifier: "DatePickerViewController") as! DatePickerViewController
selfVC.present(datePickerVC, animated: true)
}
}
}

OK,現在我們已經設定好這個closure會幫我present畫面
於是,我要加上當我按下日期Button後,讓這個closure執行的code

class InputView: UIView {
var presentDatePickerClosure: ()->() = {}
}

@IBAction func changeDate(_ sender: Any) {
self.presentDatePickerClosure()
}

完成囉!

下一篇,我們來探討第二部分:選擇日期後,XIB View上日期Button修改為選擇的日期

文章傳送門:
初探Closure(二):利用Closure傳送參數,讓其他ViewController把獲得的值傳入XIB View

--

--