问题
I am adding a keyboard observer to adjust the view height when the keyboard shows. But when the text field is at the top of the view and the keyboard shows, the text field goes up even more. Can someone please guide me on how to fix this properly because after performing lots of searches, they all suggest the same thing. I am using iOS 9 on an iPhone 5.
Here is my code. In viewDidLoad()
:
//SET OBSERVER WHEN KEYBOARD IS SHOWN
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: self.view.window)
//SET OBSERVER WHEN KEYBOARD IS HIDDEN
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: self.view.window)
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: self.view.window)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: self.view.window)
}
//HANDLING KEYBOARD APPEARING AND DISAPPEARING
func keyboardWillHide(sender: NSNotification) {
let userInfo: [NSObject : AnyObject] = sender.userInfo!
let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
self.view.frame.origin.y += keyboardSize.height
}
func keyboardWillShow(sender: NSNotification) {
let userInfo: [NSObject : AnyObject] = sender.userInfo!
let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size
print(("\(keyboardSize.height)---\(offset.height)")) **//this is always showing the values 216.0 for both**
if keyboardSize.height == offset.height {
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.view.frame.origin.y -= keyboardSize.height
})
} else {
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.view.frame.origin.y += keyboardSize.height - offset.height
})
}
}
回答1:
You're taking a complicated approach to what isn't a very difficult problem. Please remember that phones come in a variety of sizes, so trying to move a view around might work great for one device (e.g. iPhone 5) but be a poor experience on others (e.g. iPhone 4, iPhone 6s).
The solution you're looking for is to place your controls inside a UIScrollView
. You then don't move anything when the keyboard shows or hides – you just adjust the content inset of your scroll view, and let iOS do the rest.
The keyboard being shown and hidden is complicated by the fact that there are also hardware keyboards that can be connected and unplugged at will; in my (extremely extensive!) testing, I've managed to pull together code that seems to behave properly in all conditions, no matter what happens with the keyboard. I've tried to trim it down smaller and have always found an edge case where it stopped working, so I've settled with this fixed approach and it works great. If you're able to use a UIScrollView
, this exact approach will work for you too.
Step 1: Register for the right notifications. Specifically, put this into viewDidLoad()
:
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self, selector: "adjustForKeyboard:", name: UIKeyboardWillHideNotification, object: nil)
notificationCenter.addObserver(self, selector: "adjustForKeyboard:", name: UIKeyboardWillChangeFrameNotification, object: nil)
Step 2: Add this method to your view controller:
func adjustForKeyboard(notification: NSNotification) {
let userInfo = notification.userInfo!
let keyboardScreenEndFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
let keyboardViewEndFrame = view.convertRect(keyboardScreenEndFrame, fromView: view.window)
if notification.name == UIKeyboardWillHideNotification {
yourScrollView.contentInset = UIEdgeInsetsZero
} else {
yourScrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height, right: 0)
}
yourScrollView.scrollIndicatorInsets = yourScrollView.contentInset
}
Step 3: Anyone using a UITextView
should also add these two lines to the end of that method so the user doesn't lose their place:
let selectedRange = yourScrollView.selectedRange
yourScrollView.scrollRangeToVisible(selectedRange)
…although presumably in that case it would be yourTextView
or similar.
来源:https://stackoverflow.com/questions/34314106/adjusting-a-uiview-when-the-keyboard-shows-or-hides