我有一个应用,它在视图的下半部分有一个文本框。 这意味着当我在文本框中输入时,键盘会覆盖文本框。
我如何在打字时向上移动视图,这样我就可以看到我键入的内容,然后在键盘消失时将它移回原来的位置?
我到处都看了,但所有的解似乎都在Obj-C中,我还不能完全转换。
任何帮助都将不胜感激。
我有一个应用,它在视图的下半部分有一个文本框。 这意味着当我在文本框中输入时,键盘会覆盖文本框。
我如何在打字时向上移动视图,这样我就可以看到我键入的内容,然后在键盘消失时将它移回原来的位置?
我到处都看了,但所有的解似乎都在Obj-C中,我还不能完全转换。
任何帮助都将不胜感激。
当前回答
类似于@Boris的回答,但在Swift 5中:
override func viewDidLoad() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
@IBAction func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y == 0 {
self.view.frame.origin.y -= keyboardSize.height
}
}
}
@IBAction func keyboardWillHide(notification: NSNotification) {
if self.view.frame.origin.y != 0 {
self.view.frame.origin.y = 0
}
}
其他回答
将这个添加到你的视图控制器中。效果非常好。只是调整数值。
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name:NSNotification.Name.UIKeyboardWillShow, object: nil);
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name:NSNotification.Name.UIKeyboardWillHide, object: nil);
}
@objc func keyboardWillShow(sender: NSNotification) {
self.view.frame.origin.y -= 150
}
@objc func keyboardWillHide(sender: NSNotification) {
self.view.frame.origin.y += 150
}
在这个线程中,一个流行的答案使用了以下代码:
func keyboardWillShow(sender: NSNotification) {
self.view.frame.origin.y -= 150
}
func keyboardWillHide(sender: NSNotification) {
self.view.frame.origin.y += 150
}
用一个静态量来抵消你的视图有一个明显的问题。它在一个设备上看起来很好,但在任何其他尺寸配置上看起来都很糟糕。您需要获取键盘高度并将其用作偏移值。
下面是一种适用于所有设备的解决方案,它可以处理用户在输入时隐藏预测文本字段的边缘情况。
解决方案
下面需要注意的是,我们将self.view.window作为对象参数传入。这将为我们提供来自键盘的数据,比如它的高度!
@IBOutlet weak var messageField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: self.view.window)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: self.view.window)
}
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
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
})
}
}
删除观察者
不要忘记在离开视图之前删除您的观察器,以防止传输不必要的消息。
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)
}
根据评论中的问题更新:
如果你有两个或更多的文本字段,你可以检查你的view.frame.origin.y是否为零。
func keyboardWillShow(sender: NSNotification) {
let userInfo: [NSObject : AnyObject] = sender.userInfo!
let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size
if keyboardSize.height == offset.height {
if self.view.frame.origin.y == 0 {
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
})
}
print(self.view.frame.origin.y)
}
func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y != 0{
// self.view.frame.origin.y += keyboardSize.height
self.view.frame.origin.y = 0
}
}
}
Swift 3更新…
正如其他人所说,你需要在控制器的viewDidLoad()方法中添加通知观察者,如下所示:
NotificationCenter.default.addObserver(forName: .UIKeyboardWillShow, object: nil, queue: nil)
{ notification in
self.keyboardWillShow(notification)
}
NotificationCenter.default.addObserver(forName: .UIKeyboardWillHide, object: nil, queue: nil)
{ notification in
self.keyboardWillHide(notification)
}
NotificationCenter.default.addObserver(forName: .UIKeyboardDidShow, object: nil, queue: nil)
{ _ in
self.enableUserInteraction()
}
NotificationCenter.default.addObserver(forName: .UIKeyboardDidHide, object: nil, queue: nil)
{ _ in
self.enableUserInteraction()
}
记得在适当的地方删除你的观察器(我在viewWillDisappear()方法中这样做)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidHide, object: nil)
然后,实现你的show和hide方法——注意告诉应用程序忽略交互事件的行(beginIgnoringInteractionEvents)。这很重要,因为如果没有它,用户可能会点击一个字段甚至滚动视图,导致第二次发生移位,从而导致可怕的UI故障。在键盘显示和隐藏之前忽略交互事件将防止这种情况:
func keyboardWillShow(notification: Notification)
{
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
{
UIApplication.shared.beginIgnoringInteractionEvents()
self.view.frame.origin.y -= keyboardSize.height
// add this line if you are shifting a scrollView, as in a chat application
self.timelineCollectionView.contentInset.top += keyboardSize.height
}
}
func keyboardWillHide(notification: Notification)
{
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
{
UIApplication.shared.beginIgnoringInteractionEvents()
self.view.frame.origin.y += keyboardSize.height
// add this line if you are shifting a scrollView, as in a chat application
self.timelineCollectionView.contentInset.top -= keyboardSize.height
}
}
最后,重新启用用户交互(记住,这个方法在键盘didShow或didHide之后触发):
func enableUserInteraction()
{
UIApplication.shared.endIgnoringInteractionEvents()
}
斯威夫特4.1
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y == 0 {
self.view.frame.origin.y -= keyboardSize.height //can adjust as keyboardSize.height-(any number 30 or 40)
}
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if self.view.frame.origin.y != 0 {
self.view.frame.origin.y = 0
}
}