Ios 如何在使用CADisplayLink和UITableViewAutomaticDimension滚动时在UITableView上执行更新而不跳跃?

Ios 如何在使用CADisplayLink和UITableViewAutomaticDimension滚动时在UITableView上执行更新而不跳跃?,ios,swift,uitableview,uitableviewautomaticdimension,Ios,Swift,Uitableview,Uitableviewautomaticdimension,为什么UITableView在滚动时会跳转?您能帮我吗 对于帮助我的人,我先开始,然后再奖励另一个100:-) 如何在设置其contentOffset的同时对UITableView执行一些更改 这是我设置滚动显示链接的方式: scrollDisplayLink = CADisplayLink(target: self, selector: Selector("scrollTable")) scrollDisplayLink?.addToRunLoop(NSRunLoop.mainRunLoop(

为什么UITableView在滚动时会跳转?您能帮我吗

对于帮助我的人,我先开始,然后再奖励另一个100:-)

如何在设置其
contentOffset
的同时对
UITableView
执行一些更改

这是我设置滚动显示链接的方式:

scrollDisplayLink = CADisplayLink(target: self, selector: Selector("scrollTable"))
scrollDisplayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
cellForCurrentIndexPath?.hidden = true
然后在
滚动表中我做以下事情:

func scrollTable() {
    var newOffset = CGPointMake(currentContentOffset.x, currentContentOffset.y + scrollRate * 10)

    if currentContentSize.height < frame.size.height {
        newOffset = currentContentOffset
    } else if newOffset.y > currentContentSize.height - frame.size.height {
        newOffset.y = currentContentSize.height - frame.size.height
    } else if newOffset.y < 0 {
        newOffset = CGPointZero
    }

    contentOffset = newOffset


    if coveredIndexPath != nil && coveredIndexPath! != currentIndexPath! {

        let verticalPositionInCoveredCell = longPressGestureRecognizer.locationInView(cellForRowAtIndexPath(coveredIndexPath!)).y

        if direction == .Down && heightForCoveredCell - verticalPositionInCoveredCell <= heightForCurrentCell / 2 {
                print("moved down")

                beginUpdates() //1
                moveRowAtIndexPath(currentIndexPath!, toIndexPath: coveredIndexPath!)  //2
                currentIndexPath = coveredIndexPath //3
                endUpdates() //4

        }
    }
}

让我们从显而易见的事情开始:

UITableView是UIScrollView的一个子类,我们可以使用它的一些属性

几乎每年都有一次关于如何定制UIScrollView的精彩WWDC演讲

他们建议你做一些你在里面做的事情

// is called every frame of scrolling and zooming
override func layoutSubviews() {
    ...
    super.layoutSubviews()
    ...
}
当用户滚动时,它被称为每一帧

在滚动时,我经常使用这个地方来处理currentContentOffset、大小和坐标系(我将UIScrollView和not UITableView子类化)

优点:

  • 您可以免费获得每帧的回调,无需使用CADisplayLink
  • 当UIScrollView希望更改内容时,您正在更改内容偏移量
希望这有帮助

附言

根据我的实验,在UIScrollView中滚动的视图不能高于8000像素左右

因此,Apple UITableView必须实施一种称为无限滚动的策略,该策略在WWDC关于UIScrollView的视频中有介绍:

简言之:

表格的一部分绘制一次,然后滚动,而不重新绘制表格内容。当用户滚动过远时,将绘制滚动表的不同部分,同时UITableView实现会更改contentOffset

在layoutSubviews()的实现中调用super.layoutSubviews()时,可能会执行此操作

// is called every frame of scrolling and zooming
override func layoutSubviews() {
    ...
    super.layoutSubviews()
    ...
}