我正在尝试为iPhone构建输入屏幕.屏幕有许多输入字段.其中大多数位于屏幕顶部,但两个字段位于底部.当用户尝试编辑屏幕底部的文本时,键盘将弹出并覆盖屏幕.我找到了一个简单的解决方案,可以在发生这种情况时将屏幕向上移动,但结果是屏幕总是向上移动,当用户尝试编辑屏幕时,屏幕顶部的字段会移动.
有没有办法让屏幕只在编辑底部字段时移动?
我使用了这里找到的代码:
override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil) } func keyboardWillShow(sender: NSNotification) { self.view.frame.origin.y -= 150 } func keyboardWillHide(sender: NSNotification) { self.view.frame.origin.y += 150 }
Nerkyator.. 206
Apple在本文档中对您的问题进行了详细解释.此页面上的示例代码(at Listing 4-1
)完全符合您的需要,只有在当前编辑应位于键盘下方时才会滚动视图.您只需要将所需的控件放在scrollViiew中.唯一的问题是这是Objective-C,我认为你需要它在Swift中...所以它是:它是:
声明一个变量
var activeField: UITextField?
然后添加这些方法
func registerForKeyboardNotifications() { //Adding notifies on keyboard appearing NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil) } func deregisterFromKeyboardNotifications() { //Removing notifies on keyboard appearing NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil) } func keyboardWasShown(notification: NSNotification) { //Need to calculate keyboard exact size due to Apple suggestions self.scrollView.scrollEnabled = true var info : NSDictiOnary= notification.userInfo! var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size var contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0) self.scrollView.cOntentInset= contentInsets self.scrollView.scrollIndicatorInsets = contentInsets var aRect : CGRect = self.view.frame aRect.size.height -= keyboardSize!.height if let activeFieldPresent = activeField { if (!CGRectContainsPoint(aRect, activeField!.frame.origin)) { self.scrollView.scrollRectToVisible(activeField!.frame, animated: true) } } } func keyboardWillBeHidden(notification: NSNotification) { //Once keyboard disappears, restore original positions var info : NSDictiOnary= notification.userInfo! var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size var contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, -keyboardSize!.height, 0.0) self.scrollView.cOntentInset= contentInsets self.scrollView.scrollIndicatorInsets = contentInsets self.view.endEditing(true) self.scrollView.scrollEnabled = false } func textFieldDidBeginEditing(textField: UITextField!) { activeField = textField } func textFieldDidEndEditing(textField: UITextField!) { activeField = nil }
请务必将ViewController声明为UITextFieldDelegate
初始化方法并在初始化方法中设置正确的委托:ex:
self.you_text_field.delegate = self
并记得调用registerForKeyboardNotifications
viewInit并deregisterFromKeyboardNotifications
退出.
func registerForKeyboardNotifications(){ //Adding notifies on keyboard appearing NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIResponder.keyboardWillHideNotification, object: nil) } func deregisterFromKeyboardNotifications(){ //Removing notifies on keyboard appearing NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIResponder.keyboardWillHideNotification, object: nil) } @objc func keyboardWasShown(notification: NSNotification){ //Need to calculate keyboard exact size due to Apple suggestions self.scrollView.isScrollEnabled = true var info = notification.userInfo! let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize!.height, right: 0.0) self.scrollView.cOntentInset= contentInsets self.scrollView.scrollIndicatorInsets = contentInsets var aRect : CGRect = self.view.frame aRect.size.height -= keyboardSize!.height if let activeField = self.activeField { if (!aRect.contains(activeField.frame.origin)){ self.scrollView.scrollRectToVisible(activeField.frame, animated: true) } } } @objc func keyboardWillBeHidden(notification: NSNotification){ //Once keyboard disappears, restore original positions var info = notification.userInfo! let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: -keyboardSize!.height, right: 0.0) self.scrollView.cOntentInset= contentInsets self.scrollView.scrollIndicatorInsets = contentInsets self.view.endEditing(true) self.scrollView.isScrollEnabled = false } func textFieldDidBeginEditing(_ textField: UITextField){ activeField = textField } func textFieldDidEndEditing(_ textField: UITextField){ activeField = nil }
谢谢,这正是我想要的 - 苹果推荐的解决方案.但是,在我的情况下,我已经有一个跨越可视区域的滚动视图.此代码将在键盘隐藏后禁用滚动.我删除了"self.scrollView.scrollEnabled = false",它仍然不会滚动.对我有用的是"self.scrollView.cOntentInset= UIEdgeInsetsZero;" 在keyboardWillHide事件中的这一行 (10认同)
完美的代码.但我需要使用`UIKeyboardFrameEndUserInfoKey`而不是'UIKeyboardFrameBeginUserInfoKey`,因为后者返回高度为0.并且将hittest点更改为底部而不是原点.`if let activeField = self.activeField {var point = activeField.frame.origin point.y + = activeField.frame.size.height if(!aRect.contains(point)){self.scrollView.scrollRectToVisible(activeField.frame,动画:true)}}` (5认同)
您必须在viewDidLoad上调用registerForKeyboardNotifications,因此您将向观察中心添加一个观察者,以了解键盘何时出现或从屏幕上消失。当这些通知触发时,将调用方法keyboardWasShown和keyboardWillBeHidden,然后scrollview将根据键盘大小移动。您可以在此处找到有关NotificationCenter的更多详细信息:https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/ (2认同)
@MaX:它应该可以工作,但是如果你想要一个Swift4解决方案你可以查看[这个iOS示例](https://github.com/mattneub/Programming-iOS-Book-Examples/blob/swift4ios11/bk2ch10p522textFieldScrollView/ch23p805textFieldSliding/ViewController .swift)来自[Matt Neuburg](/sf/ask/17360801/)的书,我向所有iOS开发者推荐:) (2认同)
Mr H.. 131
这是我的2美分:
您是否尝试过:https://github.com/hackiftekhar/IQKeyboardManager
非常容易安装Swift或Objective-C.
它是如何工作的:
IQKeyboardManager(Swift): - IQKeyboardManagerSwift可通过CocoaPods获得,安装它只需将以下行添加到您的Podfile:(#236)
pod 'IQKeyboardManagerSwift'
在AppDelegate.swift中,只需导入IQKeyboardManagerSwift框架并启用IQKeyboardManager.
import IQKeyboardManagerSwift @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { IQKeyboardManager.sharedManager().enable = true // For Swift 4, use this instead // IQKeyboardManager.shared.enable = true return true } }
这就是全部.简单!
Apple在本文档中对您的问题进行了详细解释.此页面上的示例代码(at Listing 4-1
)完全符合您的需要,只有在当前编辑应位于键盘下方时才会滚动视图.您只需要将所需的控件放在scrollViiew中.唯一的问题是这是Objective-C,我认为你需要它在Swift中...所以它是:它是:
声明一个变量
var activeField: UITextField?
然后添加这些方法
func registerForKeyboardNotifications() { //Adding notifies on keyboard appearing NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil) } func deregisterFromKeyboardNotifications() { //Removing notifies on keyboard appearing NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil) } func keyboardWasShown(notification: NSNotification) { //Need to calculate keyboard exact size due to Apple suggestions self.scrollView.scrollEnabled = true var info : NSDictiOnary= notification.userInfo! var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size var contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0) self.scrollView.cOntentInset= contentInsets self.scrollView.scrollIndicatorInsets = contentInsets var aRect : CGRect = self.view.frame aRect.size.height -= keyboardSize!.height if let activeFieldPresent = activeField { if (!CGRectContainsPoint(aRect, activeField!.frame.origin)) { self.scrollView.scrollRectToVisible(activeField!.frame, animated: true) } } } func keyboardWillBeHidden(notification: NSNotification) { //Once keyboard disappears, restore original positions var info : NSDictiOnary= notification.userInfo! var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size var contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, -keyboardSize!.height, 0.0) self.scrollView.cOntentInset= contentInsets self.scrollView.scrollIndicatorInsets = contentInsets self.view.endEditing(true) self.scrollView.scrollEnabled = false } func textFieldDidBeginEditing(textField: UITextField!) { activeField = textField } func textFieldDidEndEditing(textField: UITextField!) { activeField = nil }
请务必将ViewController声明为UITextFieldDelegate
初始化方法并在初始化方法中设置正确的委托:ex:
self.you_text_field.delegate = self
并记得调用registerForKeyboardNotifications
viewInit并deregisterFromKeyboardNotifications
退出.
func registerForKeyboardNotifications(){ //Adding notifies on keyboard appearing NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIResponder.keyboardWillHideNotification, object: nil) } func deregisterFromKeyboardNotifications(){ //Removing notifies on keyboard appearing NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIResponder.keyboardWillHideNotification, object: nil) } @objc func keyboardWasShown(notification: NSNotification){ //Need to calculate keyboard exact size due to Apple suggestions self.scrollView.isScrollEnabled = true var info = notification.userInfo! let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize!.height, right: 0.0) self.scrollView.cOntentInset= contentInsets self.scrollView.scrollIndicatorInsets = contentInsets var aRect : CGRect = self.view.frame aRect.size.height -= keyboardSize!.height if let activeField = self.activeField { if (!aRect.contains(activeField.frame.origin)){ self.scrollView.scrollRectToVisible(activeField.frame, animated: true) } } } @objc func keyboardWillBeHidden(notification: NSNotification){ //Once keyboard disappears, restore original positions var info = notification.userInfo! let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: -keyboardSize!.height, right: 0.0) self.scrollView.cOntentInset= contentInsets self.scrollView.scrollIndicatorInsets = contentInsets self.view.endEditing(true) self.scrollView.isScrollEnabled = false } func textFieldDidBeginEditing(_ textField: UITextField){ activeField = textField } func textFieldDidEndEditing(_ textField: UITextField){ activeField = nil }
这是我的2美分:
您是否尝试过:https://github.com/hackiftekhar/IQKeyboardManager
非常容易安装Swift或Objective-C.
它是如何工作的:
IQKeyboardManager(Swift): - IQKeyboardManagerSwift可通过CocoaPods获得,安装它只需将以下行添加到您的Podfile:(#236)
pod 'IQKeyboardManagerSwift'
在AppDelegate.swift中,只需导入IQKeyboardManagerSwift框架并启用IQKeyboardManager.
import IQKeyboardManagerSwift @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { IQKeyboardManager.sharedManager().enable = true // For Swift 4, use this instead // IQKeyboardManager.shared.enable = true return true } }
这就是全部.简单!
我发现对我来说完美的工作是:
func textFieldDidBeginEditing(textField: UITextField) { if textField == email || textField == password { animateViewMoving(true, moveValue: 100) } } func textFieldDidEndEditing(textField: UITextField) { if textField == email || textField == password { animateViewMoving(false, moveValue: 100) } } func animateViewMoving (up:Bool, moveValue :CGFloat){ let movementDuration:NSTimeInterval = 0.3 let movement:CGFloat = ( up ? -moveValue : moveValue) UIView.beginAnimations("animateView", context: nil) UIView.setAnimationBeginsFromCurrentState(true) UIView.setAnimationDuration(movementDuration) self.view.frame = CGRectOffset(self.view.frame, 0, movement) UIView.commitAnimations() }
您还可以更改高度值.如果要将其用于所有文本字段,请删除"if语句".
您甚至可以将此用于需要用户输入的所有控件,如TextView.
有没有办法让屏幕只在编辑底部字段时移动?
我有一个类似的问题,发现一个非常简单的解决方案,而不使用scrollView,而是在keyboardWillShow/Hide方法中使用if语句.
func keyboardWillShow(notification: NSNotification) { if bottomText.editing{ self.view.window?.frame.origin.y = -1 * getKeyboardHeight(notification) } } func keyboardWillHide(notification: NSNotification) { if self.view.window?.frame.origin.y != 0 { self.view.window?.frame.origin.y += getKeyboardHeight(notification) } }
这对我来说是一个很好的解决方案,因为我只有两个文本字段.
移动整个视图:仅在编辑某些文本字段(bottomText)时
向下移动整个视图:仅当视图不在原始位置时
出现键盘时,只需使用此扩展名即可移动任何UIView。
extension UIView { func bindToKeyboard(){ NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillChange(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil) } @objc func keyboardWillChange(_ notification: NSNotification){ let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt let beginningFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue let endFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue let deltaY = endFrame.origin.y - beginningFrame.origin.y UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: { self.frame.origin.y += deltaY }, completion: nil) } }
然后在viewdidload中将视图绑定到键盘
UiView.bindToKeyboard()