UITableViewCell 按钮在滚动之前不显示选中或取消选中状态
Posted
技术标签:
【中文标题】UITableViewCell 按钮在滚动之前不显示选中或取消选中状态【英文标题】:UITableViewCell button doesn't show selected or deselected state until scroll 【发布时间】:2016-06-24 11:01:14 【问题描述】:我正在使用其 uitableviewcell 中的“like”按钮处理应用程序,但是除非滚动 uitableview 并且单元格离开屏幕并重新出现,否则单元格的状态不会显示。这是我尝试显示按钮的方式:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *MyIdentifier = @"ProfileCell";
PFObject *data = self.posts[indexPath.row];
NSLog(@"Data: %@", data);
ProfileTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
cell = [[ProfileTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
for(UIView *view in cell.contentView.subviews)
if ([view isKindOfClass:[UIView class]])
[view removeFromSuperview];
#pragma mark - Heart Button
heartButton = [[UIButton alloc] init];
[heartButton setImage:[UIImage imageNamed:@"heartButton"]
forState:UIControlStateNormal];
[heartButton setImage:[UIImage imageNamed:@"heartButtonSelected"]
forState:UIControlStateSelected];
dispatch_async(dispatch_get_main_queue(), ^
PFQuery *query = [PFQuery queryWithClassName:@"OrganizationLike"];
[query whereKey:@"Post" equalTo:data];
[query whereKey:@"liker" equalTo:[PFUser currentUser]];
[query getFirstObjectInBackgroundWithBlock:^(PFObject * _Nullable object, NSError * _Nullable error)
if (!object)
[heartButton setSelected:NO];
else
[heartButton setSelected:YES];
];
);
[heartButton addTarget:self action:@selector(heartButton:) forControlEvents:UIControlEventTouchDown];
[heartButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[cell.contentView addSubview:heartButton];
[heartButton autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:80];
[heartButton autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:7.0];
[heartButton autoSetDimension:ALDimensionHeight toSize:15];
[heartButton autoSetDimension:ALDimensionWidth toSize:16];
PFQuery *lquery = [PFQuery queryWithClassName:@"OrganizationLike"];
[lquery whereKey:@"Post" equalTo:data];
[lquery findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error)
if (objects.count>0)
UILabel *likeLabel = [[UILabel alloc] init];
[likeLabel setNeedsDisplay];
[likeLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
likeLabel.backgroundColor = [UIColor clearColor];
likeLabel.textColor = [UIColor colorWithRed:0.643 green:0.655 blue:0.667 alpha:1];
likeLabel.font = [UIFont fontWithName:@"OpenSans-Light" size:8.881];
likeLabel.textAlignment = NSTextAlignmentCenter;
likeLabel.text = [NSString stringWithFormat:@"%d", objects.count];
[likeLabel setNeedsDisplay];
[cell.contentView addSubview:likeLabel];
[likeLabel autoAlignAxis:ALAxisHorizontal toSameAxisOfView:heartButton withOffset:0];
[likeLabel autoPinEdge:ALEdgeLeft toEdge:ALEdgeRight ofView:heartButton withOffset:3];
];
return cell;
以下是按钮点击的处理方式:
- (void)heartButton:(UIButton *)sender
sender.selected = !sender.selected;
if (sender.selected)
NSIndexPath *i=[self indexPathForCellContainingView:sender.superview];
PFObject *data = self.posts[i.row];
PFQuery *query = [PFQuery queryWithClassName:@"OrganizationLike"];
[query whereKey:@"Post" equalTo:data];
[query whereKey:@"liker" equalTo:[PFUser currentUser]];
[query getFirstObjectInBackgroundWithBlock:^(PFObject * _Nullable object, NSError * _Nullable error)
if (!object)
PFObject *like = [PFObject objectWithClassName:@"OrganizationLike"];
like[@"liker"] = [PFUser currentUser];
like[@"Post"] = data;
[like saveInBackground];
[self.tableView reloadData];
];
else
NSIndexPath *i=[self indexPathForCellContainingView:sender.superview];
PFObject *data = self.posts[i.row];
PFQuery *query = [PFQuery queryWithClassName:@"OrganizationLike"];
[query whereKey:@"Post" equalTo:data];
[query whereKey:@"liker" equalTo:[PFUser currentUser]];
[query getFirstObjectInBackgroundWithBlock:^(PFObject * _Nullable object, NSError * _Nullable error)
[object deleteInBackground];
[self.tableView reloadData];
];
【问题讨论】:
您在 tableview 中的选择是什么? 为什么要在 cellForRowAtIndexPath 中编写这么多代码,您使用的是 storyboard/xib 吗?你的 heartButton setSelected 应该在主线程上调用。 【参考方案1】:选择或更新布局显示后重新加载表格视图
【讨论】:
【参考方案2】:首先尝试在主线程中调用 [self.tableView reloadData]。
第二次检查 [self.tableView reloadData] 是否被调用。您可以通过添加断点进行检查。
除了重新加载整个 tableView 单元格之外,您可以通过调用在特定 indexpath 处重新加载 tableView
[self.tableView reloadRowsAtIndexPaths:indexPath withRowAnimation:nil];
【讨论】:
【参考方案3】:检查一下这可能有效,
在- (void)heartButton:(UIButton *)sender
首先获取更新的对象并将其替换到您的主数组对象中
[self.posts replaceObjectAtIndex:index withObject:newObj];
比使用
[self.tableView reloadRowsAtIndexPaths:indexPath withRowAnimation:nil];
更多的建议是不需要先从单元格视图中删除所有对象,而不是在cellForRowAtIndexPath:
方法中创建新对象,而只需检查视图对象是否已经存在,而不仅仅是更新其值/属性
【讨论】:
以上是关于UITableViewCell 按钮在滚动之前不显示选中或取消选中状态的主要内容,如果未能解决你的问题,请参考以下文章
滚动时如何向 UITableViewCell 添加更多按钮?
Swift UITableViewCell 滚动时按钮状态更改