简体   繁体   中英

Reload constraint or update height in self-sizing tableview cell after image is downloaded

I show 1 image in my cell and height need to be changed according to aspect ratio. But if I don't reload table, constraint is not changed and thus cell height too. If I use 'reloadData' or reload particular row, it is okay but scrolling performance is affected. One of the ways is to download all images first but might not be good I guess. How shall I do?

Media *media = self.post.medias[0];
NSString *imgUrlStr = media.thumbnailUrl;
[self.ivMain allowTapWithMedia:self.post.medias[0]];

UIImage* displayImage = [myCache imageFromDiskCacheForKey:imgUrlStr];

if (displayImage) {
    @try {

        [self.ivMain setImage:displayImage];
        CGFloat ivHeight = (displayImage.size.height/displayImage.size.width) * CGRectGetWidth(self.ivMain.frame);

        if (roundf(ivHeight) != roundf(self.verticalConstraintIvMain.constant))
            [self.verticalConstraintIvMain setConstant:ivHeight];

    } @catch (NSException *exception) {

    }
}
else {
    [self.ivMain setImageWithURL:[NSURL URLWithString:imgUrlStr] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

        //image width > iv width
        //image height .. ?

        dispatch_async(dispatch_get_main_queue(), ^{
            CGFloat ivHeight = (image.size.height/image.size.width) * CGRectGetWidth(self.ivMain.frame);
            if (roundf(self.verticalConstraintIvMain.constant) != roundf(ivHeight)) {

                // [self.verticalConstraintIvMain setConstant:ivHeight];

                id view = [self superview];

                while (view && [view isKindOfClass:[UITableView class]] == NO) {
                    view = [view superview];
                }

                UITableView *tableView = (UITableView *)view;
                [tableView reloadData];
                // [tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:self.tag inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
            }
        });
    } usingActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];


}

The known solution is to not reload rows while the user is scrolling. It's impossible to have major layout operations and smooth scrolling simultaneously.

So when the async image-download call comes back, detect if the user is scrolling by looking at the table view properties (inherited from UIScrollView ) isDragging and isDecelerating . If the user is scrolling, instead put the 'index path to reload' into some storage. A mutable array property on whatever is the table view data source/delegate would be best, for reasons below. When the user stops scrolling, reload the paths and clear the storage.

You can do the last step by implementing the UIScrollViewDelegate method -scrollViewDidEndDecelerating: . The table view's delegate is also the scroll view's delegate. It can have a nice effect in practice to see multiple images appear when scrolling stops.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM