我正在try 为iPhone构建一个输入屏幕.屏幕上有多个输入字段.它们大多位于屏幕顶部,但有两个字段位于底部. 当用户试图编辑屏幕底部的文本时,键盘将弹出并覆盖整个屏幕. 我找到了一个简单的解决方案,当发生这种情况时将屏幕向上移动,但结果是当用户试图编辑这些字段时,屏幕always会向上移动,屏幕顶部的字段会移动到无法触及的位置.

在编辑底部字段时,是否有办法使屏幕only移动?

我使用了我发现的here个代码:

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
}

推荐答案

你的问题在this document by Apple页已经解释得很清楚了.此页面上的示例代码(位于Listing 4-1)完全符合您的需要,它仅在当前编辑应该在键盘下时才会滚动视图.你只需要把你需要的控件放在一个滚动视图中. 唯一的问题是,这是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,并在初始化方法中设置正确的委托:

self.you_text_field.delegate = self

记住在viewInit上调用registerForKeyboardNotifications,在Exit上调用deregisterFromKeyboardNotifications.

编辑/更新:SWIFT 4.2语法

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
}

Ios相关问答推荐

使用NavigationStack和.searchable时如何显示大型导航标题?

如何以最可靠的方式删除文本视图中的额外页边距?

使用UIGraphicsBeginIMAext创建新图像会扭曲图像 colored颜色

swift|在具有自定义单元格的多个TableView中没有任何内容

如何结合`@dynamicMemberLookup`和`ExpressibleByStringInterpolation`来实现方法链?

如何从单独的视图更改修饰符的值

如何解决错误 HE0004:无法在 Visual Studio 2022 中加载框架ContentDeliveryServices

当 Swift 枚举具有 any existential 作为其关联值之一时,我如何使它符合 `Equatable`?

SwiftUI - TextField - 在焦点上清除 Double 类型的值,在取消 Select 时恢复

SwiftUI 图像与下拉视图切换一起 skip

迁移到 UIKit 生命周期的应用程序不会调用 SceneDelegate

如何在不支持并发的自动关闭中修复'async'调用?

有哪些可靠的机制可以防止 CoreData CloudKit 中的数据重复?

在 iPad 上删除列表的顶部和底部行

如何关闭情节提要弹出框

使用未知类型创建图像格式是一个错误与 UIImagePickerController

如何使用 swift 添加速率按钮的链接?

使用 Swift 在一个 ViewController 中强制横向模式

UITextView 内容插图

如何在 iphone 屏幕中间显示活动指示器?