IOS how to update UITableViewCell

前端 未结 2 2036
南方客
南方客 2021-01-15 11:29

i make a custom UITableViewCell:

 SListViewCell * cell = nil;
//    cell = [listView dequeueReusableCellWithIdentifier:CELL];
if (!cell) {
    cell = [[[SLis         


        
相关标签:
2条回答
  • 2021-01-15 12:01

    Any UI updates can only occur on the main thread. I don't think you should update UITableViewCell in another thread.

    From Apple doc:

    Manipulations to your application’s user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself but all other manipulations should occur on the main thread.

    0 讨论(0)
  • 2021-01-15 12:16

    You can do most of your processing in the background but anything that updates the UI has to happen on the main thread.

    Doing background processing and then updating the UI can be done easily using Grand Central Dispatch (GCD).

    - (void)typeTapped:(id)sender
    {
        UIButton* btn = (UIButton*)sender;
        // Use Grand Central Dispatch to do the processing in the background.
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
            // Do download operation here... Something like:
            NSData* imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://some_url.com/some.image"]];
            UIImage* image = [UIImage imageWithData:imageData];
    
            //Go back to the main thread to update the UI. this is very important!
            dispatch_async(dispatch_get_main_queue(), ^{
                [btn setImage:image forState:UIControlStateNormal];
            });
        });
    }
    

    However. In a table view there's a couple of gotchas.

    Table cells are re-used. This mean that your nice UIButton in your UITableViewCell may not be the one you think it is once the download has completed. It's the same object, but has been reconfigured to display the content from another row.

    For these case your best bet is to use GCD to update the NSArray or other data structure is feeding from and then ask the table view to do the refresh for the cell.

    // In the UITableViewDelegate.

    @implementation SomeViewController
    {
      NSMutableArray* _tableData;
    }
    
    // ...
    
    // Someone tapped on the cell.
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
            // Do download operation here... Something like:
            NSData* imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://some_url.com/some.image"]];
            UIImage* image = [UIImage imageWithData:imageData];
            if([_tableData count] < indexPath.row) {
                _tableData[indexPath.row] = image;
            }
            //Go back to the main thread to update the UI. this is very important!
            dispatch_async(dispatch_get_main_queue(), ^{
                [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            });
        });
    
    }
    
    0 讨论(0)
提交回复
热议问题