检测哪个按钮需要更改单元格中的文本

Posted

技术标签:

【中文标题】检测哪个按钮需要更改单元格中的文本【英文标题】:Detect on which button need to change text in cell 【发布时间】:2014-12-01 16:25:16 【问题描述】:

tableviewcell 中有喜欢的按钮

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


    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];


    if ( !cell ) 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];

        DBImageView *imageView = [[DBImageView alloc] initWithFrame:(CGRect) 0, 0, 320, 320 ];
        [imageView setPlaceHolder:[UIImage imageNamed:@"Placeholder"]];
        [imageView setTag:101];
        [cell.contentView addSubview:imageView];
    


    NSDictionary *tmpDict = [myObject objectAtIndex:indexPath.row];
    [(DBImageView *)[cell viewWithTag:101] setImageWithPath:[tmpDict objectForKey:@"thumb_link"]];


    likeButton = [UIButton buttonWithType:UIButtonTypeCustom] ;
    [likeButton setFrame:CGRectMake(cell.frame.size.width-60,280,81,33)];
    likeButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
    likeButton.contentEdgeInsets = UIEdgeInsetsMake(3, 2, 0, 0);
    [likeButton.titleLabel setFont:[UIFont fontWithName:@"Trebuchet MS" size:16]];
    [likeButton setBackgroundImage:[UIImage imageNamed:@"heart.png"] forState:UIControlStateNormal];
    [likeButton setBackgroundImage:[UIImage imageNamed:@"heart_pressed.png"] forState:UIControlStateSelected];
    [cell addSubview:likeButton];


    // like button
    likeButton.selected = ![likeButton isSelected];
    NSInteger defaultKey2 = [[NSUserDefaults standardUserDefaults] integerForKey:[tmpDict objectForKey:@"id"]];
    if (defaultKey2 == 0)
    
        //[likeButton setTitleColor:[UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0] forState:UIControlStateNormal];
        [likeButton setSelected:NO];
    
    else if (defaultKey2 == 1)
    
        //[likeButton setTitleColor:[UIColor colorWithRed:229/255.0 green:85/255.0 blue:140/255.0 alpha:1.0] forState:UIControlStateNormal];
        [likeButton setSelected:YES];
    


    [likeButton setTitle:[tmpDict objectForKey:@"likes"] forState:UIControlStateNormal];
    [likeButton addTarget:self action:@selector(like:) forControlEvents: UIControlEventTouchUpInside];
    [likeButton setTag:indexPath.row];

    return cell;


这是我的行动:

-(void)like:(id) sender
    UIButton *likebtn = (UIButton *)sender;
    NSDictionary *tmpDict = myObject[likebtn.tag];
    NSInteger defaultKey2 = [[NSUserDefaults standardUserDefaults] integerForKey:[tmpDict objectForKey:@"id"]];
    if (defaultKey2 == 0)
    
        //Increase value
        int varTemp = [[tmpDict objectForKey:@"likes"] intValue]+1;
        NSString *strValue = [NSString stringWithFormat:@"%d", varTemp];
        [likeButton setTitle:strValue forState:UIControlStateNormal];
        NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
        [prefs setInteger:1 forKey:[tmpDict objectForKey:@"id"]];
        [[NSUserDefaults standardUserDefaults]synchronize];
    
    if (defaultKey2 == 1)
    
        //Decrease value
        int varTemp = [[tmpDict objectForKey:@"likes"] intValue]-1;
        NSString *strValue = [NSString stringWithFormat:@"%d", varTemp];
        [likeButton setTitle:strValue forState:UIControlStateNormal];
        NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
        [prefs setInteger:0 forKey:[tmpDict objectForKey:@"id"]];
        [[NSUserDefaults standardUserDefaults]synchronize];    
    
    NSIndexPath *tmpIndexpath=[NSIndexPath indexPathForRow:likebtn.tag inSection:0];
    [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:tmpIndexpath, nil] withRowAnimation:UITableViewRowAnimationNone];

当我尝试为单元格中的按钮设置标题时 [likeButton setTitle:strValue forState:UIControlStateNormal]; 值进入错误的单元格。

如何检测需要设置单元格值中的哪个按钮?如何使用我的标签?

【问题讨论】:

你是什么意思“值去错误的单元格”?您能否从 cellForRowAtIndexPath 发布您的代码? 我需要增加或减少我的喜欢值,当我按下喜欢按钮时,值会在错误的单元格中改变。 好的,有几件事...在您的like: 方法中,条件句中的“likeButton”来自哪里?因为您在方法开始时声明了“likebtn”。第二,你不能那样设置按钮标题。它必须在 cellForRowAtIndexPath 中设置。一旦你解释了“likeButton”的声明位置,我会尽快发布建议。 我在 cellForRowAtIndexPath 中设置了我的点赞按钮,并在 NSDictionary 中的 cellForRowAtIndexPath 中设置了按钮标题。但我的问题是,该值来自服务器,当我按下按钮时,值会在几秒钟后发生变化,我想在它来自服务器之前更快地增加它。在我的 .h 文件中,我设置 UIButton* likeButton; 我认为你没有理解我的问题,但没关系......我会继续写下我的答案,然后从那里解释...... 【参考方案1】:

您不能在 like: 方法中以这种方式设置按钮标题,即:

[likeButton setTitle:strValue forState:UIControlStateNormal];

(1) 因为您稍后会重新加载表格,因此手动触发对 cellForRowAtIndexPath: 的调用和 (2) 即使您没有重新加载表格数据,即使滚动也会触发对 cellForRowAtIndexPath 的调用和因此您的单元格将根据cellForRowAtIndexPath: 的信息填充。

就目前而言,您的 cellForRowAtIndexPath: 方法使用以下行来设置标题:

[likeButton setTitle:[tmpDict objectForKey:@"likes"] forState:UIControlStateNormal];

这意味着为了让like: 操作触发标题更改,您必须更改like: 中的 [tmpDict objectForKey:@"likes"] 值。由于您使用的是临时字典并且从未将字典添加回 myObject 数组,因此您没有更改最终决定 cellForRowAtIndexPath: 中按钮标题的值。所以你必须相应地更新 myObject 。这是我的代码建议:

-(void)like:(id)sender 

    UIButton *likebtn = (UIButton *)sender;
    NSMutableDictionary *tmpDict = myObject[likebtn.tag];
    NSInteger defaultKey2 = [[NSUserDefaults standardUserDefaults] integerForKey:[tmpDict objectForKey:@"id"]];

    if (defaultKey2 == 0)
    
        //Increase value
        int varTemp = [[tmpDict objectForKey:@"likes"] intValue]+1;

        // Then update myObject
        [tmpDict setObject:[NSString stringWithFormat:@"%d", varTemp] forKey:@"likes"];
        [myObject replaceObjectAtIndex:likebtn.tag withObject:tmpDict];

        NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
        [prefs setInteger:1 forKey:[tmpDict objectForKey:@"id"]];
        [[NSUserDefaults standardUserDefaults]synchronize];
    
    if (defaultKey2 == 1)
    
        //Decrease value
        int varTemp = [[tmpDict objectForKey:@"likes"] intValue]-1;

        // Then update myObject
        [tmpDict setObject:[NSString stringWithFormat:@"%d", varTemp] forKey:@"likes"];
        [myObject replaceObjectAtIndex:likebtn.tag withObject:tmpDict];


        NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
        [prefs setInteger:0 forKey:[tmpDict objectForKey:@"id"]];
        [[NSUserDefaults standardUserDefaults]synchronize];    
    

    NSIndexPath *tmpIndexpath=[NSIndexPath indexPathForRow:likebtn.tag inSection:0];
    [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:tmpIndexpath, nil] withRowAnimation:UITableViewRowAnimationNone];


编辑:现在我看到了您的cellForRowAtIndexPath: 方法,还有一个大问题。您已将按钮声明为类变量? (1) 不要那样做。保持在本地,例如:

UIButton *likeButton = [UIButton buttonWithType:UIButtonTypeCustom] ;

(2) 您正在重复使用单元格,但每次都添加一个新按钮。因此,每次cellForRowAtIndexPath: 调用时,您都会在另一个之上添加一个按钮。这可能会给您带来麻烦。

【讨论】:

*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSCFNumber 长度]:无法识别的选择器发送到实例 0x15768450” @PavelKaljunen 嗯...我不完全确定为什么会这样。但是我已经更改了代码并将该行分成两个单独的步骤。现在可以用了吗? “NSDictionary”没有可见的@interface 声明选择器“setObject:forKey:” @PavelKaljunen 哦,tmpDict 字典需要是可变的。我也会改变它。如果 myObject 不可变,则必须在代码的其他位置使其可变... 好的,同样的 NSCFNumber 长度问题。 NSLog(@"%@", [tmpDict objectForKey:@"likes"]);显示数字 100 和 NSLog(@"%d", varTemp);只显示一个数字。我不知道为什么你的代码不起作用。【参考方案2】:

您的单元格可能会重复使用按钮,并且标签可能会被打乱。 尝试在 tableView:willDisplayCell:forRowAtIndexPath: 方法中刷新按钮的标签。

【讨论】:

目前我有reuseIdentifier:nil

以上是关于检测哪个按钮需要更改单元格中的文本的主要内容,如果未能解决你的问题,请参考以下文章

当触摸单元格中的自定义按钮时,我们如何知道表格中触摸了哪个单元格?

集合视图单元格中的动态按钮宽度

IOS/Objective-C:检测自定义表格视图单元格中的按钮按下?

通过用户输入和 Javascript 更改特定表格单元格中的文本

从已知按钮标签更改自定义单元格中的特定按钮标题

滚动 UITableView 时自定义单元格中的 UITextField 文本正在更改