Keep uitableview static when inserting rows at the top

后端 未结 18 1946
名媛妹妹
名媛妹妹 2020-11-29 16:12

I have a tableView that I\'m inserting rows into at the top.

Whilst I\'m doing this I want the current view to stay completely still, so the rows only appear if you

相关标签:
18条回答
  • 2020-11-29 16:35

    Late to the party but this works even when cell have dynamic heights (a.k.a. UITableViewAutomaticDimension), no need to iterate over cells to calculate their size, but works only when items are added at the very beginning of the tableView and there is no header, with a little bit of math it's probably possible to adapt this to every situation:

    func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
            if indexPath.row == 0 {
                self.getMoreMessages()
            }
    }
    
    private func getMoreMessages(){
            var initialOffset = self.tableView.contentOffset.y
            self.tableView.reloadData()
            //@numberOfCellsAdded: number of items added at top of the table 
            self.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: numberOfCellsAdded, inSection: 0), atScrollPosition: .Top, animated: false)
            self.tableView.contentOffset.y += initialOffset
    }
    
    0 讨论(0)
  • 2020-11-29 16:36

    AmitP answers, Swift 3 version

    let beforeContentSize = self.tableView.contentSize
    self.tableView.reloadData()
    let afterContentSize = self.tableView.contentSize
    let afterContentOffset = self.tableView.contentOffset
    let newContentOffset = CGPoint(x: afterContentOffset.x, y: afterContentOffset.y + afterContentSize.height - beforeContentSize.height)
                        self.tableView.contentOffset = newContentOffset
    
    0 讨论(0)
  • 2020-11-29 16:37

    How are you adding the rows to the table?

    If you're changing the data source and then calling reloadData, that may result in the table being scrolled to the top again.

    However, if you use the beginUpdates, insertRowsAtIndexPaths:withRowAnimation:, endUpdates methods, you should be able to insert rows without having to call reloadData thus keeping the table in its original position.

    Don't forget to modify your data source before calling endUpdates or else you'll end up with an internal inconsistency exception.

    0 讨论(0)
  • 2020-11-29 16:40

    I solved this in the end by rendering the current tableview into a UIImage and then putting a temporary UIImageView over the tableview whilst it animates.

    The following code will generate the image

    
    // Save the current tableView as an UIImage
    CSize pageSize = [[self tableView] frame].size;
    UIGraphicsBeginImageContextWithOptions(pageSize, YES, 0.0); // 0.0 means scale appropriate for device ( retina or no )
    CGContextRef resizedContext = UIGraphicsGetCurrentContext();
    CGPoint offset = [[self tableView] contentOffset];
    CGContextTranslateCTM(resizedContext,-(offset.x),-(offset.y));
    
    [[[self tableView  ]layer] renderInContext:resizedContext];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();    
    

    You need to keep track of how much the tableview will have grown by whilst inserting rows and make sure you scroll the tableview back to the exact same position.

    0 讨论(0)
  • 2020-11-29 16:40

    How about using scrollToRowAtIndexPath:atScrollPosition:animated:? You should be able to just add an element to your data source, set the row with the above mentioned method and reload the table...

    0 讨论(0)
  • 2020-11-29 16:41

    Just a heads up it does not seem possible to do this if you return estimated heights for the tableview.

       - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath ;
    

    If you implement this method and return a rough height your tableview will jump about when reloading as it appears to use these heights when setting the offsets.

    To get it working use one of the above answers (I went with @Mayank Yadav answer), don't implement the estimatedHeight method and cache the cell heights (remembering to adjust the cache when you insert additional cells at the top).

    0 讨论(0)
提交回复
热议问题