问题描述
如何在协议中实现此代码以实现面向协议的编程?一个大问题是解决协议中不允许的@objc 方法。第二个是此代码现在用于许多单元格内的 UITextField,这就是我扩展 UIView 并更正 endediting
//used inside a cell with a UITextField
extension UIView {
func toolBar() -> UIToolbar{
let toolBar = UIToolbar()
toolBar.barStyle = .default
toolBar.isTranslucent = true
toolBar.barTintColor = UIColor.init(red: 0/255,green: 25/255,blue: 61/255,alpha: 1)
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace,target: nil,action: nil)
let buttonTitle = "Done"
let cancelButtonTitle = "Cancel"
let doneButton = UIBarButtonItem(title: buttonTitle,style: .done,target: self,action: #selector(onClickDoneButton))
let cancelButton = UIBarButtonItem(title: cancelButtonTitle,style: .plain,action: #selector(onClickCancelButton))
doneButton.tintColor = .white
cancelButton.tintColor = .white
toolBar.setItems([cancelButton,space,doneButton],animated: false)
toolBar.isUserInteractionEnabled = true
toolBar.sizetoFit()
return toolBar
}
@objc func onClickDoneButton(){
// view.endEditing(true)
self.endEditing(true)
}
@objc func onClickCancelButton(){
// view.endEditing(true)
self.endEditing(true)
}
}
编辑 Sandeep Bhandari 的回答,这是可行的实现
extension UIView: ToolBarProtocol {}
然后在我的牢房里,我有:
let selDone = #selector(onClickDoneButton)
let selCancel = #selector(onClickCancelButton)
self.cellTextfield.inputAccessoryView = toolBar(with: selDone,cancelSeclector: selCancel)
@objc func onClickDoneButton() {
self.endEditing(true)
}
@objc func onClickCancelButton() {
self.endEditing(true)
}
解决方法
我猜你能做的最好
protocol ToolBarProtocol where Self: UIView {
func toolBar(with doneSelector: Selector?,cancelSeclector: Selector?) -> UIToolbar
}
extension ToolBarProtocol {
func toolBar(with doneSelector: Selector?,cancelSeclector: Selector?) -> UIToolbar{
let toolBar = UIToolbar()
toolBar.barStyle = .default
toolBar.isTranslucent = true
toolBar.barTintColor = UIColor.init(red: 0/255,green: 25/255,blue: 61/255,alpha: 1)
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace,target: nil,action: nil)
let buttonTitle = "Done"
let cancelButtonTitle = "Cancel"
let doneButton = UIBarButtonItem(title: buttonTitle,style: .done,target: self,action: doneSelector)
let cancelButton = UIBarButtonItem(title: cancelButtonTitle,style: .plain,action: cancelSeclector)
doneButton.tintColor = .white
cancelButton.tintColor = .white
toolBar.setItems([cancelButton,space,doneButton],animated: false)
toolBar.isUserInteractionEnabled = true
toolBar.sizeToFit()
return toolBar
}
}
简而言之您不能为 @objc
协议提供默认扩展。
这与这个问题有什么关系?
您不能为完成和取消按钮选择器提供默认扩展,因为它们需要用 @objc
注释(典型的选择器签名是 selector(@objc method))和一旦你添加 @objc
到它们然后编译器会给你一个编译错误
@objc 只能与类成员、@objc 协议和 类的具体扩展
因此为了使您的协议与 @objc
函数兼容,您最终将使其成为@objc 协议,并且如果您创建了一个协议@objc,则您无法为其提供默认扩展