Jerky Scrolling After Updating UITableViewCell in place with UITableViewAutomaticDimension

前端 未结 6 570
我在风中等你
我在风中等你 2020-12-04 05:49

I am building an app that has a feed view for user-submitted posts. This view has a UITableView with a custom UITableViewCell implementation. Insid

6条回答
  •  囚心锁ツ
    2020-12-04 06:04

    Here is the best solution I found to solve this kind of problem (scrolling problem + reloadRows + iOS 8 UITableViewAutomaticDimension);

    It consists by keeping every heights in a dictionary and updating them (in the dictionary) as the tableView will display the cell.

    You will then return the saved height in - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath method.

    You should implement something like this :

    Objective-C

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.heightAtIndexPath = [NSMutableDictionary new];
        self.tableView.rowHeight = UITableViewAutomaticDimension;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
        NSNumber *height = [self.heightAtIndexPath objectForKey:indexPath];
        if(height) {
            return height.floatValue;
        } else {
            return UITableViewAutomaticDimension;
        }
    }
    
    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
        NSNumber *height = @(cell.frame.size.height);
        [self.heightAtIndexPath setObject:height forKey:indexPath];
    }
    

    Swift 3

    @IBOutlet var tableView : UITableView?
    var heightAtIndexPath = NSMutableDictionary()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        tableView?.rowHeight = UITableViewAutomaticDimension
    }
    
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        if let height = heightAtIndexPath.object(forKey: indexPath) as? NSNumber {
            return CGFloat(height.floatValue)
        } else {
            return UITableViewAutomaticDimension
        }
    }
    
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let height = NSNumber(value: Float(cell.frame.size.height))
        heightAtIndexPath.setObject(height, forKey: indexPath as NSCopying)
    }
    

提交回复
热议问题