iOS如何在更改输入视图时获得键盘高度?

时间:2018-03-21 08:43:38

标签: ios swift keyboard custom-keyboard

我正在尝试在键盘上方放置一个textview。键盘有两个视图 - 一个默认视图和一个自定义视图。可以在这两个键盘之间切换按钮。

我正在尝试使用以下代码将textview定位在键盘上方。但它表现得非常奇怪。不会一直调用keyboardWillShow通知。

注意:我希望它支持肖像和风景。

class ViewController: UIViewController {

    let textView = UITextView()
    let button = UIButton()

    var keyboardHeight: CGFloat = 0
    var keyboardView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        textView.backgroundColor = .lightGray
        button.backgroundColor = .red
        self.view.addSubview(textView)
        self.view.addSubview(button)
    }

    @objc func buttonAction() {
        if self.textView.inputView == nil {
            self.textView.inputView = keyboardView
            self.textView.inputView?.autoresizingMask = .flexibleHeight
            self.textView.reloadInputViews()
            textView.frame = CGRect(x: 0, y: self.view.frame.size.height - self.textView.inputView!.frame.size.height - 50, width: self.view.frame.size.width - 50, height: 50)
            button.frame = CGRect(x: self.view.frame.size.width - 50, y: self.view.frame.size.height - self.textView.inputView!.frame.size.height - 50, width: 50, height: 50)
        } else {
            self.textView.inputView = nil
            self.textView.reloadInputViews()
            textView.frame = CGRect(x: 0, y: self.view.frame.size.height - self.keyboardHeight - 50, width: self.view.frame.size.width - 50, height: 50)
            button.frame = CGRect(x: self.view.frame.size.width - 50, y: self.view.frame.size.height - self.keyboardHeight - 50, width: 50, height: 50)
        }
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        textView.frame = CGRect(x: 0, y: self.view.frame.size.height - self.keyboardHeight - 50, width: self.view.frame.size.width - 50, height: 50)
        button.frame = CGRect(x: self.view.frame.size.width - 50, y: self.view.frame.size.height - self.keyboardHeight - 50, width: 50, height: 50)
    }

    @objc func keyboardWillShow(notification: Notification) {
        if let userInfo = notification.userInfo {
            if let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
                self.keyboardHeight = keyboardFrame.size.height
                textView.frame = CGRect(x: 0, y: self.view.frame.size.height - self.keyboardHeight - 50, width: self.view.frame.size.width - 50, height: 50)
                button.frame = CGRect(x: self.view.frame.size.width - 50, y: self.view.frame.size.height - self.keyboardHeight - 50, width: 50, height: 50)
            }
        }
    }
}

1 个答案:

答案 0 :(得分:3)

如果您因为在自定义键盘和系统键盘之间切换而想要在键盘框架发生变化时获得键盘的高度,您可以通过多种方式实现它。

我个人不喜欢通知他们总是最终给我一个离散的值,虽然大多数实时情况他们都足够好当你需要修改UI作为键盘框架实时更改(如尝试解除滚动表上的键盘喜欢什么样的应用程序,当你移动时键盘会用手指向下移动,当键盘向下滚动时你需要实时对齐视图)

无论如何,我相信下面解释的方法也应该有助于你在切换时获得准确的键盘高度

第1步:

创建一个UIView的子类,我们将稍后将其作为输入附件视图添加到textView / textField

protocol KeyBoardObserverProtocol : NSObjectProtocol {
    func keyboardFrameChanged(frame : CGRect)
}

class KeyboardObserverAccessoryView: UIView {
    weak var keyboardDelegate:KeyBoardObserverProtocol? = nil
    private var kvoContext: UInt8 = 1

    override func willMove(toSuperview newSuperview: UIView?) {
        if newSuperview == nil {
            self.superview?.removeObserver(self, forKeyPath: "center")
        }
        else{
            newSuperview?.addObserver(self, forKeyPath: "center", options: [NSKeyValueObservingOptions.new, NSKeyValueObservingOptions.initial], context: &kvoContext)
        }
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if let theChange = change as [NSKeyValueChangeKey : AnyObject]?{
            if theChange[NSKeyValueChangeKey.newKey] != nil{
                if self.keyboardDelegate != nil && self.superview?.frame != nil {
                    self.keyboardDelegate?.keyboardFrameChanged(frame: (self.superview?.frame)!)
                }
            }
        }
    }
}

虽然代码看起来很大而且里面很乱,但很容易理解。它只是在收到调用willMove(toSuperview newSuperview: UIView?)后开始使用KVO开始观察父视图框,因为当你知道你的视图被移动到父视图时你知道现在你需要监视父框架。

每当您的KVO触发新值时,您都会使用该代表将其通知给对方

如何使用?

    keyBoardObserverAccessoryView = KeyboardObserverAccessoryView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
    keyBoardObserverAccessoryView.keyboardDelegate = self
    self.textView.inputAccessoryView = keyBoardObserverAccessoryView

多数民众赞成:)现在,如果您想提供自定义输入配件视图,请确保您从KeyboardObserverAccessoryView n延伸享受优惠

希望有所帮助:)