4

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.)

Joe D'Andrea
  • 5,141
  • 6
  • 49
  • 67

2 Answers2

0

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.

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
  • I'll give that a try - thank you! Didn't even think about that one. In my case, I s'pose I would set the layer being rotated. Worth a shot. – Joe D'Andrea Oct 06 '11 at 21:25
  • Oh, interesting. As soon as you mentioned shouldRasterize, I found this: http://stackoverflow.com/questions/3248201/why-is-scrolling-performance-poor-for-custom-table-view-cells-having-uisegmentedc – Joe D'Andrea Oct 06 '11 at 21:26
  • Update: If I understand correctly, shouldRasterize is for offscreen rendering, but the CALayer that I'm rotating is always in view, plus I'm using masks, and rasterization happens before the mask kicks in. Danger Will Robinson? – Joe D'Andrea Oct 07 '11 at 13:53
  • Yes, danger, definitely. I do not pretend to understand how `shouldRasterize` works - in every case where I've used it to fix jerky animation, it seems like logically it should have exactly the opposite effect. – MusiGenesis Oct 07 '11 at 14:19
  • No worries. It was worth a shot! – Joe D'Andrea Oct 19 '11 at 20:09
0

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

Community
  • 1
  • 1
nambrot
  • 2,551
  • 2
  • 19
  • 31
  • 1
    Aye, I'm already using Loren's technique elsewhere in the cell (for the supporting text). As I understand it, it's not that we use CoreGraphics "instead of" CoreAnimation. It's that CoreAnimation will scroll smooth-as-glass the more you do your own drawing. (Apple has a table view cells demo which shows a variety of techniques here.) ... all of which leads me straight back to my question: Can you have an independently animated object (which has nothing to do with the scrolling of a table view cell) and have it peacefully coexist? – Joe D'Andrea Oct 06 '11 at 21:23