28

久しぶりの潜入者 - 初めてのポスター!

UITextViewWhatsAppのようにバーを再作成しているときに問題が発生しました。

私はカスタムUIViewサブクラスを使用しており、それを遅延してインスタンス化しています:

- (UIView *)inputAccessoryView

YES を返す:

- (BOOL)canBecomeFirstResponder

inputAccessoryView今、サイズが大きくなったらサイズを変更したいと思いUITextViewます。iOS 7では、ビューのフレームのサイズを変更するだけで、原点ではなく、呼び出すreloadInputViewsと機能します。ビューが上に移動して、キーボードの上に完全に表示されるようにします。

ただし、iOS 8 では、これは機能しません。それを機能させる唯一の方法は、フレームの原点も負の値に変更することです。これは問題ありませんが、奇妙なバグが発生する場合があります。たとえば、UIViewテキストを入力すると「元の」フレームに戻るなどです。

足りないものはありますか?inputAccessoryViewアプリの最新バージョンでのみ、ドラッグ時にキーボードを閉じる方法があるため、WhatsAppが使用していると確信しています。

あなたが私を助けることができるかどうか私に知らせてください!または、私に実行してほしいテストがあれば!

ありがとうございました!:)

ところで、これは私が呼び出したカスタムUIViewの高さを更新するために使用しているコードですcomposeBar:

// ComposeBar frame size
CGRect frame = self.composeBar.frame;
frame.size.height += heightDifference;
frame.origin.y -= heightDifference;
self.composeBar.frame = frame;
[self.composeBar.textView reloadInputViews]; // Tried with this
[self reloadInputViews];                     // and this

編集: 完全なソース コードは、@ https://github.com/manuelmenzella/SocketChat-iOSで入手できます。

4

9 に答える 9

33

動作が iOS 7 から iOS 8 に変わったので、私はかなり長い間、この壁に頭をぶつけてきました。

inputAccessoryView.autoresizingMask = UIViewAutoresizingFlexibleHeight;

当たり前!

于 2014-09-15T16:14:40.997 に答える
5

これは完全な自己完結型のソリューションです(正しい方向に向けてくれた@JohnnyC@JoãoNunes 変更をアニメーション化する方法を説明intrinsicContentてくれた@stigiに感謝します):

class InputAccessoryView: UIView {

    // InputAccessoryView is instantiated from nib, but it's not a requirement
    override func awakeFromNib() {
        super.awakeFromNib()        
        autoresizingMask = .FlexibleHeight
    }

    override func intrinsicContentSize() -> CGSize {
        let exactHeight = // calculate exact height of your view here
        return CGSize(width: UIViewNoIntrinsicMetric, height: exactHeight)
    }

    func somethingDidHappen() {
        // invalidate intrinsic content size, animate superview layout        
        UIView.animateWithDuration(0.2) {
            self.invalidateIntrinsicContentSize()
            self.superview?.setNeedsLayout()
            self.superview?.layoutIfNeeded()
        }
    }
}
于 2015-07-16T13:31:22.113 に答える
4

100% 機能する非常に単純な解決策は、すべての制約を列挙し、新しい高さの値を設定することです。ここにいくつかの C# コード (xamarin) があります:

foreach (var constraint in inputAccessoryView.Constraints)
{
    if (constraint.FirstAttribute == NSLayoutAttribute.Height)
    {
        constraint.Constant = newHeight;
    }
}
于 2015-02-03T21:19:56.490 に答える
1

はい、iOS8 は、inputAccessoryView にプライベートな高さの制約を追加します。

inputAccessoryView 全体を再作成して古いものを置き換えることは非常にコストのかかる操作になる可能性があることを考慮すると、入力ビューをリロードする前に制約を削除することができます

[inputAccessoryView removeConstraints:[inputAccessoryView constraints]];
[textView reloadInputViews];

ちょうど別の回避策

于 2014-12-15T21:14:59.097 に答える
0

これを修正するために、inputAccessoryView.autoresizingMask = UIViewAutoresizingFlexibleHeight; を使用しました。

しかしもちろん、これによりテキストビューが崩壊しました。そのため、ツールバーに制約を追加して必要に応じて更新するか、テキストビュー自体に制約を追加して更新するとうまくいきました。

于 2014-10-11T23:44:59.197 に答える
0

まず、inputAccessoryView を取得し、nil を設定します

UIView *inputAccessoryView = yourTextView.inputAccessoryView;
yourTextView.inputAccessoryView = nil;
[yourTextView reloadInputViews];

次に、フレームとレイアウトを設定します

inputAccessoryView.frame = XXX
[inputAccessoryView setNeedsLayout];
[inputAccessoryView layoutIfNeeded];

最後に新しいinputAccessoryViewを再度設定してリロードします

yourTextView.inputAccessoryView = inputAccessoryView;
[yourTextView reloadInputViews];
于 2015-07-07T09:50:39.107 に答える