键盘出现时,UIScrollView无法正确移动视图

时间:2015-08-11 14:17:13

标签: ios swift uitableview uiscrollview keyboard-events

我有一个视图控制器,UIScrollView固定到所有4个边。然后在UIView内部将其所有4个边固定到滚动视图,并添加相等的宽度和相等的高度约束。

在此视图中,有两个容器视图。这两个容器视图嵌入了两个单独的UITableViewControllers。我没有收到自动布局错误或警告。

enter image description here

这就是它运行时的样子。

enter image description here enter image description here

在底部表格视图中,一个单元格(第一个部分的中间一个)具有UITextField,底部单元格具有UITextView。很明显,当键盘出现时,这些字段会变得模糊不清。

所以我想要做的是在键盘出现时移动包含两个容器视图的整个视图。这就是我将它嵌入到scrollview中的原因。我使用此代码来监视键盘显示/隐藏,并相应地设置scrollview的内容插入。

class ViewController: UIViewController {

    @IBOutlet weak var scrollView: UIScrollView!

    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)
    }

    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

    func keyboardWillShow(notification: NSNotification) {
        adjustInsetForKeyboard(true, notification: notification)
    }

    func keyboardWillHide(notification: NSNotification) {
        adjustInsetForKeyboard(false, notification: notification)
    }

    func adjustInsetForKeyboard(show: Bool, notification: NSNotification) {
        let userInfo = notification.userInfo ?? [:]
        let keybaordFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue()
        let adjustmentHeight = (CGRectGetHeight(keybaordFrame)) * (show ? 1 : -1)
        scrollView.contentInset.bottom += adjustmentHeight
    }

}

但是有几个问题。

  1. 当键盘出现时,虽然我更改了scrollview的内容插入,但整个视图不会移动。这样做很奇怪。底部的tableview位于顶部表格视图下方。它更容易展示,所以这里是一个视频。
  2. Tableviews overlapping issue

    1. 当我重新聚焦文本字段超过1次时,滚动视图会离开屏幕!
    2. Tableview going off the screen

      任何人都知道为什么会这样?

      Dropbox link to demo project

2 个答案:

答案 0 :(得分:1)

当显示键盘时,UITableViewController已自动处理内容插入的调整。没有记录的方法来禁用此行为。您可以在StaticTableViewController中覆盖viewWillAppear(animated:Bool),而不是调用它的超级方法:

override func viewWillAppear(animated: Bool) {
}

这可能是UITableViewController注册键盘事件的地方,因为这会禁用内容插入调整。但是,我不能告诉你是否会有其他不会调用UITableViewController的viewWillAppear的不利影响,并且这种行为可能会随着iOS的未来版本而改变。因此更安全的方法是不使用UITableViewController并将标准UITableView添加到UIViewController并在其中加载您的单元格。

另请注意,使用您的设计,用户可以一直向上滚动并隐藏键盘后面的较低内容视图。然后用户无法向下滚动,因为任何滚动只会滚动并反弹上方的桌面视图。因此,一旦用户滚动

,请重新考虑您的设计或隐藏键盘

答案 1 :(得分:0)

有几种方法:

  1. 要观察UIKeyboadWillShowNotification和UIKeyboardWillHideNotification,从中获取键盘大小数据并正确调整scrollView contentInset底值。

    func viewDidAppear() {
        super.viewDidAppear()
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "increaseContentInset:", name: UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "decreaseContentInset:", name: UIKeyboardWillHideNotification, object: nil)
    }
    
    func viewDidDisappear(){
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    func increaseContentInset(notification: NSNotification) {
        let endRect = notification.userInfo![UIKeyboardFrameEndUserInfoKey]
        scrollView.contentInset = UIEdgeInsetsMake(0, 0, CGRectGetHeight(endRect), 0)
    }
    
    func decreaseContentInset(notification: NSNotification) {
        scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
    }
    
  2. 使用库。我强烈建议您使用TPKeyboardAvoiding