Ios 要将UITableView设置为;“捕捉到单元格”;
我正在Ios 要将UITableView设置为;“捕捉到单元格”;,ios,objective-c,uitableview,uiscrollviewdelegate,Ios,Objective C,Uitableview,Uiscrollviewdelegate,我正在UITableView中显示相当大的图像。当用户滚动时,我想在表视图中始终捕捉中间的大多数照片。也就是说,当表格处于静止状态时,它将始终有一个UITableViewCell捕捉到中间 如何执行此操作?您可以使用UITableView上的UIScrollViewDelegate方法执行此操作: - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { //
UITableView
中显示相当大的图像。当用户滚动时,我想在表视图中始终捕捉中间的大多数照片。也就是说,当表格处于静止状态时,它将始终有一个UITableViewCell
捕捉到中间
如何执行此操作?您可以使用
UITableView
上的UIScrollViewDelegate
方法执行此操作:
- (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];
}
有一个UIScrollView委托方法特别适用于此 编辑:如果你只是想要代码,看看下面的答案,这是建立在这个基础上的 当用户停止滚动时,表视图(它是一个滚动视图)将调用
-(void)ScrollViewWillendDraging:(UIScrollView*)scrollView with velocity:(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
以查看它将到达的位置,然后找到其中的单元格并对其进行适当修改。UITableView扩展了UIScrollView
myTableView.pagingEnabled = YES
根据@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];
}
扩展上面@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;
}
为了快速窥视
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
扩展@mikepj answer(这反过来又扩展了@JesseRusak的伟大答案),此代码允许您捕捉到单元格,即使单元格的高度可变(或未知),如果您滚动到下半行,也会捕捉到下一行,使其更“自然”
原始Swift 4.2代码:(为了方便起见,这是我开发和测试的实际代码)
您可以通过更改表的ContentOffset来实现这一点。您可以使用UITableview的scrollview委托方法和ContentOffset功能,正如Nishant所建议的:)谢谢!我要找的是如何检测哪个单元格是最中心的(您的centerTable方法)。这会起作用,但在表格视图停止后会导致奇怪的小滚动。同意Jesse Rusak的观点。在滚动过程中寻找快照。用此发布答案。谢谢。这也很有用。您的代码在使用iOS8的Xcode 6.3中抛出警告。我不得不使用下面的代码,但它什么也没做。targetContentOffset->x=100*(int)targetContentOffset/100;知道为什么吗?嘿,Jesse,我注意到你对上面答案的评论“这会起作用,但在表视图停止后会导致奇怪的小滚动。”-如果我能让你的答案起作用,它会产生更多的分页/快照滚动效果吗?非常感谢您的帮助。@user3344977是的,这个答案是一个分页/快照,而不是在停止后引起另一个滚动。您想要的是
->y
而不是->x
;我已经更新了答案。您还可以查看下面@mikepj的答案。需要括号才能获得正确的值:targetContentOffset->y=(100*(int)targetContentOffset->y/100);我不确定这个答案中的“中间阻力”是什么意思,但在实现了它之后,我已经验证了它会等到阻力动量稳定下来,然后再迅速到位。这是有意义的,因为在此之前不会调用didendraging和willBeginDecelerating。如果使用以下方法取消正在进行的滚动,则距离会近得多:停止拖动后,滚动将立即捕捉,但仍不会进行拖动中间的捕捉。
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
}
- (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;
}