I'm using a custom UITableViewCell, into which I am placing a subclassed UIView (within contentView
, natch). The UIView in question displays a directional arrow and two lines of supporting text.
The arrow is displayed by means of a layer with a background color and an arrow-shaped mask. The background color changes to one of two possibilities depending on the direction the arrow is pointing.
The view receives a NSNotification whenever it needs to update the arrow (based on, but not identical to, the current heading - each cell and view is different). When it receives notice, the view calls a private method to perform a transform. This animates the arrow layer, effectively rotating it around its center to a new direction, like so:
// Update layer BG color, then ...
[UIView setAnimationBeginsFromCurrentState:YES];
CATransform3D transform = CATransform3DMakeRotation(DegreesToRadians(locationDirection), 0, 0, 1);
_arrowLayer.transform = transform;
(n.b.: _arrowLayer
is for internal use only, and is not exposed through a property.)
There is also a property on the UIView to set info used to create the supporting text. When this is changed, setNeedsDisplay
is invoked, the drawRect:
method makes the calculations and draws the resulting text.
That's all well and good. However, there is one major problem I'm encountering:
Scrolling the table view at the same time the arrows are animating results in some major league choppy scrolling, often to the point of the scrolling stopping short! Even when this is the only view in contentView
(in the name of minimal test cases), it doesn't matter.
If the device is not moved, scrolling is moderately acceptable, but still open to improvement.
I'm hopeful that I'm simply making a fundamental error (Don't use drawRect:
? Do the transform some other way? None of the above?)
Thanks in advance for any clues/advisement!
UPDATE 4 Oct 2011: I tried having the UITableViewController watch UIScrollViewDelegate (per the UIScrollView programming guide) for when scrolling starts/stops, then each directional arrow view asks its delegate (the Table VC in this case) if it's OK to animate. This doesn't help much either though. If animation is in progress, we're out of luck. Perhaps NSNotification is in order, with the directional arrow view looking for a certain notification. (That sounds a bit backwards though, doesn't it? Giving other objects a notification that they can send out? Hmm.)
Try something like this:
self.layer.shouldRasterize = YES;
I'm not sure which layer (or layers) should set this property, but I've often faced the problem of animation being jerky, which problem is fixed by setting shouldRasterize
.
The trick for performant scrolling is to use CoreGraphics instead of CoreAnimation. The explanation can be found here:
http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/
Here is another StackOverflow Question: Tricks for improving iPhone UITableView scrolling performance?
So in this example, I would try to avoid the arrow mask and draw it with CG
来源:https://stackoverflow.com/questions/7419985/uiview-with-catransform3d-inside-a-uitableviewcell-choppy-scrolling