Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add snap-to position in a UITableView or UIScrollView

Is it possible to add a snap-to position in a UITableView or UIScrollView? What I mean is not auto scroll to a position if I press a button or call some method to do it, I mean is if I scroll my scroll view or tableview around a specific point, say 0, 30, it will auto-snap to it and stay there? So if my scroll view or table view scrolls and then the user lets go inbetween 0, 25 or 0, 35, it will auto "snap" and scroll there? I can imagine maybe putting in an if-statement to test if the position falls in that area in either the scrollViewDidEndDragging:WillDecelerate: or scrollViewWillBeginDecelerating: methods of UIScrollView but I'm unsure how to implement this in the case of a UITableView. Any guidance would be much appreciated.

like image 598
Milo Avatar asked Jan 06 '14 00:01

Milo


1 Answers

This code lets you snap to a cell, even when cells have a variable (or unknown) height, and will snap to the next row if you'll scroll over the bottom half of the row, making it more "natural".

Original Swift 4.2 code: (for convenience, this is the actual code I developed and tested)

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    guard var scrollingToIP = table.indexPathForRow(at: CGPoint(x: 0, y: targetContentOffset.pointee.y)) else {
        return
    }
    var scrollingToRect = table.rectForRow(at: scrollingToIP)
    let roundingRow = Int(((targetContentOffset.pointee.y - scrollingToRect.origin.y) / scrollingToRect.size.height).rounded())
    scrollingToIP.row += roundingRow
    scrollingToRect = table.rectForRow(at: scrollingToIP)
    targetContentOffset.pointee.y = scrollingToRect.origin.y
}

(translated) Objective-C code: (since this question is tagged objective-c)

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    NSIndexPath *scrollingToIP = [self.tableView indexPathForRowAtPoint:CGPointMake(0, targetContentOffset->y)];
    if (scrollingToIP == nil)
        return;
    CGRect scrollingToRect = [table rectForRowAtIndexPath:scrollingToIP];
    NSInteger roundingRow = (NSInteger)(round(targetContentOffset->y - scrollingToRect.origin.y) / scrollingToRect.size.height));
    scrollingToIP.row += roundingRow;
    scrollingToRect = [table rectForRowAtIndexPath:scrollingToIP];
    targetContentOffset->y = scrollingToRect.origin.y;
}
like image 103
gog Avatar answered Sep 24 '22 19:09

gog