48

定義済みの値のみを取得できるカスタム セルを備えたこの UITableView があるため、inputView として UIPickerView を使用します。フィールドを編集して更新された値を表示する必要があるまでは、すべて問題ありません。

物事をより明確にし、維持しやすくするために、デリゲートとデータ ソースを別のクラスとして作成し、通知を使用してそれらが tableView とやり取りできるようにします。そのため、UIPickerView から値が選択された後、tableView のデータ ソースが通知され、tableView への参照を保持するメインの ViewController に通知されます。そこから電話する

[_tableView reloadData];

UIPickerView が消えることを除いて、すべてが機能しているように見えます。セルが再生成され、どこかで rejectFirstResponder が呼び出されるか、そのようなことが原因だと思います。それを行うカスタムメソッドをどこかに実装する必要なく、tableView がその値を更新するようにする他の方法はありますか?

4

14 に答える 14

24

これは予想される動作のようです。ピッカーは特定のセルに属し、そのセルはリロードされ、ファーストレスポンダーではなくなります。とにかくピッカーを表示するには、特定の要素を選択する必要があったと思います。つまり、最初のレスポンダーにします

そのため、リロード後に再びファーストレスポンダーにするか、特定のセルを直接更新する必要があります。

于 2011-06-20T12:06:46.777 に答える
22

追加:

[yourSearchBar becomeFirstResponder];

あなたの後:

[_tableView reloadData];

トリックをした

于 2011-10-28T13:53:47.740 に答える
22

私は同じ問題に遭遇しました.上記の答えはどれも完全に機能しませんでした(キーボードが上下に跳ね返るなど)。このSO投稿
に 続いて、私は電話して問題を修正しました

[tableView beginUpdates];
[tableView endUpdates]; 

これは私にとってはうまくいきました。テーブルの行は更新され、拡張/縮小 (行の高さを動的に変更している場合) も素敵なアニメーションで行われます。
これは、展開された行に合わせてテーブルビューをスクロールしないため、上記のスニペットを専用のメソッド fe に配置します。

- (void)tableView:(UITableView *)tableView reloadRowWhileShowingKeyboard:(NSIndexPath *)indexPath 
{  
    [tableView beginUpdates];
    [tableView endUpdates]; 

    [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
于 2015-08-13T08:43:44.973 に答える
8

このアプローチに従うことができますが、最善ではありませんが、機能します。

// pass the responder to a temporary (hidden) textField
[_tmpTextField becomeFirstResponder];

// reload data
[_tableView reloadData];

// reloadData is definitely async... 
// so pass the responder back in a timed op
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [_textField becomeFirstResponder];
});
于 2013-05-09T13:02:35.897 に答える
8

UITextView をサブクラス化し、-(BOOL)resignFirstResponder をオーバーライドし、BOOL canResign を追加することで、これを解決しました。この変数は、データを再ロードする前に設定され、その後すぐに設定が解除されます。

于 2013-09-23T22:32:27.117 に答える
0

検索バーでこの問題に直面している場合、iOS6では次の問題が発生しました。

  • UISearchBarをインスタンス化し、それをサブビューとして上部のUITableViewに追加します。
  • UITableViewにダミーの最初のセルを作成して、検索バーがこのダミーセルのみをブロックし、実際のセルはデータでブロックしないようにします。
于 2012-11-17T16:13:09.117 に答える
0

@Eikoで述べたように、これは私にとってはうまくいきます!

UIPickerViewDelegate のpickerView:didSelectRow:inComponent:メソッドでセルを更新します。

- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
  TableViewCell *cell = (TableViewCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:pickerView.tag inSection:0]];

  /*
  Update your cell here. 
  */

  // Reload TableViewCell will resign the PickerView, so we need to focus it back.  
  [self.tableView reloadData];
  NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];
  NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
  [self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationNone];
  [cell.textField becomeFirstResponder];
}
于 2015-01-06T02:46:53.027 に答える
0

私はbeginUpdateendUpdateを使用します 更新終了後、テキストフィールドが既にフォーカスされているセルを取得し、最初のレスポンダーにします

    self.tableView.beginUpdates()
    self.tableView.reloadRows(at: [indexPath], with: .automatic)
    self.tableView.endUpdates()
    let newCell = self.tableView.cellForRow(at: indexPath)
    newCell.textField.becomeFirstResponder()
于 2018-10-09T19:37:36.100 に答える
-1

この問題は、ファーストレスポンダーのステータスを一時的に他のオブジェクトに転送することで解決できます。通常、入力ビューの制御を ViewController に転送します。UIViewController も UIResponder から継承するため、次のようなことができます。

didSelect { ....で

[yourViewController becomeFirstRespoder];

[_tableView reloadData];

[yourInputField becomeFirstResponder];

.... }

したがって、テーブルがリロードされると、firstResponder ステータスをラベル/フィールドに戻すことができます。デフォルトでは、canBecomeFirstResponder は NO に設定されています。そのため、ViewController で同じものをオーバーライドする必要がある場合があります。また、View Controller の inputView を UIPicker と同じにする必要がある場合もあります。そうしないと、ピッカーを閉じてキーボードを表示するだけになる場合があります。

于 2013-04-15T10:20:11.287 に答える