[英]Passing closure in swift as parameter to be used by selector in function
我正在嘗試創建一個通用按鈕創建 function,我將一個閉包傳遞到其中,該閉包表示單擊按鈕后產生的操作。 我的代碼如下。 但是,我收到以下錯誤:#selector 的參數無法引用屬性。 有什么解決方法的建議嗎? 我不想編寫單獨的函數,除了目標操作之外,其他所有內容都相同。
func myButton(textColor tColor:UIColor , title:String,
_ buttonFcn: (UIButton) -> Void,
titleSize:CGFloat=30) -> UIButton {
let newButton = UIButton(type: .System)
let bgColor = UIColor(red:204/255, green:204/255, blue:204/255, alpha:1.0)
newButton.backgroundColor = bgColor
newButton.setTitle(title, forState: .Normal)
newButton.setTitleColor(tColor, forState: .Normal)
newButton.titleLabel?.font = newButton.titleLabel?.font.fontWithSize(titleSize)
newButton.addTarget(self, action:#selector(buttonFcn),
forControlEvents:
UIControlEvents.TouchUpInside)
return newButton
}
問題在於目標動作機制是一種Objective-C機制,因此基於動作選擇器是一種對象 方法的概念來進行判斷。 因此,您需要具有一些基於NSObject的對象 ,該對象具有將此功能用作方法 ,然后可以用作目標。
因此,如果目標和操作在每種情況下都不同,那么您需要傳遞的是對目標的引用以及選擇器字符串 。 Swift會對此之以鼻,但是,如果您知道如何正確形成選擇器字符串,那么您當然可以擺脫它; 您將無法使用#selector
語法,因此,如果輸入格式不正確,可能會導致崩潰。 但這是我們在過去的Objective-C時代一直做的事情,因此,如果這是您的目標,那就繼續吧。
完全人為但可行的示例:
func buttonMaker(target:NSObject, selectorString:String) -> UIButton {
let b = UIButton(type:.system)
b.setTitle("Testing", for: .normal)
b.addTarget(target, action: Selector(selectorString), for: .touchUpInside)
b.sizeToFit()
return b
}
這是從視圖控制器調用它的方法:
func doButton(_ sender:Any) {
print("ha!")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let b = buttonMaker(target:self, selectorString:"doButton:")
b.frame.origin = CGPoint(x:100, y:100)
self.view.addSubview(b)
}
而且當我們點擊按鈕時,我們不會崩潰(而是打印“ ha”),因為我知道如何正確制作選擇器字符串。 但是,正如您所看到的,要實現此目的,我必須完全放棄使用#selector
,因此安全性不在考慮之列。 如果我沒有正確輸入選擇器字符串(例如,如果我拼寫錯誤或省略了冒號),我們將在按鈕點擊時崩潰,就像我們在Swift #selector
和Objective-C之前一直都一樣@selector
被發明了。
如果您的部署目標是 iOS 14 或更高版本,您可以使用addAction
方法而不是addTarget
。 addAction
方法允許您使用閉包而不是選擇器:
func myButton(
textColor: UIColor,
title: String,
titleSize: CGFloat = 30,
_ handler: @escaping (UIButton) -> Void
) -> UIButton {
let button = UIButton(type: .system)
button.backgroundColor = UIColor(red: 204/255, green: 204/255, blue: 204/255, alpha: 1.0)
button.setTitle(title, for: .normal)
button.setTitleColor(textColor, for: .normal)
button.titleLabel?.font = button.titleLabel?.font.withSize(titleSize)
let action = UIAction { action in
guard let button = action.sender as? UIButton else { return }
handler(button)
}
button.addAction(action, for: .touchUpInside)
return button
}
iOS 14於2020-09-16發布,支持iPhone 6S及之后的設備。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.