TODO: WIP. Need to test next time I integrate this.
See Greg Heo's video ScrollView tutorial on raywenderlich.com.
Text boxes can get covered up by the keyboard, especially on 3.5 inch screens (4s). The first step is to embed the page contents inside a UIScrollView
.
@IBOutlet weak var scrollview: UIScrollView!
Call scrollRectToVisible
to bring a view out from under the keyboard.
scrollview.scrollRectToVisible(myTextView.frame, animated: true)
It's a lot of boilerplate, but sometimes you just need to shift the whole thing up and down with the keyboard.
First hook into the keyboard notifications in viewDidLoad
.
override func viewDidLoad() {
super.viewDidLoad()
keyboardHeightRegisterNotifications()
}
Wire up a selector
for UIKeyboardWillShowNotification
and UIKeyboardWillHideNotification
. Don't forget the :
because we need to access the userInfo
object.
func keyboardHeightRegisterNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
A good neighbor always cleans up after his dog.
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
Each selector we defined takes a NSNotification
parameter. For each one, just call a helper method and pass in a Bool
to indicate up or down.
func keyboardWillShow(notification: NSNotification) {
adjustInsetForKeyboardShow(true, notification: notification)
}
func keyboardWillHide(notification: NSNotification) {
adjustInsetForKeyboardShow(false, notification: notification)
}
Now to actually move the thing up and down. Grab the keyboard height from the NSNotification
and move the scrollview
contentInset
up or down.
To spare us from some gotchas down the road, we don't actually move the keyboard down (show ? 1 : -1)
-- rather we just zero out the state.
func adjustInsetForKeyboardShow(show: Bool, notification: NSNotification) {
let adjustmentHeight = getKeyboardHeight(notification) * (show ? 1 : 0)
scrollview.contentInset.bottom = adjustmentHeight
scrollview.scrollIndicatorInsets.bottom = adjustmentHeight
}
Lots of helper functions. This one unwraps the keyboard height from the NSNotification
object. It's important to use the UIKeyboardFrameEndUserInfoKey
from userInfo
. Don't use UIKeyboardFrameBeginUserInfoKey
, or you'll find yourself driving a car using your rearview mirror.
func getKeyboardHeight(notification: NSNotification) -> CGFloat{
let userInfo = notification.userInfo ?? [:]
let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
return CGRectGetHeight(keyboardFrame)
}
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var scrollview: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
keyboardHeightRegisterNotifications()
}
func keyboardHeightRegisterNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func keyboardWillShow(notification: NSNotification) {
adjustInsetForKeyboardShow(true, notification: notification)
}
func keyboardWillHide(notification: NSNotification) {
adjustInsetForKeyboardShow(false, notification: notification)
}
func adjustInsetForKeyboardShow(show: Bool, notification: NSNotification) {
let adjustmentHeight = getKeyboardHeight(notification) * (show ? 1 : 0)
scrollview.contentInset.bottom = adjustmentHeight
scrollview.scrollIndicatorInsets.bottom = adjustmentHeight
}
func getKeyboardHeight(notification: NSNotification) -> CGFloat{
let userInfo = notification.userInfo ?? [:]
let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
return CGRectGetHeight(keyboardFrame)
}
}