【问题标题】:KeyboardDidShow called when keyboard isn't shown未显示键盘时调用 KeyboardDidShow
【发布时间】:2018-09-24 00:13:12
【问题描述】:

所以我使用 KeyboardDidShow 设置了键盘观察器,这样我就可以仅在显示键盘时向上移动视图。但是,KeyboardDidShow 在每个视图启动时运行,并且在随机时间运行。我尝试过监控键盘框架,并且仅在框架发生变化时才移动视图,但是即使没有显示键盘,视图也会经常发生变化。通常,每当首次启动视图时都会发生这种情况,因此我尝试添加延迟,但它不是很可靠。

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidShow(_:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
    }

@objc func keyboardDidShow(_ notification: Notification) {

    let userInfo = notification.userInfo!
    let beginFrameValue = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)!
    let beginFrame = beginFrameValue.cgRectValue
    let endFrameValue = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)!
    let endFrame = endFrameValue.cgRectValue

    if beginFrame.equalTo(endFrame) {
        return
    } else {
        let indexPath = IndexPath(item: 0, section: 0)
        if UIScreen.main.bounds.height == 812 {
            collectionView?.contentInset = UIEdgeInsets(top: 318 + view.safeAreaInsets.bottom, left: 0, bottom: 73, right: 0)
        } 
        collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: true)
    }
}

【问题讨论】:

  • 你最好只使用keyboardDidChangeFrameNotification。它还将通知 kb 几何图形随动画持续时间的变化。当键盘即将显示/隐藏以及旋转设备时调用它
  • 我尝试使用keyboardDidChangeFrame,但只要第一次显示视图,它仍然会运行。我在某处读到它们在开始时运行,因为当时(或类似)配置了键盘的框架

标签: swift keyboard


【解决方案1】:

问题是您配置了错误的通知。不要使用 UIKeyboardDidShow。使用 UIKeyboardWillShow,并检查旧框架、新框架以及新框架是否会覆盖您的视图。

实现一个健壮的实现并非易事,但它肯定是一个之前已解决的问题,已在此处多次解释。

【讨论】:

    【解决方案2】:

    对于 UIViewController 实例,仅当视图可见且不订阅通知多次时,您才需要观察这些通知。最好的方法是:

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)        
        NotificationCenter.default.addObserver(self, selector: #selector(onKeyboardWillChangeFrame(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
    }
    

    这是我项目中用于处理键盘框架的工作代码

    @objc private func onKeyboardWillChangeFrame(_ notification: NSNotification) {
        // extract values
        if let userInfo = notification.userInfo,
            let keyboardFrameEnd = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
            let animationCurveInt = (userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.intValue {
    
            /*
             СУКАБЛЯТЬ
             With upgrate to Swift 4.2 UIView.AnimationCurve(rawValue: 7) returns actual instance of
             UIView.AnimationCurve which crashes on access, mod by 4 limits value to max
             */
            let animationCurve = UIView.AnimationCurve(rawValue: animationCurveInt % 4) ?? .easeIn
    
            // View chanages
            let topPoint = self.view.convert(keyboardFrameEnd.origin, from: self.view.window)
            let height = self.view.bounds.size.height - topPoint.y
    
            ... update your constraints or manually update vars that affect layoutSubviews()...
    
            let animationDuration: TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
            var animationOptions: UIView.AnimationOptions = []
            switch animationCurve {
                case .easeInOut: animationOptions = .curveEaseInOut
                case .easeIn: animationOptions = .curveEaseIn
                case .easeOut: animationOptions = .curveEaseOut
                case .linear: animationOptions = .curveLinear
            }
    
            // run animation
            UIView.animate(withDuration: animationDuration, delay: 0, options: animationOptions, animations: {
                self.view.layoutIfNeeded()
            })
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-21
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 2019-02-26
      相关资源
      最近更新 更多