2
votes

I am inside a UIView subclass (CustomView in the code below).

I am drawing a border around an image in a UIImageView subclass (containerView). The Core Graphics code for this is located inside drawInRect: in the subclass.

The Core Animation transition is a flip, however when it is drawn, the Core Graphics code is not used, i.e. drawInRect: is not called to provide the CALayer with my rendered image.

Instead I get the animation from one image to the other without any Core Graphics drawing occurring.

How do I allow the CALayer to animate using my Core Graphics drawing rather than the raw image?

[CustomView beginAnimations:@"transitionNextImage" context:nil];
[CustomView setAnimationDuration:2.0];
[containerView setImage:image];
[CustomView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:containerView cache:YES];
[containerView setImage:differentImage];
[CustomView commitAnimations];
2

2 Answers

3
votes

Okay yes I was implementing drawRect:, and yes my drawing worked outside of the transition.

The problem was that drawRect: inside a UIImageView subclass was not being called by the CALayer for the drawing.

So when I switched the parent of this subclass to UIView, implemented my own property for the image, and also adjusted the animation - everything came together.

The animation's containerView in the code above, was changed to be a vanilla UIView instance. The animation code had to be changed slightly to accommodate this:

[CustomView beginAnimations:@"transitionNextImage" context:nil];
[CustomView setAnimationDuration:2.0];
[containerView addSubview:aViewSubclass];
[CustomView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:containerView cache:YES];
[aViewSubclass removeFromSuperview];
[containerView addSubview:anotherInstanceOfTheViewSubclass];
[CustomView commitAnimations];

I.e. from Apple's docs on these kinds of transitions:

If you want to change the appearance of a view during a transition—for example, flip from one view to another—then use a container view, an instance of UIView, as follows:

  1. Begin an animation block.
  2. Set the transition on the container view.
  3. Remove the subview from the container view.
  4. Add the new subview to the container view.
  5. Commit the animation block.
2
votes

You're implementing drawRect:, not drawInRect:, right? Also, have you verified that outside of this transition, it actually works?

Can you paste your drawRect:implementation? I'm just afraid that UIImageView sets the contents of its layer directly instead of relying on drawRect: to do it, which would mean your drawRect: doesn't work.

In fact, given how simple this actually is, I would recommend you just subclass UIView instead of UIImageView. The math to preserve aspect ratio when scaling the image for drawing is pretty simple.

Another option is, of course, to subclass UIImageView and then just override setImage: to create a new image based on the first but drawing a border around that, and then passing that to super. That way you don't have to do anything with drawRect: at all.