Single extension for UITextView and UITextField in Swift

馋奶兔 提交于 2020-06-23 01:43:23

问题


I want to create a single extension for both UITextField and UITextView and add a below method to it:

    func addDoneButtonOnKeyboardWith(selector : Selector)
    {
        let keyBoardToolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: 320, height: 30))
        let barButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: selector)
        let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        keyBoardToolBar.items = [flexibleSpace, barButtonItem]
        keyBoardToolBar.barStyle = .default
        self.inputAccessoryView = keyBoardToolBar
        self.reloadInputViews()
    }

I want the extension method to be available only for UITextField and UITextView.


回答1:


Maybe this will work, since UIView is the parent class of them, downside is probably this will appear on all kinds of view, not sure if there's any other way to achieve what you need:

extension UIView  {
    func addDoneButtonOnKeyboardWith(selector : Selector)
    {
        if self is UITextField || self is UITextView {
            //do something
        }
    }
}



回答2:


I have an idea that could do what you want, utilising the default implementation of a protocol. Technically you would still need two extensions but they would both be totally empty. Consider the following:

Create a protocol for your method, and provide a default implementation:

protocol DoneButtonBearer {
    func addDoneButtonOnKeyboardWith(selector: Selector)
}

extension DoneButtonBearer {
    func addDoneButtonOnKeyboardWith(selector: Selector) {
        var view: UIView?
        defer  {
            if view != nil {
                let keyBoardToolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: 320, height: 30))
                let barButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: selector)
                let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
                keyBoardToolBar.items = [flexibleSpace, barButtonItem]
                keyBoardToolBar.barStyle = .default
                view!.inputAccessoryView = keyBoardToolBar
                view!.reloadInputViews()
            }
        }
        if let textField = self as? UITextField {
            view = textField
            return
        }
        if let textView = self as? UITextView {
            view = textView
            return
        }
    }
}

Then just extend UITextField and UITextView with this functionality:

extension UITextField: DoneButtonBearer { }

extension UITextView: DoneButtonBearer { }




回答3:


The closest class, which you can extend is UIControl, you can extend it but this method will be accessible again for UIButtons and other controls.

So you can extend or subclass for example UIBarButtonItem with static method.

class func addDoneBarButtonOnKeyboardFor(keyInput: UIControl <UIKeyInput>, usingSelector : Selector)
{
    let keyBoardToolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: 320, height: 30))
    let barButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: selector)
    let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    keyBoardToolBar.items = [flexibleSpace, barButtonItem]
    keyBoardToolBar.barStyle = .default
    keyInput.inputAccessoryView = keyBoardToolBar
    keyInput.reloadInputViews()
}

Sorry if made some mistake in Swift code. Developing on Obj C now.



来源:https://stackoverflow.com/questions/40738258/single-extension-for-uitextview-and-uitextfield-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!