2013-04-18 29 views
17

我在UITableView中显示了相当大的图像。随着用户滚动,我希望桌面视图始终将最中间的照片放在中间。也就是说,当桌子处于休息状态时,它将始终有一个对齐到中心的UITableViewCell想要UITableView“捕捉到单元格”

这是怎么回事?

+0

可以通过更改表的ContentOffset做到这一点。 –

+0

你可以使用UITableview的scrollview委托方法和contentoffset功能,因为Nishant建议:) – Mangesh

回答

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]; 
} 
+0

谢谢!我一直在寻找的是如何检测哪个单元格是最重要的(您的centerTable方法)。 – VaporwareWolf

+0

这会起作用,但是在桌子视图停止之后它会引起一个奇怪的小滚动。 –

+0

同意Jesse Rusak。在滚动期间寻找快照。 – quantumpotato

14

有一个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,然后找到正在进入的单元格并进行相应更改。

+0

谢谢。这也很有用。 – VaporwareWolf

+0

您的代码会在iOS 8的Xcode 6.3中引发警告。我不得不使用下面的代码,但它没有做任何事情。 targetContentOffset-> x = 100 *(int)targetContentOffset/100;任何想法为什么? – user3344977

+0

嘿,杰西我注意到了你对上述答案的评论“这样会起作用,但是在桌子视图停止之后它会引起一个奇怪的小滚动。” - 如果我能得到你的答案,它会产生更多的分页/捕捉滚动效果?真的很感谢帮助。 – user3344977

-3

的UITableView延伸的UIScrollView ...

myTableView.pagingEnabled = YES 
5

从什么@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]; 
} 
+1

我不确定这个答案意味着什么“中间拖动”,但是已经实现了它,我已经验证了它在等待拖动动能稳定下来之前等待。这是有道理的,因为直到那时才调用didEndDragging和willBeginDecelerating。如果您使用此方法取消正在进行的滚动,则距离更近:http://stackoverflow.com/a/3421387/111243,然后在您停止拖动时立即捕捉,但仍然没有中间拖动捕捉。 – SimplGy

5

扩展@杰西 - 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; 
} 
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