Как выполнять обновления в UITableView при прокрутке с использованием CADisplayLink и UITableViewAutomaticDimension без прыжка?

Ссылка на подкласс UITableView

Почему UITableView перескакивает при прокрутке? Можете ли вы мне помочь?

для того, кто помогает мне, я начинаю и награждаю позже ДРУГОЙ щедрость 100: -)

Как выполнить некоторые изменения на UITableView вместе с настройкой contentOffset?

Вот как я установил свой scrollDisplayLink:

scrollDisplayLink = CADisplayLink(target: self, selector: Selector("scrollTable"))
scrollDisplayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
cellForCurrentIndexPath?.hidden = true

а затем внутри scrollTable выполняю следующие действия:

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

        }
    }
}

Прокрутка отлично, если строки 1-4 не комментируются или я отключен UITableViewAutomaticDimension. Когда они не комментируются, таблица перескакивает, когда currentContentOffset отличается от 0 при прокрутке. Почему так происходит? Это проблема с потоками или чем-то еще?

Примечание:

UITableView работает с UITableViewAutomaticDimension:

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

Ответ 1

Начнем с очевидного:

UITableView является подклассом UIScrollView, и мы можем использовать некоторые его свойства.

Почти каждый год есть отличный разговор WWDC о том, как настроить UIScrollviews.

Они предлагают делать то, что вы делаете внутри

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

который вызывается каждым кадром во время прокрутки пользователя.

Я использовал это место для беспорядка с помощью currentContentOffset и систем размера и координат во время прокрутки (я подклассифицировал UIScrollView, а не UITableView).

Преимущества:

  • вы получаете свои обратные вызовы в каждом кадре бесплатно, не нужно использовать CADisplayLink
  • вы меняете вещи tike contentOffset точно, когда UIScrollView ожидает, что он будет изменен.

Надеюсь, что это поможет

P.S.

согласно моим экспериментам, представление, которое прокручивается внутри UIScrollView, может быть не выше, чем около 8000 пикселей.

Итак, яблоки UITableView должны реализовать стратегию, называемую бесконечной прокруткой, и описывается в одном из видео WWDC о UIScrollViews:

:

часть таблицы рисуется один раз и затем прокручивается без перерисовки содержимого таблицы. Когда пользователь прокручивается слишком далеко, выполняется другая часть прокрученной таблицы и в то же время contentOffset изменяется с помощью реализации UITableView.

Это возможно, когда вы вызываете super.layoutSubviews() в своей реализации layoutSubviews().