簡體   English   中英

鍵盤隱藏時,為什么整個視圖都變得混亂?

[英]Why does the whole view jerk up when the keyboard hides?

調用keyboardWillHideFunction時,從viewController向上拖動整個視圖。 以下是發生探針的視頻。

屏幕抽搐的視頻

以下是我用來控制鍵盤通知的代碼。 我嘗試過嘗試動畫時間和布局約束,但是我還無法獲得更多。 關於如何解決它的任何建議,謝謝。

基於建議的可編輯代碼-我已經嘗試按照建議的那樣為布局約束創建變量,但是問題仍然存在,為什么?

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

}

keyboardWillShow內將顯示

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

並在keyboardWillHidekeyboardWillHide

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
}

每次調用以下行時,都會添加一個新的約束:

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

您需要添加對約束的引用,只需更改其常數即可。

let constraint = self.searchBarTopTags?.myView.bottomAnchor.constraint...
contraint.constant = ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM