使用 swift 中的协议在 UITableViewCell 中实现我的 UITextField 的工具栏

问题描述

如何在协议中实现此代码以实现面向协议的编程?一个大问题是解决协议中不允许的@objc 方法。第二个是此代码现在用于许多单元格内的 UITextField,这就是我扩展 UIView 并更正 endediting

的原因

找到原始代码 here

 //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,则您无法为其提供默认扩展

更多详情请参考:Swift protocol extension in Objective-C class