问题
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