Re: UIView animation (backgroundColor) + drawRect:

2011-03-03 Thread Roland King
As ever, thanks very much David. I figured there was *something* going on when 
drawRect: was defined but I wouldn't have figured out what without this help. 

In this case a crossfade in every case for that particular view works 
perfectly, I implemented what you suggested and it looks so much better, it's 
amazing the difference that even a .3-.5 second smooth transition can make, 
just takes the edge off something which was quite harsh before, looks much more 
professional. 

Got the point (again) on using simple subviews when possible, a mistake I've 
made before. In this particular case I don't think that was going to work, but 
I'm very happy with what I have now. 

Andreas, thanks for your reply too. You had pretty much exactly the same 
thoughts I did and we both tried the same ideas, with the same 
..AllowAnimatedContent etc and got the same results; hope David's reply was 
useful to you too, it goes in my 'keepers' file. 

On 03-Mar-2011, at 5:10 AM, David Duncan wrote:

 On Mar 2, 2011, at 5:12 AM, Roland King wrote:
 
 I was trying to animate the backgroundColor of one of my UIView subclasses 
 yesterday using 
 
  [ UIView animateWithDuration:2.0 animations:^{ [ myView 
 setBackgroundColor:someColor ]; } ];
 
 but no matter what the duration set, the background color was changing 
 instantly. Whilst looking to see if there were two places I called 
 setBackgroundColor: (there weren't) I realized that my UIView subclass has 
 its own drawRect: method (this view is basically a piece of paper with some 
 lines drawn on it, so it needs a custom drawRect: method). Commenting that 
 out, the view background animated properly, but of course I had no content. 
 Even just adding an empty drawRect: method was enough to defeat the 
 animation. 
 
 
 When you implement -drawRect:, the background color of your view is then 
 drawn into the associated CALayer, rather than just being set on the CALayer 
 as a style property. Now Core Animation can animate both transitions, but 
 UIView disables the animation of a layer's contents, which thus prevents you 
 from getting a contents crossfade (as in the vast majority of cases this 
 wouldn't be what you want).
 
 The crossfade may be exactly what you want in this case. Likely the best way 
 to defeat UIView's override in this case may be to create a subclass of 
 CALayer that overrides -actionForKey:. In that override, you would check for 
 the @contents key and return a CABasicAnimation ([CABasicAnimation 
 animation] should do it) and in all other cases return what the default 
 implementation does. This has the downside that you will *always* cross fade 
 and you won't be able to integrate with UIKit's animation APIs (you just get 
 animation for contents on all the time).
 
 Another solution would be to use a super view that contains just the 
 background color and have your lines composited over it (assuming they are 
 simple lines this could be done with simple subviews that are sized for each 
 line). This would allow you to avoid -drawRect: entirely, which would allow 
 you to animate the background color and may offer some memory usage benefits 
 (if you can use subviews). 
 --
 David Duncan
 

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: UIView animation (backgroundColor) + drawRect:

2011-03-02 Thread Andreas Grosam

On Mar 2, 2011, at 2:12 PM, Roland King wrote:

 I was trying to animate the backgroundColor of one of my UIView subclasses 
 yesterday using 
 
   [ UIView animateWithDuration:2.0 animations:^{ [ myView 
 setBackgroundColor:someColor ]; } ];
 
 but no matter what the duration set, the background color was changing 
 instantly. Whilst looking to see if there were two places I called 
 setBackgroundColor: (there weren't) I realized that my UIView subclass has 
 its own drawRect: method (this view is basically a piece of paper with some 
 lines drawn on it, so it needs a custom drawRect: method). Commenting that 
 out, the view background animated properly, but of course I had no content. 
 Even just adding an empty drawRect: method was enough to defeat the 
 animation. 
 
 My assumption is that if there is no custom drawing, the view can smoothly 
 animate its layer between the two colors, and animate any other simple 
 properties, but if there is custom drawing, it doesn't want to call that 
 constantly as it animates the color change, so animation doesn't happen. 
 
 Is there anything I missed which will make this work,? I was thinking that 
 the other transition animation methods ( [ UIView transitionWithView: .. ] ) 
 take a 'before' and 'after' snapshot and then, if you are flipping, animate 
 one away, and one in. I perhaps expected that UIView to do basically that, 
 and crossfade the old view out and the new one in, but I see no option for 
 that, just flips and curls, I want fade. This would be more generally useful 
 than just this example. 

Intuitively, a possibly solution would look like this:

UIView* view = self.helloView;
[UIView transitionWithView:view 
  duration:2.0 
   options:UIViewAnimationOptionAllowAnimatedContent | 
UIViewAnimationOptionTransitionNone
animations:^{ view.backgroundColor = [UIColor greenColor]; 
} 
completion:NULL];

Unfortunately, I couldn't get the background color to fade smoothly for UILabel 
or IUView whose drawRect is overridden as well. Implicit layer animations 
didn't work either.

For plain UIView instances the code above works with smooth animations, though. 
The simplest version is:

[UIView animateWithDuration:2.0 animations:^{ 
self.helloView.backgroundColor = [UIColor greenColor];
}];

 
 Obviously I have a few other options including building an entirely new 
 UIView on a color change, adding them both and fading their alphas in and 
 out, or splitting my 'paper' into a background view and an otherwise-clear 
 lines view. That may well be the right way to go with this, however I was 
 interested to know if there was some part of UIView animation which would 
 automatically handle a smooth transition of one single UIView between two 
 drawn states. 
Well, there is - but transition means the process of creating another image 
(from the original) and then move (in some animated way) from the original 
position to the target position. Fading the background color might not be a 
transition. However, when specifying the option 
UIViewAnimationOptionAllowAnimatedContent in a transition I would hope property 
changes would be simultaneously animated - and it did for UIViews.

A solution for your problem may look like this:

UIView* fromView = self.helloView;
UIView* toView = ...  // copy the fromView
toView.alpha = 0.0;
toView.backgroundColor = [UIColor greenColor]; // change the background 
color
[self.view insertSubview:toView aboveSubview:fromView];

[UIView animateWithDuration:2.0 
 animations:^{ 
 fromView.alpha = 0.0;
 toView.alpha = 1.0;
 }
 completion:^(BOOL finished){ [fromView 
removeFromSuperview]; }];

self.helloView = toView;
[toView release], toView = nil;


Regards
Andreas

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: UIView animation (backgroundColor) + drawRect:

2011-03-02 Thread David Duncan
On Mar 2, 2011, at 5:12 AM, Roland King wrote:

 I was trying to animate the backgroundColor of one of my UIView subclasses 
 yesterday using 
 
   [ UIView animateWithDuration:2.0 animations:^{ [ myView 
 setBackgroundColor:someColor ]; } ];
 
 but no matter what the duration set, the background color was changing 
 instantly. Whilst looking to see if there were two places I called 
 setBackgroundColor: (there weren't) I realized that my UIView subclass has 
 its own drawRect: method (this view is basically a piece of paper with some 
 lines drawn on it, so it needs a custom drawRect: method). Commenting that 
 out, the view background animated properly, but of course I had no content. 
 Even just adding an empty drawRect: method was enough to defeat the 
 animation. 


When you implement -drawRect:, the background color of your view is then drawn 
into the associated CALayer, rather than just being set on the CALayer as a 
style property. Now Core Animation can animate both transitions, but UIView 
disables the animation of a layer's contents, which thus prevents you from 
getting a contents crossfade (as in the vast majority of cases this wouldn't be 
what you want).

The crossfade may be exactly what you want in this case. Likely the best way to 
defeat UIView's override in this case may be to create a subclass of CALayer 
that overrides -actionForKey:. In that override, you would check for the 
@contents key and return a CABasicAnimation ([CABasicAnimation animation] 
should do it) and in all other cases return what the default implementation 
does. This has the downside that you will *always* cross fade and you won't be 
able to integrate with UIKit's animation APIs (you just get animation for 
contents on all the time).

Another solution would be to use a super view that contains just the background 
color and have your lines composited over it (assuming they are simple lines 
this could be done with simple subviews that are sized for each line). This 
would allow you to avoid -drawRect: entirely, which would allow you to animate 
the background color and may offer some memory usage benefits (if you can use 
subviews). 
--
David Duncan

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com