2012-01-26 4 views
2

私のアプリでは、私はかなり大きなフォームに記入する必要があります。フォーム自体は、テーブルビューとスタティックセルモードで作成されます。各セルにはラベルとテキストフィールドが含まれています。キーボードの上にツールバーを追加して、テキストフィールド間を移動できるようにしたかったのです。私はそれをしましたが、それは非常に奇妙な行動です(少なくとも私は考える)。iOS 5:TextFieldsの間でジャンプするときの不思議な動作

次のテキストフィールドにジャンプする際に問題はありませんが、前のテキストフィールドにジャンプすることは表示されている場合にのみ可能です。表示されていない場合、古いテキストフィールドは最初のレスポンダのままですが、テーブルビューをスクロールして目的のテキストフィールドが表示されると、最初のレスポンダになります(私はクリックしません)。まあ、これはもちろん、私が望む行動ではありません。

私の質問です:この種の動作は正常ですか?何とかそれを回避できますか?

この種の動作を確認したい場合は、問題を示すXcodeプロジェクトをアップロードしました。 zipプロジェクトはdownloadからダウンロードできます。コードの主要部分を以下に説明します。

スタティックセルでグループ化されたテーブルビューを設定しました。それぞれにラベルとtextfieldが入っています。私はすべてのテキストフィールド用のアウトレットを作成してアクセスしました。私のviewDidLoadメソッドでは、ツールバーとそのボタンを作成し、テキストフィールドを配列に格納し、テキストフィールドの代理人になるようにコントローラを設定します。

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // create the keyboard toolbar with navigation elements 
    self.keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)]; 

    UIBarButtonItem *prevButton = [[UIBarButtonItem alloc] initWithTitle:@"Previous" style:UIBarButtonItemStyleBordered target:self action:@selector(prevClicked:)]; 
    UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:@"Next" style:UIBarButtonItemStyleBordered target:self action:@selector(nextClicked:)]; 

    [self.keyboardToolbar setItems:[NSArray arrayWithObjects:prevButton, nextButton, nil]]; 


    // create the field chain 
    self.fields = [NSArray arrayWithObjects:self.aField, self.bField, self.cField, self.dField, self.eField, self.fField, nil]; 

    // for scrolling and keeping track of currently active field 
    NSInteger max = [self.fields count]; 
    for(NSInteger i = 0; i < max; i++) { 
     UITextField *curr = (UITextField *)[self.fields objectAtIndex:i]; 
     curr.delegate  = self; 
    } 
} 

テキストフィールドデリゲートメソッドは、アクティブテキストフィールドの参照を格納し、改行が挿入されないようにします。

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField 
{ 
    textField.inputAccessoryView = self.keyboardToolbar; 
    return YES; 
} 

- (void)textFieldDidBeginEditing:(UITextField *)textField 
{ 
    // set the current active textfield 
    self.currentField = textField; 

    // scroll this textfield to top 
    UITableViewCell *cell = (UITableViewCell *)textField.superview.superview; 
    [self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
} 

- (BOOL)textFieldShouldReturn:(UITextField *)textField 
{ 
    [textField resignFirstResponder]; 
    self.currentField = nil; 
    return NO; 
} 

最後に、ツールバーボタンのセレクタと次のテキストフィールドを取得するロジックがあります。

- (void)moveResponderByStep:(NSInteger)step 
{ 
    // only move if a textfield is the current responder 
    if(![self.currentField isEditing]) { 
     return; 
    } 

    // where we are and where to move 
    NSInteger max = [self.fields count]; 
    NSInteger moveToNumber; 

    for(NSInteger i = 0; i < max; i++) { 
     if(self.currentField == [self.fields objectAtIndex:i]) { 
      moveToNumber = i + step; 
     } 
    } 

    // stay in bounds 
    if(moveToNumber >= max || moveToNumber < 0) { 
     [self.currentField resignFirstResponder]; 
     return; 
    } 

    // move on 
    UITextField *next = [self.fields objectAtIndex:moveToNumber]; 
    [next becomeFirstResponder]; 

} 

- (void)prevClicked:(id)sender 
{ 
    [self moveResponderByStep:-1]; 
} 

- (void)nextClicked:(id)sender 
{ 
    [self moveResponderByStep:1]; 
} 

ありがとうございます!

+0

最初のレスポンダを変更する前に、前のセルが表示されるようにテーブルビューをスクロールしようとしましたか? – dasdom

+0

@dasdomとrobに感謝します。私は、私が試したことを言及すべきだった。問題は、cellが見えない場合、indexPathForCellはnullを返します。私のアプリケーションでは、すべての行にテキストフィールドが含まれているわけではないので、私は自分の位置を他の場所で把握しなければなりません。それはもちろん、私の意見では理想的な解決策ではありません。 – patman

答えて

0

まず、行が表示されているかどうかを確認してください。行が表示されていない場合は、表示するようにスクロールします。テキストフィールドを最初のレスポンダとして設定します。

関連する問題