Ios 当键盘显示为Swift 4时,为什么堆栈视图在3秒钟后消失?

Ios 当键盘显示为Swift 4时,为什么堆栈视图在3秒钟后消失?,ios,keyboard,swift4,Ios,Keyboard,Swift4,在屏幕的底部,我有一个stackView,里面有一个TextView。TextView将成为viewDidLoad()中的第一响应程序()。我想要的是,正如我提到的,键盘显示在stackView下面 这是我的密码: override func viewDidLoad() { super.viewDidLoad() textView.becomeFirstResponder() self.hideKeyboardWhenTappedAround() //here will

在屏幕的底部,我有一个
stackView
,里面有一个
TextView
。TextView将
成为
viewDidLoad()
中的第一响应程序()
。我想要的是,正如我提到的,键盘显示在stackView下面

这是我的密码:

override func viewDidLoad() {
    super.viewDidLoad()

    textView.becomeFirstResponder()
    self.hideKeyboardWhenTappedAround() //here will hide the keyboard

    NotificationCenter.default.addObserver(self, selector: #selector(MyViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(MyViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {

        if let window = self.view.window?.frame {
            // We're not just minusing the kb height from the view height because
            // the view could already have been resized for the keyboard before
            self.view.frame = CGRect(x: self.view.frame.origin.x,
                                    y: self.view.frame.origin.y,
                                    width: self.view.frame.width,
                                    height: window.origin.y + window.height - keyboardSize.height)
            }

        }
    }

 @objc func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {

            let viewHeight = self.view.frame.height
            self.view.frame = CGRect(x: self.view.frame.origin.x,
                                     y: self.view.frame.origin.y,
                                     width: self.view.frame.width,
                                     height: viewHeight + keyboardSize.height)
        }
    }
应用上述代码后,键盘显示。我提到的
stackView
在键盘上方停留了3秒钟。然后底部的
stackView
消失。即使我隐藏键盘,
stackView
也从未显示出来

我完全不知道发生了什么。请有人在这里解释一下我的代码出了什么问题

你可以试试

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 {

        self.viewBotCon.constant = -1 * keyboardSize.height

        self.view.layoutIfNeeded()

    }        
}

@objc func keyboardWillHide(notification: NSNotification) {

      self.viewBotCon.constant = 0

      self.view.layoutIfNeeded()
}

尽量使用自动布局。最好将框架和边界属性视为只读

实际上,最好的方法是

  • 设置从堆栈底部视图到安全区域的约束,并通过IBOutlet将其公开给您的代码

  • 我建议你们订阅UIKeyboardWillChangeFrame,这样你们就可以对键盘的变化做出反应了

  • 使用窗口坐标空间计算与键盘的所有交点:
    let stackViewFrame=stackView.convert(stackView.bounds,to:nil)

  • 计算键盘和stackview之间的交点:
    让交点=键盘框架。交点(stackViewFrame)

  • 将约束的常数调整为交点+偏移量:
    constraint.constant=intersection.size.height+offset

  • 从通知获取动画时间
    let duration=notification.userInfo[UIKeyboardAnimationDurationUserInfoKey].floatValue

  • 并使用动画更新布局:
    UIView.animate(withDuration:duration){self.view.layoutifneed()}

  • PS:您在viewDidLoad中订阅通知,并且从不取消订阅。这意味着,如果您有任何其他后续场景,则viewcontroller也会对这些场景做出反应,从而消耗性能并可能导致缺陷。最好是在
    视图中订阅键盘通知,然后在
    视图中取消订阅


    PSS:使用块而不是选择器来使用订阅对您的技能有好处

    如何布置视图?在底部的stackView中,我将前导、尾随和底部的约束设置为0,以使其在底部@MilanNosáľ
    ViewBotCon
    是指您想要向上/向下移动的视图的底部约束,将其拖动为IBOutlet'