上記のポイント 2 で Michael McGuire が述べたように、スクロール ビューにテキスト フィールドとスクロール ビューの間に別のスクロール ビューが含まれている場合、システムのデフォルトの動作は正しく動作しません。テキストフィールドの隣にスクロールビューがある場合にも誤動作が発生することがわかりました(両方ともスクロールビューに埋め込まれており、テキストフィールドの編集を開始したいときにテキストフィールドを表示するように調整する必要があります。これはiOS 12.1 で。
しかし、私の解決策は上記とは異なります。プロパティを追加してメソッドをオーバーライドできるようにサブクラス化されている最上位のスクロール ビューでは、オーバーライドしますscrollRectToVisible:animated:
。テキストフィールドのフレームである、渡された[super scrollRectToVisible:animated:]
ものを調整するように指示するプロパティセットがない限り、単にそれを呼び出します。rect
プロパティが非 nil の場合、それはUITextField
問題の への参照でありrect
、スクロール ビューがシステムの想定よりも先に進むように調整されます。したがって、これをUIScrollView
のサブクラス化されたヘッダー ファイルに入れます。
@property (nullable) UITextField *textFieldToBringIntoView;
(実装に適切@synthesize textFieldToBringIntoView;
です。次に、このオーバーライドメソッドを実装に追加しました:
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)how
{
if (textFieldToBringIntoView) {
// Do whatever mucking with `rect`'s origin needed to make it visible
// based on context or its spatial relationship with the other
// view that the system is getting confused by.
textFieldToBringIntoView = nil; // Go back to normal
}
[super scrollRectToVisible:rect animated:how];
}
UITextField
編集を開始しようとしているときの for のデリゲート メソッドで、問題textFieldToBringIntoView
の に設定するだけです。textField
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
// Ensure it scrolls into view so that keyboard doesn't obscure it
// The system is about to call |scrollRectIntoView:| for the scrolling
// superview, but the system doesn't get things right in certain cases.
UIScrollView *parent = (UIScrollView *)textField.superview;
// (or figure out the parent UIScrollView some other way)
// Tell the override to do something special just once
// based on this text field's position in its parent's scroll view.
parent.textFieldToBringIntoView = textField;
// The override function will set this back to nil
return(YES);
}
うまくいくようです。そして、Apple がバグを修正したとしても、まだ機能するようです (指を交差させてください)。