2011-08-25 10 views
7

私は、ビューの上部からビューの下部までのテキストフィールドを持つビューを持つアプリケーションを持っています。フィールドが表示されるようにボトムフィールドを編集するときにスクロールする必要がありましたが、正しく動作するようには見えませんでした。アクティブなテキストフィールドでのキーボードスクロール - 非表示へのスクロール?

Apple docsに続いて、そのコードをすべて私のプログラム(Listings 4-1,4-2)に置き、scrollViewactiveFieldアウトレットをヘッダファイルに追加してIBにリンクしました。

問題は、テキストフィールドをクリックすると、すべてのテキストフィールドが表示されなくなり、キーボードを閉じるまで問題になります。それらは非常に遠くまでスクロールします(再び、フィールドが表示されていない場所まで十分に移動します)。

この問題が原因で発生する可能性のあることは誰でも知っていますか?

私はクリックしなくても使用しているコードを正確に見ることができるように、ここにApple Docsのコードを配置します。

//my .h 
    IBOutlet UIScrollView *scrollView; 
    IBOutlet UITextField *activeField; 

//.m 
    // Call this method somewhere in your view controller setup code. 
    - (void)registerForKeyboardNotifications 
    { 
     [[NSNotificationCenter defaultCenter] addObserver:self 
       selector:@selector(keyboardWasShown:) 
       name:UIKeyboardDidShowNotification object:nil]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
      selector:@selector(keyboardWillBeHidden:) 
      name:UIKeyboardWillHideNotification object:nil]; 

} 

// Called when the UIKeyboardDidShowNotification is sent. 
- (void)keyboardWasShown:(NSNotification*)aNotification 
{ 
    NSDictionary* info = [aNotification userInfo]; 
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; 

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0); 
    scrollView.contentInset = contentInsets; 
    scrollView.scrollIndicatorInsets = contentInsets; 

    // If active text field is hidden by keyboard, scroll it so it's visible 
    // Your application might not need or want this behavior. 
    CGRect aRect = self.view.frame; 
    aRect.size.height -= kbSize.height; 
    if (!CGRectContainsPoint(aRect, activeField.frame.origin)) { 
     CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-kbSize.height); 
     [scrollView setContentOffset:scrollPoint animated:YES]; 
    } 
} 

// Called when the UIKeyboardWillHideNotification is sent 
- (void)keyboardWillBeHidden:(NSNotification*)aNotification 
{ 
    UIEdgeInsets contentInsets = UIEdgeInsetsZero; 
    scrollView.contentInset = contentInsets; 
    scrollView.scrollIndicatorInsets = contentInsets; 
} 
- (void)textFieldDidBeginEditing:(UITextField *)textField 
{ 
    activeField = textField; 
} 

- (void)textFieldDidEndEditing:(UITextField *)textField 
{ 
    activeField = nil; 
} 
+0

それはので、それを再現するために、アップルから許可を持っていることは疑問だので、私はあなたのポストのうち、アップルのコードのコピー&ペーストを編集しました。私はまた、司会者に見せるようにと指示しました - 私は公式の方針が何であるべきか、そうすべきかどうかはわかりません。 –

+0

@ジョシュ: "フェアユース"(http://en.wikipedia.org/wiki/Fair_use)の目的のために、コードの量はおそらくOKです。 –

+0

@Robert:ありがとう、ありがとう。ジェームズ、私はそれがあなたがそう選ぶなら、あなたがそれを戻すべきであることを意味すると思います。気にして申し訳ありません。 –

答えて

33

UPDATE:答え以下は時代遅れです。今のところあなたはUIScrollView、UITableView &より多くの種類のテキストフィールド操作を扱うのに "TPkeyboardavoiding"ライブラリを使うことができます。誰かが統合に問題があるかどうか、それを試してみてください。

旧回答

この機能のキーボード通知を登録する必要はありません。

// called when textField start editting. 
- (void)textFieldDidBeginEditing:(UITextField *)textField 
{ 
    activeField = textField; 
    [scrollView setContentOffset:CGPointMake(0,textField.center.y-60) animated:YES]; 
} 



// called when click on the retun button. 
- (BOOL)textFieldShouldReturn:(UITextField *)textField 
{ 


    NSInteger nextTag = textField.tag + 1; 
    // Try to find next responder 
    UIResponder *nextResponder = [textField.superview viewWithTag:nextTag]; 

    if (nextResponder) { 
     [scrollview setContentOffset:CGPointMake(0,textField.center.y-60) animated:YES]; 
     // Found next responder, so set it. 
     [nextResponder becomeFirstResponder]; 
    } else { 
     [scrollview setContentOffset:CGPointMake(0,0) animated:YES]; 
     [textField resignFirstResponder]; 
     return YES; 
    } 

    return NO; 
} 

注:ここに示すように、スクリーンキーボードの上にアクティブなTextFieldをセンタリングするためには、あなただけUIScrollViewの二つの方法のcontentOffsetを設定する必要がすべてのTextFieldは1,2のように増分のタグを持っている必要がありますが、 3とそうでない。そして代議員を自己に設定する。

おかげで、デリゲートを設定し、確認した後

+5

テキストフィールドが直接含まれていない場合スクロールビュー 'center.y'は間違った位置になります。したがって、正しい位置を計算する代わりに、次のようなものを使用してください。 '_scrollView.contentOffset = CGPointMake(0、[_scrollView convertPoint:CGPointZero fromView:textField] .y - 60); ' – AndiDog

+0

-60の値は? –

+0

-60は、ビューとキーボードのサイズに応じて可変になるオフセットでした。私の場合、その価値は私のために最も適していました。 – MinuMaster

0

は、私は、コードを経て、すべての座標の全てを引き出したと数学のすべてを行なったし、手動でいくつかの変数を設定する必要がありましたが、今で意図したとおりに動作します。

将来的に誰かが助けを必要とする場合は、私は喜んで助けてくれるでしょう。私のTwitterは私のプロフィールにあります。

+0

こんにちはJames、私はAppleのDocに従うことで問題をも満たしました。私の問題は、テキストフィールドをタップすると何も起こりません。スクロールバーは表示されず、スクロールバーも表示されません。あなたは私にこれに手を貸すことができますか?前もって感謝します。 – dumbfingers

+0

遅い応答に申し訳ありません。仕事で忙しかった。私が見ることができるいくつかのコードがありますか? IBを使用している場合は、すべてのアウトレットが接続されていることを確認してください。 – Baub

+0

こんにちはジェームズ、あなたの返事のおかげで、私はあなたに尋ねたほんの数時間後に自分でこの問題を解決しました。とにかくありがとう!!! – dumbfingers

6

私はそれを見つけたので、私はそれは素晴らしい作業、およびセットアップに非常に簡単ですTPKeyboardAvoiding

使用:

  1. あなたのビューコントローラのXIB
  2. 設定し、スクロールビューのクラスにUIScrollViewのを追加します。 TPKeyboardAvoidingScrollViewへ(IDインスペクタを介してxib内の )
  3. すべてのコントロールをそのスクロールビュー内に配置

また、キーボードの「次へ」ボタンを自動的に接続して、テキストフィールドを切り替えることができます。

幸運を祈る!

1

@ Minumasterのアプローチはうまくいきますが、キーボードの上にカスタムツールバーを使用しているときにリンゴがキーボードの高さを考慮しているように、はるかに単純で一般的な方法を提案したいと思います。 Appleのアプローチhereにはほとんど問題がありませんが、 です。ここで

は(少しAppleのやり方を変更された)私のアプローチである -

// Called when the UIKeyboardDidShowNotification is sent. 
- (void)keyboardWasShown:(NSNotification*)aNotification 
{ 
    NSDictionary* info = [aNotification userInfo]; 
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; 

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0); 
    self.scrollView.contentInset = contentInsets; 
    self.scrollView.scrollIndicatorInsets = contentInsets; 
} 

// Called when the UIKeyboardWillHideNotification is sent 
- (void)keyboardWillBeHidden:(NSNotification*)aNotification 
{ 
    UIEdgeInsets contentInsets = UIEdgeInsetsZero; 
    self.scrollView.contentInset = contentInsets; 
    self.scrollView.scrollIndicatorInsets = contentInsets; 
} 
関連する問題