Reputation: 303
In my iOS App I want to create the equivalent of a UILabel that can be highlighted in such a way as to briefly draw attention to itself. So I want it to change its color from blue to red at the same time as it pulsates. So I increase and then decrease the fontSize by say 20%, as a consequence I also need to change the AnchorPoint so that it appears to expand outwards equally in all directions from the centre. I have managed to write code that achieves all these goals, only if it executes as I create the object. However, when I call it via an IBAction by pressing a button the colorChange and fontSizeChange have no effect, whilst the anchorPointChange continues to work. I have no idea what I am doing wrong, though the reason for my problem might well be blindingly obvious, I have failed to spot it. I have tried various incarnations of the code, subclassing UIView and using CALayer classes, but to provide a concise example, here I have packaged it all into viewDidLoad.
Any help would be most appreciated.
OSX Yosemite Version 10.10 (14A389), Xcode Version 6.1 (6A1052d), iOS Simulator Version 8.1 (550.3)
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) CATextLayer *textLayer;
@end
@implementation ViewController
@synthesize textLayer;
float animationDuration;
- (void)viewDidLoad {
[super viewDidLoad];
textLayer = [CATextLayer layer];
[textLayer setString: @"AB"];
[textLayer setForegroundColor: [UIColor blueColor].CGColor];
[textLayer setFontSize: 50.0];
[textLayer setAlignmentMode: kCAAlignmentCenter];
[textLayer setFrame: CGRectMake(100, 150, 100, 60)];
[textLayer setPosition: CGPointMake(CGRectGetMidX(textLayer.frame), CGRectGetMidY(textLayer.frame))];
[textLayer setAnchorPoint: CGPointMake(0.5, 0.5)];
[[self.view layer] addSublayer:textLayer];
UIButton *activationButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
activationButton.backgroundColor = [UIColor lightGrayColor];
activationButton.frame = CGRectMake(130.0, 250.0, 150.0, 30.0);
[activationButton setTitle:@"Highlight Label" forState:UIControlStateNormal];
[activationButton addTarget:self action:@selector(highlightLabel:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:activationButton];
animationDuration = 2.0;
// [self changeColor]; // all three methods work perfectly, if called here
// [self changeFontSize: 50.0 scale: 1.2];
// [self changeAnchorPointFrom: CGPointMake(0.5, 0.5) to: CGPointMake(0.5, 0.6)];
/* [self highlightLabel: nil]; */
}
- (IBAction) highlightLabel: (UIButton *) sender {
NSLog(@" textLayer.string: %@", textLayer.string);
[self changeColor]; // Has no effect
[self changeFontSize: 50.0 scale: 1.2]; // Has no effect
[self changeAnchorPointFrom: CGPointMake(0.5, 0.5) to: CGPointMake(0.5, 0.6)]; // Only this method call works
}
- (void)changeFontSize: (float) fontSize scale: (float)factor
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"fontSize"];
animation.duration = animationDuration;
animation.removedOnCompletion = NO;
animation.autoreverses = YES;
animation.fromValue = @(fontSize);
animation.toValue = @(fontSize * factor);
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[textLayer addAnimation:animation forKey:@"fontSizeAnimation"];
}
- (void)changeAnchorPointFrom: (CGPoint) startPoint to: (CGPoint)endPoint
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"anchorPoint"];
animation.duration = animationDuration;
animation.removedOnCompletion = NO;
animation.autoreverses = YES;
animation.fromValue = [NSValue valueWithCGPoint:startPoint];
animation.toValue = [NSValue valueWithCGPoint:endPoint];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[textLayer addAnimation:animation forKey:@"anchorPointAnimation"];
}
- (void)changeColor
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"foregroundColor"];
animation.duration = animationDuration * 2;
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
animation.fromValue = (id)[UIColor blueColor].CGColor;
animation.toValue = (id)[UIColor redColor].CGColor;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[textLayer addAnimation:animation forKey:@"colorAnimation"];
}
@end
Upvotes: 2
Views: 1094
Reputation: 13766
You need to set the final color of the textlayer, try to add this in the end of your highlightLabel
method.
[CATransaction begin];
[CATransaction setDisableActions:YES];
[textLayer setForegroundColor: [UIColor redColor].CGColor];
[CATransaction commit];
Upvotes: 2