iOS 自定义键盘扩展 - 将高度更改为全屏

iOS Custom Keyboard Extension - Change height to fullscreen

我有一个 iOS 自定义键盘扩展(UIInputViewController),我想让它全屏显示。

更改其高度非常简单:

self.heightConstraint = NSLayoutConstraint(item: self.view!,
                                                   attribute: NSLayoutConstraint.Attribute.height,
                                                   relatedBy: NSLayoutConstraint.Relation.equal,
                                                   toItem: nil,
                                                   attribute: NSLayoutConstraint.Attribute.notAnAttribute,
                                                   multiplier: 0,
                                                   constant: UIScreen.main.bounds.height)

问题是键盘框架位于 UIKeyboardDockView -- 包含地球(更改键盘)和麦克风(听写)图标的底部区域的顶部。

现在,我想访问该底部区域,以便将其高度减去 UIScreen.main.bounds.height

有人知道这是否可能吗?如果没有,请随时提出任何其他解决方案。

Xcode UI debugger view Simulator screenshot

这对我有用。看起来在 viewWillAppear 中调用 view.layoutIfNeeded() 很重要。

import UIKit

class InputVC: UIInputViewController {
    
    var initialHeightConstraint: NSLayoutConstraint?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        guard let view = view else { return }
        
        view.backgroundColor = .red
        
        view.translatesAutoresizingMaskIntoConstraints = false
        
        self.initialHeightConstraint = NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: UIScreen.main.bounds.height)
        self.initialHeightConstraint?.isActive = true
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        view.layoutIfNeeded()
    }
}

class ViewController: UIViewController {
    
    var inputVC = InputVC()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .green
    }
    
    override var canBecomeFirstResponder: Bool {
        true
    }
    
    override var inputAccessoryViewController: UIInputViewController? {
        inputVC
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        becomeFirstResponder()
    }
}

我也尝试在几个地方将它固定到 window,这也有效,但在控制台中出现约束错误。

override func didMove(toParent parent: UIViewController?) {
    super.didMove(toParent: parent)
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    guard let view = view, let window = view.window else { return }

    self.initialHeightConstraint?.isActive = false
    
    NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: window, attribute: .top, multiplier: 1, constant: 0).isActive = true
    
    NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: window, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
    
    NSLayoutConstraint(item: view, attribute: .left, relatedBy: .equal, toItem: window, attribute: .left, multiplier: 1, constant: 0).isActive = true

    NSLayoutConstraint(item: view, attribute: .right, relatedBy: .equal, toItem: window, attribute: .right, multiplier: 1, constant: 0).isActive = true

    self.view.layoutIfNeeded()
}