Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 要将UITableView设置为;“捕捉到单元格”;_Ios_Objective C_Uitableview_Uiscrollviewdelegate - Fatal编程技术网

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;
}