4

UITableViewスクロールが必要なほどの高さがあります。テーブルの一番上のセルにはUITextField、ユーザーがテキストを入力するための が含まれています。

これを構築する標準的な方法は、テキスト フィールドを作成して追加し、作成または再利用されたセルに追加することです。cellFOrRowAtIndexPath:ただし、この一定の再作成は、セルがスクロール アウトして戻ると、フィールドに入力されたテキストが消去されることを意味します。見えます。

私がこれまでに見つけた解決策では、UITextField委任を使用してテキストの変更を追跡し、iVar またはプロパティに保存することを提案しています。私が使用しているより単純なアプローチではなく、これが推奨される理由を知りたいです。

UITextFieldの init メソッドで を作成しUITableViewController、すぐにプロパティに格納しています。新しいフィールドを初期化するのではcellFOrROwAtIndexPathなく、既存のフィールドを追加するだけです。セル自体は問題なくリサイクルできますが、いつもオンリーワンを使っているのでUITextField中身は保たれています。

これは合理的なアプローチですか?何が問題になる可能性がありますか?改善点 (おそらく、フィールドを作成することはできますcellForRowAtIndexPathが、最初にプロパティが nil かどうかを確認できますか?)

4

3 に答える 3

1

でセルを作成するときはcellForRowAtIndexPath、最初のセル (つまり cellId1) に 1 つの再利用可能な識別子を使用し、残り (つまり cellId2) に別の識別子を使用する必要があります。

これを行うと、呼び出しによって最初の要素のセルを取得する[tableView dequeueReusableCellWithIdentifier:@"cellId1"]と、常に同じオブジェクトが取得され、他のセルによって再利用されることはありません。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    MyCell *cell = nil;

    // Only for first row
    if (indexPath.row == 0) {
        static NSString *cellId1 = @"cellId1";
        cell = [tableView dequeueReusableCellWithIdentifier:cellId1];

        if (cell == nil) {
            cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId1];
        }
    }
    else {
        static NSString *cellId2 = @"cellId2";
        cell = [tableView cellId2];

        if (cell == nil) {
            cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault cellId2];
        }
    }

    // do whatever

    return cell;
}
于 2013-08-30T15:31:46.303 に答える
0

UITextField が 1 つしかない場合は、UITextField 委任を使用する場合と比較して、あなたのアプローチの方が優れている/同じであることに同意します (私は思います)。

ただし、現在約 7 ~ 8 個以上の TextField が存在するように、ビューを「拡張」したいと仮定しましょう。次に、このアプローチを使用する場合、問題は、7 ~ 8 個以上の TextField をメモリに格納して維持することになります。

このような状況では、画面に表示される数のテキストフィールドのみを作成することをお勧めします。次に、テキストフィールドに存在するコンテンツを維持する辞書を作成します (UITextFieldDelegate メソッドで取得できます)。このようにして、セルを再利用するときに同じテキストフィールドを使用できます。値のみが変更され、ディクショナリ内の値によって決定されます。

補足として、cellForRowAtIndexPath で最小限の作成を行います。これは、すべてのテーブル スクロール中に呼び出されるため、cellForRowAtIndexPath で textField を作成するとコストがかかる可能性があります。

于 2013-08-30T15:11:49.737 に答える
0
#import "ViewController.h"
#import "TxtFieldCell.h"

#define NUMBER_OF_ROWS 26

@interface ViewController ()<UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tablView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tablView.datasource = self; //set textfield delegate in storyboard
    textFieldValuesArray = [[NSMutableArray alloc] init];
    for(int i=0; i<NUMBER_OF_ROWS; i++){
        [textFieldValuesArray addObject:@""];
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

#pragma mark - TableView Datasource

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TxtFieldCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TxtFieldCellId" forIndexPath:indexPath];
    cell.txtField.tag = indexPath.row;
    if (textFieldValuesArray.count > 0) {
        NSString *strText = [textFieldValuesArray objectAtIndex:indexPath.row];

        cell.txtField.text = strText;
    }
    return cell;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return NUMBER_OF_ROWS;
}

#pragma mark - TextField Delegate

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

   [textFieldValuesArray replaceObjectAtIndex:textField.tag withObject:textField.text];
}
于 2016-12-09T08:59:56.663 に答える