21

我在UITableView. 当用户滚动时,我希望表格视图始终在中间捕捉最中心的照片。也就是说,当桌子处于静止状态时,它总会有一个UITableViewCell对齐到中心的位置。

如何做到这一点?

4

7 回答 7

29

您可以使用以下UIScrollViewDelegate方法UITableView来执行此操作:

- (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];
}
于 2013-04-18T16:51:40.663 回答
18

有一个 UIScrollView 委托方法专门为此!

编辑:如果您只想要代码,请查看以下基于此构建的答案。

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset当用户停止滚动时,将调用表格视图(滚动视图) 。您可以设置操作targetContentOffset以确保它最终到达您想要的位置,并且它将减速到该位置结束(就像分页 UIScrollView 一样)。

例如,如果你的单元格都是 100 点高,你可以这样做:

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

当然,您也可以检查targetContentOffset传入的内容以查看它要降落的位置,然后找到其中的单元格并进行适当的更改。

于 2013-04-18T16:59:11.763 回答
6

扩展上面@jesse-rusak 的答案,如果您有高度可变的单元格,这是您需要添加到 UITableViewController 子类的代码。这将避免接受答案中的双滚动问题。

- (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;
}
于 2014-03-26T21:24:20.847 回答
6

根据@jszumski 发布的内容构建,如果您希望在拖动中发生快照,请使用以下代码:

- (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];
}
于 2013-10-21T23:21:37.257 回答
4

扩展@mikepj 答案(这反过来又扩展了@JesseRusak 的出色答案),此代码可让您捕捉到一个单元格,即使单元格具有可变(或未知)高度,并且如果您愿意,它将捕捉到下一行滚动到行的下半部分,使其更“自然”。

原始 Swift 4.2 代码:(为方便起见,这是我开发和测试的实际代码)

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
}

(翻译)Objective-C 代码:(因为这个问题被标记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;
}
于 2018-11-12T15:07:27.330 回答
0

对于快速窥视

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
于 2017-02-25T10:56:31.850 回答
-3

UITableView 扩展了 UIScrollView...

myTableView.pagingEnabled = YES 
于 2013-08-12T21:51:49.523 回答