iOS键盘 - 输入附件查看xib,自动布局不接收触摸事件

Eri*_*ich 6 keyboard xib ios autolayout inputaccessoryview

我已经构建了一个不断增长的UITextView连接到键盘,类似于股票消息应用程序,通过将.xib加载到键盘的inputAccessoryView中:

self.keyboardAccessoryView = [[[NSBundle mainBundle]
                             loadNibNamed:@"KeyboardAccessoryView"
                             owner:self options:nil]
                             firstObject];
Run Code Online (Sandbox Code Playgroud)

.xib看起来像这样,并且正在使用布局约束,以便当用户输入更多文本行时textView会垂直增长:

在此输入图像描述

旋转和一切都很好,除了一个大错误 - 当文本是多行时,只有最底线处理触摸事件.这意味着用户无法在UITextView内滚动,因为他们的触摸事件被传递到后面的(深灰色)视图并转而滚动.他们也无法在前3行选择和编辑他们的文字.

在此输入图像描述

我想我可以通过捕获所有点击事件的坐标并检查键盘是否打开以及UITextView有多高来做一个解决方法,然后选择正确的元素来接收触摸事件.但这是一个脆弱的解决方案,更复杂的旋转.在我的自动增长的文本视图方法中是否存在我缺少的东西,或者更容易修复?

max*_*lov 5

要使输入附件视图垂直增长,您只需设置它autoresizingMask = .flexibleHeight,计算它intrinsicContentSize并让框架完成剩下的工作.

代码:

class InputAccessoryView: UIView, UITextViewDelegate {

    let textView = UITextView()

    override init(frame: CGRect) {
        super.init(frame: frame)

        // This is required to make the view grow vertically
        self.autoresizingMask = UIViewAutoresizing.flexibleHeight

        // Setup textView as needed
        self.addSubview(self.textView)
        self.textView.translatesAutoresizingMaskIntoConstraints = false
        self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[textView]|", options: [], metrics: nil, views: ["textView": self.textView]))
    self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[textView]|", options: [], metrics: nil, views: ["textView": self.textView]))

        self.textView.delegate = self

        // Disabling textView scrolling prevents some undesired effects,
        // like incorrect contentOffset when adding new line,
        // and makes the textView behave similar to Apple's Messages app
        self.textView.scrollEnabled = false
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override var intrinsicContentSize: CGSize {
        // Calculate intrinsicContentSize that will fit all the text
        let textSize = self.textView.sizeThatFits(CGSize(width: self.textView.bounds.width, height: CGFloat.max))
        return CGSize(width: self.bounds.width, height: textSize.height)
    }

    // MARK: UITextViewDelegate

    func textViewDidChange(_ textView: UITextView) {
        // Re-calculate intrinsicContentSize when text changes
        self.invalidateIntrinsicContentSize()
    }

}
Run Code Online (Sandbox Code Playgroud)

这种方法非常简单和可靠,因为它不需要黑客约束或每次更改大小时重新创建视图.


Eri*_*ich 2

我发现即使键盘配件输入随着自动布局垂直增长,但它的框架却没有。因此,每次 uitextview 的高度增大、缩小和旋转时,您都必须调整键盘配件的框架。这引入了一些复杂性,因为 iOS7 中的 UITextView 出了名的错误——我注意到 iPhone、iPad 和模拟器之间的行为不一致。