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 滚动时按钮状态更改

滚动时 UITableViewCell 的选定按钮消失

UITableViewCell 图像在滚动时消失

出队的 UITableViewCell 在滚动之前布局不正确(使用自动布局)

UIImageView 在滚动之前不会加载到 UITableViewCell 中