web-dev-qa-db-ja.com

UITextFieldがファーストレスポンダーになったときにUIScrollViewを自動スクロールする方法

サブビューUIScrollViewsが最初のレスポンダーになった場合、UITextFieldが自動的にスクロールすることを示唆する here の周りの投稿を見てきました。ただし、これを機能させる方法がわかりません。

私が持っているのはUIViewControllerを持つUIScrollViewで、UIScrollViewの中に複数のテキストフィールドがあります。

必要に応じてこれを手動で行う方法を知っています。しかし、私が読んでいたものから、それを自動スクロールさせることは可能だと思われます。助けてください。

27
Nosrettap

この例がお役に立てば幸いです。このコードで任意のポイントまでスクロールできます。

scrollView.contentOffset = CGPointMake(0,0);

したがって、テキストフィールドがある場合は、ビュー上にX、Yの位置が必要なので、使用できます

CGPoint point = textfield.frame.Origin ;
scrollView.contentOffset = point 

これでうまくいくはずです、

ただし、このコードをいつ呼び出すかわからない場合は、ITextFieldDelegateメソッドを学ぶ必要があります

このメソッドをコードに実装します

- (void)textFieldDidBeginEditing:(UITextField *)textField {
// Place Scroll Code here
}

デリゲートメソッドの使用方法を知っていることを望みます。

33
Adeel Pervaiz

この質問にはすでに回答済みですが、iOS 9では完璧に機能するように思えるので、@ Adeelと@Basilの回答から使用したコードの組み合わせを共有すると思いました。

-(void)textFieldDidBeginEditing:(UITextField *)textField {

    // Scroll to the text field so that it is
    // not hidden by the keyboard during editing.
    [scroll setContentOffset:CGPointMake(0, (textField.superview.frame.Origin.y + (textField.frame.Origin.y))) animated:YES];
}

-(void)textFieldDidEndEditing:(UITextField *)textField {

    // Remove any content offset from the scroll
    // view otherwise the scroll view will look odd.
    [scroll setContentOffset:CGPointMake(0, 0) animated:YES];
}

また、アニメーション化された方法を使用しました。これにより、移行がよりスムーズになります。

11
Supertecnoboff

手動で行う必要はありません。これがデフォルトの動作です。動作が表示されない理由として2つの可能性があります。

  1. 最も可能性の高い理由は、キーボードがUITextFieldを覆っていることです。解決策については以下を参照してください
  2. 他の可能性は、ビュー階層内のUIScrollViewUITextFieldの間の別のUIScrollViewが自動スクロールすることです。これは可能性は低いですが、それでも問題を引き起こす可能性があります。

#1の場合、Appleの推奨事項 キーボードの下にあるコンテンツの移動 に類似したものを実装します。 Appleによって提供されるコードは回転を考慮しません。コードの改善については、 このブログ投稿keyboardDidShowメソッドの実装を確認してください。ウィンドウを使用してキーボードのフレームを適切に変換します。

6
Michael McGuire
- (void)textFieldDidBeginEditing:(UITextField *)textField {
    CGRect rect = [textField bounds];
    rect = [textField convertRect:rect toView:self.scrollView];
    rect.Origin.x = 0 ;
    rect.Origin.y -= 60 ;
    rect.size.height = 400;

    [self.scrollView scrollRectToVisible:rect animated:YES];
}
4
George

@Supertecnoboffの回答に対するSwift 4の更新です。

func textFieldDidBeginEditing(_ textField: UITextField) {
    scroll.setContentOffset(CGPoint(x: 0, y: (textField.superview?.frame.Origin.y)!), animated: true)
}

func textFieldDidEndEditing(_ textField: UITextField) {
    scroll.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
}

UITextFieldDelegateを拡張し、テキストフィールドのデリゲートをselfに設定してください。

4
donmiller

UITextFieldのautoScrollにこの関数を使用できます

UITextFieldDelegate

- (void)textFieldDidBeginEditing:(UITextField *)textField {

[self autoScrolTextField:textField onScrollView:self.scrollView];
}




- (void) autoScrolTextField: (UITextField *) textField onScrollView: (UIScrollView *) scrollView { 
 float slidePoint = 0.0f;
float keyBoard_Y_Origin = self.view.bounds.size.height - 216.0f;
float textFieldButtomPoint = textField.superview.frame.Origin.y + (textField.frame.Origin.y + textField.frame.size.height);

if (keyBoard_Y_Origin < textFieldButtomPoint - scrollView.contentOffset.y) {
    slidePoint = textFieldButtomPoint - keyBoard_Y_Origin + 10.0f;
    CGPoint point = CGPointMake(0.0f, slidePoint);
    scrollView.contentOffset = point;
}

編集:

私は現在、この開発者に IQKeyboardManager を使用しており、これを試す必要があります。

3
Basil Mariano

複数のテキストフィールドがある場合はTextfield1Textfield2Textfield3そして、textfield2が最初のレスポンダーになったときにy軸に沿ってスクロールビューをスクロールしたい場合:

if([Textfield2 isFirstResponder])
{
    scrollView.contentOffset = CGPointMake(0,yourY);
} 
1
Deep Batra

Michael McGuireが上記のポイント#2で述べたように、スクロールビューにテキストフィールドとスクロールビューの間に別のスクロールビューが含まれている場合、システムのデフォルトの動作は正しく動作しません。スクロールビューが単にnextテキストフィールド(どちらも調整が必要なスクロールビューに埋め込まれている)がある場合にも、誤動作が発生することがわかりましたテキストフィールドの編集を開始するときにテキストフィールドを表示するには、iOS 12.1を使用します。

しかし、私の解決策は上記とは異なります。プロパティを追加してメソッドをオーバーライドできるようにサブクラス化されたトップレベルのスクロールビューで、scrollRectToVisible:animated:をオーバーライドします。渡されたrect(テキストフィールドのフレーム)を調整するように指示するプロパティセットがない限り、単に[super scrollRectToVisible:animated:]を呼び出します。プロパティが非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のデリゲートメソッドで、単に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がバグを修正した場合、まだ動作する可能性があります(指が交差しています)。

0
jsbox