2013-08-30 30 views
4

我有一個UITableView高得足以使它需要滾動。表中最頂端的單元格包含一個UITextField供用戶輸入一些文本。UITableViewCell內的UITextField - 防止文本重置的方法

建立此的標準方法可能是創建並添加文本字段並將其添加到在cellFOrRowAtIndexPath:中創建或回收的單元格中。但是,此不斷重新創建意味着在單元格中輸入的文本被刪除滾出並返回到視圖中。

到目前爲止我發現的解決方案建議使用UITextField代表團跟蹤文本,因爲它會更改並將其存儲在iVar或屬性中。我想知道爲什麼這是建議,而不是我正在使用的更簡單的方法:

我在UITableViewController的init方法中創建UITextField,並立即將其存儲在屬性中。在cellFOrROwAtIndexPath我只是添加預先存在的字段,而不是初始化一個新的字段。單元本身可以被回收而沒有問題,但因爲我總是使用唯一的UITextField,所以內容被保留。

這是一個合理的方法嗎?什麼可能會出錯?任何改進(也許我仍然可以在cellForRowAtIndexPath中創建該字段,但首先檢查該屬性是否爲零)

回答

1

當您在cellForRowAtIndexPath中創建單元格時,必須爲該第一個單元格(即cellId1)使用一個可重用的標識符,其餘部分(即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; 
} 
+0

謝謝,但這並沒有解決嵌入細胞的文本字段。 –

+0

您可以將第一個單元格存儲爲創建時的類屬性之一,並隨時訪問其內容。重點是一旦創建它將不會被重用,並且其內容不會被刪除。 – clubifaximatic

+0

你很對 - 這比使用init更好。另外,我可以將textview本身存儲爲屬性而不是單元格。如果有的話,這會重新強調我的問題 - 因爲如果我有很多文本標籤,我仍然認爲你的方法比使用委託更好。希望有人會解釋爲什麼不。 –

0

如果只有一個UITextField,那麼我同意您的方法與使用UITextField委派相比會更好/相同(我認爲)。

但是,讓我們假設您想「展開」您的視圖,以便現在有大約7-8個或更多的TextField。然後,如果你開始使用你的方法,那麼問題是你將在內存中存儲7-8個或更多的TextField並且維護它們。

在這種情況下,更好的方法是隻創建屏幕上可見的文本字段數量。然後你創建一個字典,它可以保持文本字段中的內容(你可以通過UITextFieldDelegate方法獲得)。這樣,當單元格被重用時,可以使用相同的文本字段。只有值會改變,並將由字典中的值決定。

在旁註中,在每個表滾動過程中調用cellForRowAtIndexPath時進行最小創建,因此在cellForRowAtIndexPath中創建textField可能很昂貴。

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]; 
}