I have a CAEmitterCell and I have set it up with a specific colour. The documentation says that this property is animatable, and I would like to animate this between a number of different colours for the different players in my game (all of whom choose their color at the start).
Here is my EmitterCell when I set it up:
//
// Emitter Cells
//
// 'New Emitter' cell configuration
newEmitter = [CAEmitterCell emitterCell];
newEmitter.scaleSpeed = 10;
newEmitter.lifetime = 2.481715;
newEmitter.velocity = 332.3636968085106;
newEmitter.contents = newemitterImg;
newEmitter.name = #"New Emitter";
newEmitter.color = [[UIColor colorWithRed:0.50 green:0.00 blue:1.00 alpha:1.00] CGColor];
newEmitter.scaleRange = 4.178236607142859;
newEmitter.lifetimeRange = 1.6;
newEmitter.greenRange = -2.775558e-17;
newEmitter.birthRate = 40;
newEmitter.emissionRange = -6.283185306666667;
newEmitter.scale = 0;
//
// Emitter Cell Chains
//
emitter.emitterCells = [NSArray arrayWithObjects:newEmitter, nil];
And here is where I am testing the color change in this case just bouncing between two different colors:
-(void)changeColor {
if (color == 0) {
color = 1;
NSLog(#"color = 1");
[UIView animateWithDuration:1.5 delay:0 options:0 animations:^{
newEmitter.color = [[UIColor colorWithRed:0.50 green:0.00 blue:1.00 alpha:1.00] CGColor];
} completion:^(BOOL finished) {[self performSelector:#selector(changeColor) withObject:nil afterDelay:2];}];
} else {
color = 0;
NSLog(#"color = 0");
[UIView animateWithDuration:1.5 delay:0 options:0 animations:^{
newEmitter.color = [[UIColor colorWithRed:1.00 green:0.50 blue:0.10 alpha:1.00] CGColor];
} completion:^(BOOL finished) {[self performSelector:#selector(changeColor) withObject:nil afterDelay:2];}];
}
}
However, when I run this the color never changes. Have I misunderstood the nature of "Animatable" here, or do I just need to go about it differently for a CAEmitterCell?
CAEmitterCells are, in fact, different. To get animations working on them, you need to take these steps:
1.Assign a name to your CAEmitterCell, e.g.:
newEmitter.name = #"fire";
2.Access the animation property for this emitter through the CAEmitterLayer instance:
//Set first before doing CABasicAnimation so it sticks
newEmitter.redSpeed = 1.0;
//Access the property with this key path format: #"emitterCells.<name>.<property>"
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:#"emitterCells.fire.redSpeed"];
anim.fromValue = #(0.0);
anim.toValue = #(1.0);
anim.duration = 1.5;
anim.fillMode = kCAFillModeForwards;
[emitter addAnimation:anim forKey:#"emitterAnim"];
Try this:
[newEmitter.emitterCells[0] setColor:[[UIColor yellowColor] CGColor]];
You can use those properties to animate emiter color.
newEmitter.redSpeed = 1.0;
newEmitter.greenSpeed = 1.0;
newEmitter.blueSpeed = 1.0;
Related
I need to rotate and scale a UIImageView image with the help of UISlider.
There are three condition when UISlider value is in its middle position then the original image will be its original position.
Second case, When slider value is maximum then image will rotate with 45 degree add bit scale.
Third case, when slider value is in its minimum position then image will rotate 45 degree in opposite direction and also bit scale.
I used this code but did not get desired result.
-(IBAction)sliderMoved:(id)sender
{
UIImage *image = [UIImage imageNamed:#"landscape.jpg"];
photoImage.transform = CGAffineTransformMakeRotation(slider.value * 2*M_PI_2 / slider.maximumValue);
CGFloat scale=0.5;
NSLog(#"sliderVlaue=%f",slider.value);
if ((slider.value) >(0.75)) {
scale =(.25+ slider.value);
} else {
scale =(0.75 +slider.value);
}
CGAffineTransform currentTransform = photoImage.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[photoImage setTransform:newTransform];
}
you can try this code
CGFloat Angle=(((int)slider.value*M_PI)/180);
transform=CGAffineTransformScale(transform, photoImage.scale, photoImage.scale);
transform= CGAffineTransformRotate(transform,Angle);
photoImage.transform = transform;
You can use this code for image rotation
imageview.transform = CGAffineTransformMakeRotation(M_PI);
For scaling an image
-(IBAction)grow
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationRepeatAutoreverses:YES];
CGRect b = grower.bounds;
b.size.height = 200;
b.size.width = 200;
grower.bounds = b;
[UIView commitAnimations];
}
I tried my self with the help of given hints and able to way out from my problem. here is the code`
in you h file declare UIImageView *photoImage;
UIView *canvas;
CAShapeLayer *_marque;
And in view did load
if (!_marque) {
_marque = [CAShapeLayer layer] ;
_marque.fillColor = [[UIColor clearColor] CGColor];
_marque.strokeColor = [[UIColor grayColor] CGColor];
_marque.lineWidth = 1.0f;
_marque.lineJoin = kCALineJoinRound;
_marque.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:10],[NSNumber numberWithInt:5], nil];
_marque.bounds = CGRectMake(photoImage.frame.origin.x, photoImage.frame.origin.y, 0, 0);
_marque.position = CGPointMake(photoImage.frame.origin.x + canvas.frame.origin.x, photoImage.frame.origin.y + canvas.frame.origin.y);
}
[[self.view layer] addSublayer:_marque];
- (IBAction) sliderMoved:(id)sender
{
CGFloat scale=0;
NSLog(#"sliderVlaue=%f",slider.value);
if ((slider.value) >(0.77)) {
scale =(.5+ slider.value);
photoImage.transform = CGAffineTransformMakeRotation(((4*slider.value)*(M_PI/180)));
CGAffineTransform currentTransform = photoImage.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale-.25, scale-.25);
[photoImage setTransform:newTransform];
NSLog(#"max=%f",scale);
}else if(slider.value< 0.77 && slider.value >.73){
photoImage.transform=CGAffineTransformIdentity;
photoImage.frame=imageframe;
scale =(0.5 +slider.value);
NSLog(#"mid=%f",scale);
}
else{
scale =(.77 +(1.0-slider.value));
photoImage.transform = CGAffineTransformMakeRotation((((-4)*(slider.value))*(M_PI/180)));
CGAffineTransform currentTransform = photoImage.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[photoImage setTransform:newTransform];
NSLog(#"min=%f",scale);
}
//_lastScale = 1;
[self showOverlayWithFrame:photoImage.frame];
}
-(void)showOverlayWithFrame:(CGRect)frame {
if (![_marque actionForKey:#"linePhase"]) {
CABasicAnimation *dashAnimation;
dashAnimation = [CABasicAnimation animationWithKeyPath:#"lineDashPhase"];
[dashAnimation setFromValue:[NSNumber numberWithFloat:0.0f]];
[dashAnimation setToValue:[NSNumber numberWithFloat:15.0f]];
[dashAnimation setDuration:0.5f];
[dashAnimation setRepeatCount:HUGE_VALF];
[_marque addAnimation:dashAnimation forKey:#"linePhase"];
}
_marque.bounds = CGRectMake(frame.origin.x, frame.origin.y, 0, 0);
_marque.position = CGPointMake(frame.origin.x + canvas.frame.origin.x, frame.origin.y + canvas.frame.origin.y);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, frame);
[_marque setPath:path];
CGPathRelease(path);
_marque.hidden = NO;
}
You can do it with the following code:
- (void)viewDidLoad
{
[super viewDidLoad];
imgToRotate = [[UIImageView alloc]initWithFrame:CGRectMake(48, 208, 240, 240)];
imgToRotate.image = [UIImage imageNamed:#"rtm.jpeg"];
[self.view addSubview:imgToRotate];
}
- (IBAction)slideToRotateScale:(UISlider *)sender
{
sender.maximumValue = 1.0;
sender.minimumValue = -1.0;
imgToRotate.transform = CGAffineTransformRotate(CGAffineTransformMakeScale(fabsf(sender.value), fabs(sender.value)), sender.value*M_PI/4);
}
I have an image on the UIButton that I wish to glow in when I click button and glow out when I click it again.
Everytime I click, it doesn't glow out, it only glows in making it brighter
.
I have tried UIView animateWithDuration as well as CATransition and CABasicAnimation..
Something is wrong. Probably something basic that I should know about.
I'd appreciate the help.
Heres my code:
-(void)didTapButton:(UIButton *)button {
button.selected = !button.selected;
UIColor *glowColor = [self.arrayOfGlowColor objectAtIndex:button.tag];
UIImageView *imageView = button.imageView;
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, [UIScreen mainScreen].scale);
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0,0,imageView.bounds.size.width,imageView.bounds.size.height)];
[glowColor setFill];
[path fillWithBlendMode:kCGBlendModeSourceAtop alpha:1.0];
UIImage *imageContext_image = UIGraphicsGetImageFromCurrentImageContext();
UIView *glowView = [[UIImageView alloc] initWithImage:imageContext_image];
glowView.center = imageView.center;
[imageView.superview insertSubview:glowView aboveSubview:imageView];
glowView.alpha = 0;
glowView.layer.shadowColor = glowColor.CGColor;
glowView.layer.shadowOffset = CGSizeZero;
glowView.layer.shadowRadius = 10;
glowView.layer.shadowOpacity = 1.0;
/*
[UIView animateWithDuration: 1.0 animations:^(void) {
glowView.alpha = (button.selected) ? 1.0 : 0.0f;
}];
NSLog(#"glowView.alpha:%f",glowView.alpha);
NSLog(button.selected ? #"YES" : #"NO");
*/
/*
if (button.selected) {
CATransition *fadeIn = [CATransition animation];
fadeIn.duration = 1.0;
fadeIn.startProgress = 0.0f;
fadeIn.endProgress = 1.0f;
[fadeIn setType:kCATransitionFade];
fadeIn.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[fadeIn setFillMode:#"extended"];
[glowView.layer addAnimation:fadeIn forKey:nil];
}
if (!button.selected) {
CATransition *fadeOut = [CATransition animation];
fadeOut.duration = 1.0;
fadeOut.startProgress = 1.0f;
fadeOut.endProgress = 0.0f;
[fadeOut setType:kCATransitionFade];
fadeOut.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[fadeOut setFillMode:#"extended"];
[glowView.layer addAnimation:fadeOut forKey:nil];
}
*/
if (button.selected) {
//Create a one-way animation that fades in the glow.
glowView.layer.opacity = 1.0;
CABasicAnimation *glowFadeInAnim = [CABasicAnimation animationWithKeyPath:#"opacity"];
glowFadeInAnim.fromValue = [NSNumber numberWithDouble:0.0];
glowFadeInAnim.toValue = [NSNumber numberWithDouble:1.0];
glowFadeInAnim.repeatCount = 1;
glowFadeInAnim.duration = 1.0;
glowFadeInAnim.autoreverses = FALSE;
glowFadeInAnim.fillMode = kCAFillModeForwards;
glowFadeInAnim.removedOnCompletion = NO;
glowFadeInAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[glowView.layer addAnimation:glowFadeInAnim forKey:nil];
}
if (!button.selected) {
glowView.layer.opacity = 1.0;
CABasicAnimation *glowFadeOutAnim = [CABasicAnimation animationWithKeyPath:#"opacity"];
glowFadeOutAnim.fromValue = [NSNumber numberWithDouble:1.0];
glowFadeOutAnim.toValue = [NSNumber numberWithDouble:0.0];
glowFadeOutAnim.repeatCount = 1;
glowFadeOutAnim.beginTime = 2;
glowFadeOutAnim.duration = 2.0;
glowFadeOutAnim.autoreverses = FALSE;
glowFadeOutAnim.fillMode = kCAFillModeForwards;
glowFadeOutAnim.removedOnCompletion = NO;
glowFadeOutAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[glowView.layer addAnimation:glowFadeOutAnim forKey:nil];
glowView.layer.opacity = 0.0;
}
NSLog(#"glowView.opacity:%f",glowView.layer.opacity);
NSLog(button.selected ? #"YES" : #"NO");
}
If you create a new glowView every time the button is pressed and add it to the button, then obviously it will just keep getting brighter, as more and more of them are being added to the button. You need to create the glowView once, for example in your viewDidLoad method, and store it as an instance variable so you don't lose it:
#interface MyViewController : UIViewController {
UIView *_glowView;
}
...
- (void)viewDidLoad {
[super viewDidLoad];
_glowView = ... // Initialise it here
...
[imageView.superview insertSubview:_glowView aboveSubview:imageView];
}
Then in your didTapButton: method, you handle the tap as you do (adding or removing the _glowView, but make sure you don't set it to nil so the reference to it is always retained). This way, you only create and add it once, and the problem should be solved.
I need to give some stretch & skew animation to a UIView upon pressing a button or completion of a task.
Most of the animation applied to UIView are usually applied when they are added to or removed from a UIView but how can I accomplish that with a view already added to view.
Animation could be anything as long as it catches users attention (to indicate that the task was completed).
EDIT How to scale and rotate a view in a single animation
You might need use Core Animation and add both animations in a group:
CABasicAnimation *stetchAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale.x"];
stetchAnimation.toValue = [NSNumber numberWithDouble:(someView.frame.size.width+100)/someView.frame.size.width];
CABasicAnimation *skewAnimation = CABasicAnimation animationWithKeyPath:#"transform.rotation.x"];
stetchAnimation.toValue:[NSNumber numberWithInt:180];
//Add both animation at time when task is completed
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.animations = [NSArray arrayWithObjects:stetchAnimation,skewAnimation,nil];
animationGroup.removedOnCompletion = YES;
animationGroup.fillMode = kCAFillModeForwards;
animationGroup.duration = 0.7; // increase duration if needed
[someView.layer addAnimation:animationGroup forKey:#"animations"];
Simple UIView animation; temporarily grows the view:
[UIView animateWithDuration:0.3 animations:^{
CGRect frm = view.frame;
frm.size.width += 20;
frm.size.height += 20;
frm.origin.x -= 10;
frm.origin.y -= 10;
view.frame = frm;
} completion:^{
[UIView animateWithDuration:0.3 animations:^{
CGRect frm = view.frame;
frm.size.width -= 20;
frm.size.height -= 20;
frm.origin.x += 10;
frm.origin.y += 10;
view.frame = frm;
}];
}];
how to animate the uilabel view in such a way that it should keep moving from right side of the screen towards left ,
i have used the folloiwing code but it didnt work
UILabel * lbl =[UILabel alloc]init];
CALayer *cloud = [CALayer layer];
cloud.contents = lbl.text;
cloud.bounds = CGRectMake(0, 40, 100, 30);
cloud.position = CGPointMake(-45 ,30);
//cloud.position = CGPointMake(self.view.bounds.size.width / 2,cloudImage.size.height / 2);
[self.view.layer addSublayer:cloud];
CGPoint startPt = CGPointMake(self.view.bounds.size.width + cloud.bounds.size.width / 2,
cloud.position.y);
CGPoint endPt = CGPointMake(cloud.bounds.size.width / -2,
cloud.position.y);
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:#"position"];
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
anim.fromValue = [NSValue valueWithCGPoint:startPt];
anim.toValue = [NSValue valueWithCGPoint:endPt];
anim.repeatCount = 1;
anim.duration = 5.0;
[cloud addAnimation:anim forKey:#"position"];
It's a lot easier if you can use animateWithDuration in ios4
UILabel *label = //new label
[UIView animateWithDuration:1.0 animations:^{
label.frame = //new frame
}];
You can do it like this:
UILabel *label = [[UILabel alloc] initWithFrame:theRect];
[self.view addSubview:label];
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationCurveEaseIn
animations:^{label.bounds = targetRect;}
completion:^(BOOL finished) { /* completion stuff */}];
There are more animate methods that take less parameters. You find them in the UIView documentation.
I have two UIViewControllers A and B and they are added as subviews in the AppDelegate with B on top of A.
When a UIButton on B is tapped B slides off to the left with the following code:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(slideOutFinished)];
simonSaysView.view.frame = CGRectMake(40-BView.view.frame.size.width, BView.view.frame.origin.y, BView.view.frame.size.width, BView.view.frame.size.height);
[UIView commitAnimations];
On the right edge I want a 20px drop shadow but i cannot use the shadow properties of BView.view.layer.shadow.... because its 3.2/4.0+ only. And the performance of the animation is awful, the slide is lagging extremely much (Its fluent without the shadow).
I'm thinking using a custom UIView and do some magic in drawRect but is this possible or can i only draw within the bounds of the view?
Hope some of you guys and girls can help me.
Cheers
objneodude
Solved with the following code
// Add drop shadow to the view.
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = CGRectMake(self.view.frame.size.width, 0, 30, self.view.frame.size.height);
gradientLayer.colors = [NSArray arrayWithObjects:
(id)[UIColor blackColor].CGColor,
(id)[UIColor clearColor].CGColor,
nil];
gradientLayer.startPoint = CGPointMake(-2, 0.5);
gradientLayer.endPoint = CGPointMake(1, 0.5);
[self.view.layer addSublayer:gradientLayer];
I had the same problem, after trying various ideas, I just added a subview a shadow colour (Gray) behind the UIView I needed to have a shadow, see code: (Included is the code for >3.2.x/4.x as well.
/*Shaded/rounded borders on subviews*/
self.viewOne.layer.cornerRadius = 10;
self.viewOne.layer.borderColor = [UIColor darkGrayColor].CGColor;
self.viewOne.layer.borderWidth = 0.8;
self.viewTwo.layer.cornerRadius = 10;
self.viewTwo.layer.borderColor = [UIColor darkGrayColor].CGColor;
self.viewTwo.layer.borderWidth = 0.8;
self.viewThree.layer.cornerRadius = 10;
self.viewThree.layer.borderColor = [UIColor darkGrayColor].CGColor;
self.viewThree.layer.borderWidth = 0.8;
if (SYSTEM_VERSION_LESS_THAN(#"3.2")) {
self.shadowOne.layer.cornerRadius = 10;
self.shadowTwo.layer.cornerRadius = 10;
self.shadowThree.layer.cornerRadius = 10;
}
else{
//Use QuartzCore to make shadows etc.
self.viewOne.layer.shadowColor = [[UIColor grayColor] CGColor];
self.viewOne.layer.shadowOffset = CGSizeMake(2, 2);
self.viewOne.layer.shadowOpacity = 0.6;
self.viewOne.layer.shouldRasterize = YES;
self.viewOne.layer.shadowRadius = 2;
self.viewTwo.layer.shadowColor = [[UIColor grayColor] CGColor];
self.viewTwo.layer.shadowOffset = CGSizeMake(2, 2);
self.viewTwo.layer.shadowOpacity = 0.6;
self.viewTwo.layer.shouldRasterize = YES;
self.viewTwo.layer.shadowRadius = 2;
self.viewThree.layer.shadowColor = [[UIColor grayColor] CGColor];
self.viewThree.layer.shadowOffset = CGSizeMake(2, 2);
self.viewThree.layer.shadowOpacity = 0.6;
self.viewThree.layer.shouldRasterize = YES;
self.viewThree.layer.shadowRadius = 2;
}