I am currently developing an iOS application with login and sign up forms. To make sure that the keyboard does not cover any UITextField
s I've implemented the following solution provided by Apple and discussed in this issue.
To briefly sum it up, this solution uses a UIScrollView
in which the different UI elements are placed and UIKeyboardDidShowNotification
and UIKeyboardDidHideNotification
to move the elements up and down when the keyboard appears/disappears so that the UITextField
s aren't hidden.
This works like a charm except for one thing: for all my UIViewController
s I have to repeat the same code. To tackle my problem I have tried:
- to create a base
UIViewController
, providing an implementation for the different functions, that can be subclasses by the otherUIViewController
s; - to use a protocol and a protocol extension to provide a default implementation for the different functions and make my
UIViewController
s conform to it.
Both solutions didn't solve my problem. For the first solution, I wasn't able to connect the UIScrollView
of my base class through the Interface Builder although it was declared.
@IBOutlet weak var scrollView: UIScrollView!
When trying to implement the second solution, the UIViewController
implementing my protocol somehow did not recognise the declared methods and their implementations.
The protocol declaration:
protocol ScrollViewProtocol {
var scrollView: UIScrollView! { get set }
var activeTextField: UITextField? { get set }
func addTapGestureRecognizer()
func singleTapGestureCaptured()
func registerForKeyboardNotifications()
func deregisterForKeyboardNotifications()
func keyboardWasShown(notification: NSNotification)
func keyboardWillBeHidden(notification: NSNotification)
func setActiveTextField(textField: UITextField)
func unsetActiveTextField()
}
The protocol extension implements all functions expect for the addTapGestureRecognizer()
as I would like to avoid using @objc
:
extension ScrollViewProtocol where Self: UIViewController {
// The implementation for the different functions
// as described in the provided links expect for the following method
func registerFromKeyboardNotifications() {
NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardDidShowNotification, object: nil, queue: nil, usingBlock: { notification in
self.keyboardWasShown(notification)
})
NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardDidHideNotification, object: nil, queue: nil, usingBlock: { notification in
self.keyboardWillBeHidden(notification)
})
}
}
Does anyone have a good solution to my problem, knowingly how could I avoid repeating the code related to moving the UITextField
s up and down when the keyboard appears/disappears? Or does anyone know why my solutions did not work?