7

.xib をキーボードの inputAccessoryView にロードすることで、ストック メッセージ アプリと同様に、キーボードにアタッチされた成長する UITextView を作成しました。

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

.xib は次のようになり、レイアウト制約を使用して、ユーザーがさらにテキスト行を入力すると textView が垂直方向に拡大するようにします。

ここに画像の説明を入力

これは、1 つの大きなバグ (テキストが複数行の場合、一番下の行だけがタッチ イベントを処理する) を除いて、回転とすべてでうまく機能しています。これは、ユーザーのタッチ イベントが背面の (濃い灰色の) ビューに渡され、代わりにスクロールしているため、ユーザーが 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 に答える