7

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

self.keyboardAccessoryView = [[[NSBundle mainBundle]
                             loadNibNamed:@"KeyboardAccessoryView"
                             owner:self options:nil]
                             firstObject];

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

在此处输入图像描述

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

在此处输入图像描述

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

4

2 回答 2

6

要使输入附件视图垂直增长,您只需设置它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()
    }

}

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

于 2015-09-18T08:51:42.607 回答
2

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

于 2014-04-30T21:33:24.373 回答