简体   繁体   English

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

[英]iOS Keyboard - input Accessory View xib with autolayout not receiving touch event

I've built a growing UITextView attached to the keyboard, similar to the stock Messages app, by loading a .xib into the keyboard's inputAccessoryView as such: 我已经构建了一个不断增长的UITextView连接到键盘,类似于股票消息应用程序,通过将.xib加载到键盘的inputAccessoryView中:

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

The .xib looks like this, and is using layout constraints so that the textView grows vertically when the user enters more lines of text: .xib看起来像这样,并且正在使用布局约束,以便当用户输入更多文本行时textView会垂直增长:

在此输入图像描述

This is all working great, with rotation and everything, except one big bug -- when the text is multiple lines, only the very bottom line handles touch events. 旋转和一切都很好,除了一个大错误 - 当文本是多行时,只有最底线处理触摸事件。 This means that a user cannot scroll inside the UITextView because their touch events are being passed to the (dark gray) view in the back and scrolling that instead. 这意味着用户无法在UITextView内滚动,因为他们的触摸事件被传递到后面的(深灰色)视图并转而滚动。 They also cannot select and edit their text on the top 3 lines. 他们也无法在前3行选择和编辑他们的文字。

在此输入图像描述

I think I could do a workaround by capturing the coordinates of all tap events and checking if the keyboard is open and how tall the UITextView is, then selecting the correct element to receive the touch event. 我想我可以通过捕获所有点击事件的坐标并检查键盘是否打开以及UITextView有多高来做一个解决方法,然后选择正确的元素来接收触摸事件。 But this is brittle solution that is more complicated with rotation. 但这是一个脆弱的解决方案,更复杂的旋转。 Is there something I'm missing in my auto-growing text view approach, or some easier fix? 在我的自动增长的文本视图方法中是否存在我缺少的东西,或者更容易修复?

To make input accessory view grow vertically you just set its autoresizingMask = .flexibleHeight , calculate its intrinsicContentSize and let the framework do the rest. 要使输入附件视图垂直增长,只需​​设置其autoresizingMask = .flexibleHeight ,计算其intrinsicContentSize并让框架执行其余操作。

The code: 代码:

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

}

This approach is quite straightforward and reliable, as it doesn't require hacking constraints or recreating the view each time its size changes. 这种方法非常简单和可靠,因为它不需要黑客约束或每次更改大小时重新创建视图。

I figured out that even though the keyboard accessory input grows vertically with auto layout, its frame does not. 我发现尽管键盘附件输入在自动布局下垂直增长,但它的框架却没有。 So you have to adjust the keyboard accessory's frame each time the height of the uitextview grows, shrinks, and rotates. 因此,每次uitextview的高度增大,缩小和旋转时,您都必须调整键盘附件的框架。 This introduces some complications as UITextView's in iOS7 are notoriously buggy -- I noticed behavior was not consistent across iPhone, iPad, and the Simulator. 这引入了一些复杂性,因为iOS7中的UITextView是臭名昭着的错误 - 我注意到iPhone,iPad和模拟器的行为不一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM