How to keep UITableView contentoffset after calling -reloadData

前端 未结 13 1375
隐瞒了意图╮
隐瞒了意图╮ 2020-11-28 02:43
CGPoint offset = [_table contentOffset];
[_table reloadData];
[_table setContentOffset:offset animated:NO];    //unuseful

//    __block UITableView *tableBlock = _t         


        
13条回答
  •  时光说笑
    2020-11-28 03:13

    Swift 4 variant of @Skywalker answer:

    fileprivate var heightDictionary: [IndexPath: CGFloat] = [:]
    
    override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        heightDictionary[indexPath] = cell.frame.size.height
    }
    
    override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        let height = heightDictionary[indexPath]
        return height ?? UITableViewAutomaticDimension
    }
    

    Another solution (fetched from MessageKit):

    This method should be called instead of reloadData. This can fit for specific cases.

    public func reloadDataAndKeepOffset() {
        // stop scrolling
        setContentOffset(contentOffset, animated: false)
            
        // calculate the offset and reloadData
        let beforeContentSize = contentSize
        reloadData()
        layoutIfNeeded()
        let afterContentSize = contentSize
            
        // reset the contentOffset after data is updated
        let newOffset = CGPoint(
            x: contentOffset.x + (afterContentSize.width - beforeContentSize.width),
            y: contentOffset.y + (afterContentSize.height - beforeContentSize.height))
        setContentOffset(newOffset, animated: false)
    }
    

提交回复
热议问题