检测哪个按钮需要更改单元格中的文本
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:检测自定义表格视图单元格中的按钮按下?