ios - uitableviewdatasource - 為TableView中的所有單元格設置標籤的正確方法




xcode uitableview (2)

您正在遇到細胞重複使用的問題。

當你為視圖創建一個按鈕時,你為它設置一個標籤,但是你重寫這個標籤來設置它的行號。

當單元格被重用時,由於行號更長ROW_BUTTON_ACTION,因此不會將標記重置為正確的行號,並且出錯。

使用標籤從視圖中獲取信息幾乎總是一個壞主意,而且非常脆弱,正如您在這裡所看到的。

正如馬特所說,走等級制是一個更好的主意。

而且,你的方法不需要這樣寫。 如果您創建自己的自定義單元格,則不需要用於創建和添加按鈕和標籤的代碼,您可以在xib,故事板或甚至是類中的代碼中執行該代碼。 此外,如果使用採用索引路徑的出隊方法,則將始終獲得循環單元格或新創建的單元格,因此不需要檢查返回的單元格是否為零。

我正在使用一個tableView中的按鈕,當我按下時,我得到的indexPath.row 。 但是,當單元格可以在屏幕上顯示而不scroll時,它才能正常工作。

一旦tableView可以滾動,我滾動tableview, indexPath.row返回是一個錯誤的值,我注意到,最初設置20個對象,例如Check只是打印9次沒有20。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
   if (cell == nil) {
       cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

       lBtnWithAction = [[UIButton alloc] initWithFrame:CGRectMake(liLight1Xcord + 23, 10, liLight1Width + 5, liLight1Height + 25)];
       lBtnWithAction.tag = ROW_BUTTON_ACTION;
       lBtnWithAction.titleLabel.font = luiFontCheckmark;
       lBtnWithAction.tintColor = [UIColor blackColor];
       lBtnWithAction.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
       [cell.contentView addSubview:lBtnWithAction];
   }
   else 
   { 
       lBtnWithAction = (UIButton *)[cell.contentView viewWithTag:ROW_BUTTON_ACTION];
   }

//Set the tag
lBtnWithAction.tag = indexPath.row;
//Add the click event to the button inside a row
[lBtnWithAction addTarget:self action:@selector(rowButtonClicked:) forControlEvents:UIControlEventTouchUpInside];

//This is printed just 9 times (the the number of cells that are initially displayed in the screen with no scroll), when scrolling the other ones are printed
NSLog(@"Check: %li", (long)indexPath.row);

return cell;
}

要點擊索引來做些事情:

-(void)rowButtonClicked:(UIButton*)sender
{
    NSLog(@"Pressed: %li", (long)sender.tag);
}

Constants.h

#define ROW_BUTTON_ACTION 9

什麼是正確的方式來獲得indexPath.row裡面rowButtonClicked或設置一個標籤,當我有很多的單元格在我的tableView


我對這類問題的解決方法是不要以這種方式使用標籤。 這是一個完全濫用標籤(在我看來),並可能導致麻煩(正如你所發現的),因為細胞被重複使用。

通常情況下,解決的問題是:單元中的一塊界面與用戶交互(例如點擊一個按鈕),現在我們想要知道該單元當前對應的什麼 ,以便我們可以對其進行響應到相應的數據模型。

我在我的應用程序中解決這個問題的方式是,當按鈕被輕敲或任何我收到一個控制事件或委託事件,從這個界面(按鈕或任何)走向視圖的層次結構,直到我來到單元格,然後調用表視圖的indexPath(for:) ,它將一個單元格並返回相應的索引路徑。 控件事件或委託事件始終將接口對像作為參數包含在內,因此很容易從該對像到單元格以及從那裡到該行。

因此,例如:

UIView* v = // sender, the interface object
do {
    v = v.superview;
} while (![v isKindOfClass: [UITableViewCell class]]);
UITableViewCell* cell = (UITableViewCell*)v;
NSIndexPath* ip = [self.tableView indexPathForCell:cell];
// and now we know the row (ip.row)

[ 注:一種可能的替代方法是使用一個自定義的單元格子類,其中有一個特殊的屬性,將行​​存儲在cellForRowAt 但是在我看來,這完全沒有必要,因為indexPath(for:)給了你完全相同的信息! 另一方面,對於頁眉/頁腳沒有indexPath(for:) ,所以在這種情況下,我使用一個自定義的子類來存儲段號,如本例所示 (參見viewForHeaderInSection的實現)。]