Want UITableView to “snap to cell”

前端 未结 7 1601
长发绾君心
长发绾君心 2020-12-23 17:40

I am displaying fairly large images in a UITableView. As the user scrolls, I\'d like to the table view to always snap the center-most photo in the middle. That

相关标签:
7条回答
  • 2020-12-23 18:04

    UITableView extends UIScrollView...

    myTableView.pagingEnabled = YES 
    
    0 讨论(0)
  • 2020-12-23 18:06

    for the swift peeps

    override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) 
    {
       if decelerate == false
       {
           self.centerTable()
       }
     }
    
    override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        self.centerTable()
    }
    
    func centerTable()
    {
       let midX:CGFloat = self.tableView.bounds.midX
       let midY:CGFloat = self.tableView.bounds.midY
       let midPoint:CGPoint = CGPoint(x: midX, y: midY)
    
       if let pathForCenterCell:IndexPath = self.tableView .indexPathForRow(at: midPoint)
        {
          self.tableView.scrollToRow(at: pathForCenterCell, at: .middle, animated: true)
        }
    }//eom
    
    0 讨论(0)
  • 2020-12-23 18:08

    There is a UIScrollView delegate method especially for this!

    Edit: if you just want the code, look at the answers below which build off this.

    The table view (which is a scroll view) will call - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset when the user stops scrolling. You can set manipulate the targetContentOffset to ensure it ends up where you want, and it will decelerate ending at that position (just like a paging UIScrollView).

    For example, if your cells were all 100 points high, you could do:

    - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
        targetContentOffset->y = 100 * (int)targetContentOffset->y/100;
    }
    

    Of course, you can also inspect the targetContentOffset passed in to see where it was going to land, and then find the cell that is in and alter it appropriately.

    0 讨论(0)
  • 2020-12-23 18:10

    Building from what @jszumski posted, if you want the snap to occur mid drag, use this code:

    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
        [self centerTable];
    }
    
    - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
        [self centerTable];
    }
    
    - (void)centerTable {
        NSIndexPath *pathForCenterCell = [self.tableView indexPathForRowAtPoint:CGPointMake(CGRectGetMidX(self.tableView.bounds), CGRectGetMidY(self.tableView.bounds))];
    
        [self.tableView scrollToRowAtIndexPath:pathForCenterCell atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
    }
    
    0 讨论(0)
  • 2020-12-23 18:19

    Extending @jesse-rusak's answer above, this is the code you would need to add to your UITableViewController subclass if you have cells with variable heights. This will avoid the double-scroll issue in the accepted answer.

    - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
        NSIndexPath *pathForTargetTopCell = [self.tableView indexPathForRowAtPoint:CGPointMake(CGRectGetMidX(self.tableView.bounds), targetContentOffset->y)];
        targetContentOffset->y = [self.tableView rectForRowAtIndexPath:pathForTargetTopCell].origin.y;
    }
    
    0 讨论(0)
  • 2020-12-23 18:21

    You can use the UIScrollViewDelegate methods on UITableView to do this:

    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
        // if decelerating, let scrollViewDidEndDecelerating: handle it
        if (decelerate == NO) {
            [self centerTable];
        }
    }
    
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
        [self centerTable];
    }
    
    - (void)centerTable {
        NSIndexPath *pathForCenterCell = [self.tableView indexPathForRowAtPoint:CGPointMake(CGRectGetMidX(self.tableView.bounds), CGRectGetMidY(self.tableView.bounds))];
    
        [self.tableView scrollToRowAtIndexPath:pathForCenterCell atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
    }
    
    0 讨论(0)
提交回复
热议问题