Selector 源自 Objective-C,例如 SEL 型別,以及 @selector() 方法選擇器。
let btn = UIButton.init(type:.custom)
btn.frame = CGRect.init(x: 40, y: 50, width: 40, height: 40);
btn.backgroundColor = UIColor.red
self.view.addSubview(btn)
btn.addTarget(self, action:Selector("leftAction"), for: .touchUpInside)
複製程式碼
並定義方法
func leftAction() {
}
複製程式碼
出現警告:No method declared with Objective-C selector 'leftAction',此時執行會崩潰。
這裡是提示我們沒有方法宣告的Objective-C選擇器
修改leftAction
方法,新增@objc
@objc func leftAction() {
}
複製程式碼
又出現警告:Use '#selector' instead of explicitly constructing a 'Selector' 點選fix警告消除,執行無誤
btn.addTarget(self, action:#selector(HomeVC.leftAction), for: .touchUpInside)
複製程式碼
這裡新增HomeVC
類名引用是為了強宣告是當前類的方法,若當前作用域構造 Selector 的方法名唯一時,可以省略作用域,直接使用方法名。
然後我們試一下同名方法,傳參不同的情況
定義方法
@objc func leftAction(str:String) -> String {
return "123";
}
複製程式碼
編譯報錯,提示我們當前類不能使用leftAction這個方法
去掉作用域編譯,報錯如下然後我們將按鈕的方法名修改為leftAction(btn:)
btn.addTarget(self, action:#selector(HomeVC.leftAction(btn:)), for: .touchUpInside)
複製程式碼
程式可以正常執行,但是使用leftAction方法會報錯。
原來還是引數不同的同名方法使用會有爭議 處理方法:使用強制型別轉換let methodA = #selector(leftAction as () -> ())
let methodB = #selector(leftAction(btn:) as (UIButton) ->String)
複製程式碼
然後新增方法,
btn.addTarget(self, action:methodA, for: .touchUpInside);
複製程式碼
使用呼叫標準庫中的私有方法時,只能通過字串Seletcor("")
swift3.0之前繼承方法可以用Selector("")
來構造。swift4.0之後只能通過#selector()
。
配合 Swift 的 Extension,可以使用其管理當前控制器的所有 Selector:
fileprivate extension Selector{
static let leftBtnClick = #selector(HomeVC.leftAction(btn:))
}
複製程式碼
呼叫leftBtnClick
btn.addTarget(self, action:.leftBtnClick, for: .touchUpInside);
複製程式碼