代码之家  ›  专栏  ›  技术社区  ›  TheRedCamaro3.0 3.0

当键盘隐藏时,为什么整个视图会突然出现?

  •  0
  • TheRedCamaro3.0 3.0  · 技术社区  · 7 年前

    vidoe of screen jerking

    下面是我用来控制键盘通知的代码。我已经尝试过使用动画时间和布局限制,但我一直没能走得更远。关于如何修复的任何建议,谢谢。

    基于建议编辑代码-我曾尝试按照建议为布局约束创建一个变量,但问题仍然存在,为什么?

    import UIKit
    import Foundation
    
    extension UIView {
        func currentFirstResponder() -> UIResponder? {
            if self.isFirstResponder {
                return self
            }
    
            for view in self.subviews {
                if let responder = view.currentFirstResponder() {
                    return responder
                }
            }
    
            return nil
        }
    }
    
    extension Notification.Name{
        static let showKeyboard = Notification.Name("showKeyboard")
    }
    
    class KeyboardSlider: NSObject {
        // variables to hold and process information from the view using this class
        weak var view: UIView?
        var searchBarTopTags:SearchBarTopTagsViewController?
        var amountToShiftBy:CGFloat!
        var originalFrame:CGRect!
        var previewController:PreviewController!
    
        @objc func keyboardWillShow(notification: NSNotification) {
    self.searchBarTopTags?.myViewBottomLayoutConstraint.constant =  -self.getKeyboardHeight(notification as! Notification) + previewController.view.safeAreaInsets.bottom
            UIView.animate(withDuration: 0, animations: {
                self.view?.layoutIfNeeded()
                self.searchBarTopTags?.myView.layoutIfNeeded()
    
            })
        }
    
        @objc func keyboardWillHide(notification:NSNotification){
    
            self.searchBarTopTags?.myViewBottomLayoutConstraint.constant = 0
            UIView.animate(withDuration: 0, animations: {
                self.view?.layoutIfNeeded()
                self.searchBarTopTags?.myView.layoutIfNeeded()
            })
        }
        func getKeyboardHeight(_ notification:Notification) -> CGFloat {
            // get exact height of keyboard on all devices and convert to float value to return for use
            let userInfo = notification.userInfo
            let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue
            return keyboardSize.cgRectValue.height
        }
    
        func subscribeToKeyboardNotifications(view: UIView) {
            // assigning view to class' counterpart
            self.view = view
            // when UIKeyboardWillShow do keyboardWillShow function
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
        }
    
    
        func subscribeToKeyboardNotifications(view: UIView, previewController:PreviewController? = nil) {
            // assigning view to class' counterpart
            self.view = view
            self.searchBarTopTags = previewController?.searchBarTopTags
            self.previewController = previewController
    
            // when UIKeyboardWillShow do keyboardWillShow function
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: .UIKeyboardWillHide, object: nil)
        }
    
    
        func unsubscribeFromKeyboardNotifications() {
            NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
            NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
        }
    
    }
    

    原始代码:

    import UIKit
    import Foundation
    
    extension UIView {
        func currentFirstResponder() -> UIResponder? {
            if self.isFirstResponder {
                return self
            }
    
            for view in self.subviews {
                if let responder = view.currentFirstResponder() {
                    return responder
                }
            }
    
            return nil
        }
    }
    
    extension Notification.Name{
        static let showKeyboard = Notification.Name("showKeyboard")
    }
    
    class KeyboardSlider: NSObject {
        // variables to hold and process information from the view using this class
        weak var view: UIView?
        var searchBarTopTags:SearchBarTopTagsViewController?
        var amountToShiftBy:CGFloat!
        var originalFrame:CGRect!
    
        @objc func keyboardWillShow(notification: NSNotification) {
            self.originalFrame = self.searchBarTopTags?.myView.frame
            self.amountToShiftBy = (self.searchBarTopTags?.view.frame.maxY)! - self.getKeyboardHeight(notification as! Notification) - (self.searchBarTopTags?.myView.frame.height)!
            self.amountToShiftBy = (searchBarTopTags?.view.bounds.height)! - self.getKeyboardHeight(notification as! Notification) - (searchBarTopTags?.myView.bounds.height)!
            self.searchBarTopTags?.myView.bottomAnchor.constraint(equalTo: (self.searchBarTopTags?.view.bottomAnchor)!, constant: -self.amountToShiftBy).isActive = true
    
            UIView.animate(withDuration: 0, animations: {
                self.view?.layoutIfNeeded()
                self.searchBarTopTags?.view.layoutIfNeeded()
                self.searchBarTopTags?.myView.layoutIfNeeded()        })
    
        }
    
        @objc func keyboardWillHide(notification:NSNotification){
    
            self.searchBarTopTags?.myView.bottomAnchor.constraint(equalTo: (self.searchBarTopTags?.view.bottomAnchor)!, constant: 0).isActive = true
            UIView.animate(withDuration: 0, animations: {
                self.view?.layoutIfNeeded()
                self.searchBarTopTags?.view.layoutIfNeeded()
                self.searchBarTopTags?.myView.layoutIfNeeded()
            })
        }
        func getKeyboardHeight(_ notification:Notification) -> CGFloat {
            // get exact height of keyboard on all devices and convert to float value to return for use
            let userInfo = notification.userInfo
            let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue
            return keyboardSize.cgRectValue.height
        }
    
        func subscribeToKeyboardNotifications(view: UIView) {
            // assigning view to class' counterpart
            self.view = view
            // when UIKeyboardWillShow do keyboardWillShow function
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
        }
    
    
        func subscribeToKeyboardNotifications(view: UIView, seachBarTopTagsVC:SearchBarTopTagsViewController? = nil) {
            // assigning view to class' counterpart
            self.view = view
            self.searchBarTopTags = seachBarTopTagsVC
    
            // when UIKeyboardWillShow do keyboardWillShow function
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: .UIKeyboardWillHide, object: nil)
        }
    
    
        func unsubscribeFromKeyboardNotifications() {
            NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
            NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
        }
    
    }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Shehata Gamal    7 年前

    在…内 keyboardWillShow

    self.searchBarTopTags?.myView.bottomAnchor.constraint(equalTo: (self.searchBarTopTags?.view.bottomAnchor)!, constant: -self.amountToShiftBy).isActive = true
    

    里面 keyboardWillHide

    self.searchBarTopTags?.myView.bottomAnchor.constraint(equalTo: (self.searchBarTopTags?.view.bottomAnchor)!, constant: 0).isActive = true
    

    当键盘隐藏/显示时,您只需创建一次底部约束,例如在中 viewDidLoad ,然后在这些方法中使用常量值,如下所示

    var bottomConstraint:NSLayoutConstraint!
    

    bottomConstraint = self.searchBarTopTags?.myView.bottomAnchor.constraint(equalTo: (self.searchBarTopTags?.view.bottomAnchor)!, constant: 0)
    bottomConstraint.isActive = true
    

    //

    @objc func keyboardWillShow(notification: NSNotification) {
    
       // other code
       bottomConstraint.constant = -self.amountToShiftBy
    }
    
    @objc func keyboardWillHide(notification: NSNotification) {
    
       bottomConstraint.constant = 0 
       // other code
    }
    
        2
  •  0
  •   ukim    7 年前

    每次调用以下行时,都会添加一个新约束:

    self.searchBarTopTags?.myView.bottomAnchor.constraint(equalTo: (self.searchBarTopTags?.view.bottomAnchor)!, constant: -self.amountToShiftBy).isActive = true
    

    您需要添加对约束的引用,只需更改其常量即可。

    let constraint = self.searchBarTopTags?.myView.bottomAnchor.constraint...
    contraint.constant = ...
    
    推荐文章