Reputation: 61840
Link to the subclass of UITableView
I want to find out why UITableView jumps while scrolling.
How to perform some changes on UITableView
along with setting its contentOffset
?
This is how I set up my scrollDisplayLink
:
scrollDisplayLink = CADisplayLink(target: self, selector: Selector("scrollTable"))
scrollDisplayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
cellForCurrentIndexPath?.hidden = true
and then within scrollTable
I do following things:
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
}
}
}
Scrolling is fine unless lines 1-4
are commented or I disable UITableViewAutomaticDimension
. When they are not commented the table jumps when currentContentOffset
is different then 0
while scrolling. Why it happens like that? Is it problem with threads or something else?
UITableView
works with UITableViewAutomaticDimension
:
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Upvotes: 11
Views: 833
Reputation: 6859
Let's start with the obvious:
UITableView is a subclass of UIScrollView and we can use some properties of that.
Almost each year there is an excellent WWDC talk about how to customize UIScrollviews.
They suggest to do things like you do inside
// is called every frame of scrolling and zooming
override func layoutSubviews() {
...
super.layoutSubviews()
...
}
which is called each frame while the user is scrolling.
I've used this place heavily to mess around with currentContentOffset and size and coordinate systems while scrolling (I subclassed UIScrollView and not UITableView).
Advantages:
Hope this helps
P.S.
according to my experiments, the view that is scrolled inside a UIScrollView can be not higher than around 8000 pixels.
So Apples UITableView has to implement a strategy that is called infinite scrolling and is described in one of the WWDC videos about UIScrollViews:
in short:
a fraction of the table is drawn once and then scrolled without redrawing the table content. When the user scrolls too far, a different part of the scrolled table is drawn and at the same time contentOffset is changed by the UITableView implementation.
This is probably done when you call super.layoutSubviews() in your implementation of layoutSubviews().
Upvotes: 0