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

implementing toolbar fo my UITextField in UITableViewCell using protocols in swift

如何在协议中实现此代码以实现面向协议的编程?一个大问题是解决 @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, target: self, 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, target: self, 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 can only be used with members of classes, @objc protocols, and concrete extension of classes

因此,为了使您的协议与 @objc 功能兼容,您最终会将其设为@objc 协议,如果您将协议设为@objc,则无法为其提供默认扩展

更多详情请参考: