簡體   English   中英

IOS:維護uitableviewcell中的按鈕狀態

[英]IOS: Maintaining button state in uitableviewcell

我有一個iPhone應用程序問題一直困擾我幾天,它似乎不應該是這么困難,所以我敢肯定我錯過了一些明顯的東西。 我已經研究過很多關於“類似”主題的論壇討論,但實際上並沒有解決這個問題。

需要說明的是,如果有一些文檔或其他來源我應該研究,請指出正確的方向。

開始...

我有一個項目列表,我在表格中顯示給用戶(uitableview)。 每個項目的單元格(uitableviewcell)是自定義的,包含圖像和Like按鈕(uibutton)。 正如所料,對於表中的每個項目,用戶可以單擊“贊”按鈕或忽略它。 like按鈕調用單獨的進程來更新服務器。 簡單吧?

所以,這是問題:

當在特定單元格上單擊“贊”按鈕時,“選定”狀態正常工作,但是當您將單元格滾出視圖時,表格中的其他隨機單元格將“相似”按鈕顯示為“已選擇”,即使它們從未被觸摸過。 因為細胞被重復使用,出於明顯的性能原因,我理解為什么會發生這種情況。 我不明白的是為什么我的方法(見下面的代碼)不會像我認為的那樣覆蓋或重置按鈕的狀態。 為簡潔起見,我只在此處包含相關代碼(希望格式正確):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"MyCustomCell";
    MyCustomViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    cell = [[MyCustomViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
}

    NSString *myRating = [[self.dataArray objectAtIndex:indexPath.row] valueForKey:@"my_rating"];

    // Create the Like button
    UIButton *likeButton = [[UIButton alloc] initWithFrame:CGRectMake(260, 68, 40, 40)];
    [likeButton setImage:[UIImage imageNamed:@"thumbsUp"] forState:UIControlStateNormal];
    [likeButton setImage:[UIImage imageNamed:@"thumbsUpSelected"] forState:UIControlStateSelected];
    if (myRating == @"9") {
        [likeButton setSelected:YES];
    }
    [likeButton setTitle:@"9" forState:UIControlStateNormal];
    [likeButton setTag:indexPath.row];
    [cell.contentView addSubview:likeButton];
    [likeButton addTarget:self action:@selector(likeButtonPressed:) forControlEvents:UIControlEventTouchUpInside];

    return cell;
}

- (void)likeButtonPressed:(UIButton *)sender {

    // Changed the Selected state on the button
    UIButton *button = (UIButton *)sender;
    button.selected = !button.selected;

    // Create a new object with the user's rating and then replace it in the dataArray
    NSString *ratingText = sender.titleLabel.text;    
    NSMutableArray *myMutableArray = [[self.dataArray objectAtIndex:row] mutableCopy];
    [myMutableArray setValue:ratingText forKey:@"my_rating"];
    [self.dataArray replaceObjectAtIndex:row withObject:myMutableArray];
}

所以,我已經經歷了很多迭代,但我似乎無法獲得按鈕的狀態來顯示所選項目的所選項目,並保留那些尚未被喜歡的項目的正常圖像。

任何幫助或建議將不勝感激。

有一個簡單的方法。 你可以欺騙按鈕以保持最新的選擇狀態。

創建一個可變數組,以保持按鈕的選定狀態

selectedButton = [[NSMutableArray alloc]init];//i've already defined the array at the .h file

for (int i = 0; i<yourTableSize; i++) //yourTableSize = how many rows u got
{
    [selectedButton addObject:@"NO"];
}

在tableviewcell方法中,聲明你的按鈕並設置它以便它引用mutablearray來設置它的選擇狀態

static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) 
{ 
    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
}

UIImage *img = [UIImage imageNamed:@"btn_unselected.png"];
UIButton *toggleButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, img.size.width, img.size.height)];
[toggleButton setImage:img forState:UIControlStateNormal];
img = [UIImage imageNamed:@"btn_selected.png"];
[toggleButton setImage:img forState:UIControlStateSelected];
[toggleButton setTag:indexPath.row+100];//set the tag whichever way you wanted it, i set it this way so that the button will have tags that is corresponding with the table's indexpath.row
[toggleButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:toggleButton];

//and now we set the button's selected state, everytime the table reuse/redraw the cell the button will set it's selected state according to the array

if([[selectedButton objectAtIndex:indexPath.row]isEqualToString:@"NO"])
{
    [toggleButton setSelected:NO];
}
else 
{
    [toggleButton setSelected:YES];
}

return cell;

最后,創建按下按鈕時按鈕觸發的方法,以更改其選定狀態

-(void)buttonPressed:(UIButton*)sender
{
    int x = sender.tag - 100; //get the table's row
    if([sender isSelected]) //if the button is selected, deselect it, and then replace the "YES" in the array with "NO"
    {
        [selectedButton replaceObjectAtIndex:x withObject:@"NO"];
        [sender setSelected:NO];
    }
    else if (![sender isSelected]) //if the button is unselected, select it, and then replace the "NO" in the array with "YES"
    {
        [selectedButton replaceObjectAtIndex:x withObject:@"YES"];
        [sender setSelected:YES];
    }
}

問題是,每次你創建或重復使用一個單元格時,你都會給它一個新的類似按鈕,所以當你重復使用類似按鈕被激活的單元格時,你會給它一個停用的按鈕,但舊的,激活的像按鈕仍然存在。

您不必在每次需要單元格時創建類似按鈕,而只需設置現有類似按鈕的狀態。 有關處理此問題的一些可能方法,請參閱此問題的答案。

這是無效的(至少如果你試圖比較字符串我的內容而不是地址):

if (myRating == @"9")

嘗試這個:

if ([myRating isEqualToString:@"9"])

和+1到yuji注意到多個按鈕的創建。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM