Permalink
Browse files

Minor updates. Also reverted the Lissajous example back to using CADi…

…splayLink because of flickering problems
  • Loading branch information...
1 parent 590dc01 commit 3442c075a37d05b10278385a6e145b2069fbad28 Brian Coyner committed Mar 24, 2012
View
@@ -1,6 +1,7 @@
.DS_Store
profile
-
+.idea
+build
*.mode1
*.mode1v3
@@ -390,6 +390,8 @@
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_OBJCPP_ARC_ABI = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
@@ -401,9 +403,16 @@
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
+ GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
+ GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
+ GCC_WARN_SHADOW = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
@@ -418,13 +427,22 @@
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_OBJCPP_ARC_ABI = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
+ GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
+ GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
+ GCC_WARN_SHADOW = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
@@ -42,10 +42,10 @@ - (void)drawInContext:(CGContextRef)context
CGRect bounds = [self bounds];
CGPoint center = {CGRectGetMidX(bounds), CGRectGetMidY(bounds)};
- int strokeWidth = 2;
+ CGFloat strokeWidth = 2.0;
CGMutablePathRef path = CGPathCreateMutable();
- CGPathAddArc(path, NULL, center.x, center.y, bounds.size.width / 2 - strokeWidth, 0.0, M_PI * 2, 0);
+ CGPathAddArc(path, NULL, center.x, center.y, bounds.size.width / 2 - strokeWidth, 0.0, (CGFloat) (M_PI * 2.0), 0);
CGContextAddPath(context, path);
CGContextSetFillColorWithColor(context, [[UIColor redColor] colorWithAlphaComponent:0.5].CGColor);
@@ -9,9 +9,7 @@
#import "BTSBasicLayerPropertiesViewController.h"
#import "BTSAnchorPointLayer.h"
-#import <QuartzCore/QuartzCore.h>
-
-// This view controller shows how various Core Animation CALayer properties implicitly animate.
+// This view controller shows how various Core Animation CALayer properties implicitly animate.
// - position, corner radius, border, color, size, etc.
@interface BTSBasicLayerPropertiesViewController() {
@@ -23,8 +21,6 @@ @interface BTSBasicLayerPropertiesViewController() {
}
@property (strong, nonatomic) IBOutlet UILabel *animationDurationLabel;
-
-- (IBAction)animationDurationChanged:(id)sender;
@end
@@ -53,7 +49,7 @@ - (void)viewDidLoad
_layer = [CALayer layer];
[_layer setContentsScale:[[UIScreen mainScreen] scale]];
[_layer setBackgroundColor:[UIColor blueColor].CGColor];
- [_layer setBounds:CGRectMake(0, 0, 200, 200)];
+ [_layer setBounds:CGRectMake(0.0, 0.0, 200.0, 200.0)];
CGPoint anchorPoint = {0.5, 0.0};
[_layer setAnchorPoint:anchorPoint];
@@ -69,10 +65,10 @@ - (void)viewDidLoad
// Because the CALayer anchor point is {0.5,0.0}, we can simply set X to the center of the width.
// This centers the layer on the X axis.
- CGFloat x = frame.size.width / 2;
+ CGFloat x = frame.size.width / 2.0;
// Position the layer 10 points from the top of the view.
- CGFloat y = 10;
+ CGFloat y = 10.0;
[_layer setPosition:CGPointMake(x, y)];
[[[self view] layer] addSublayer:_layer];
@@ -135,7 +131,7 @@ - (IBAction)toggleSize:(id)sender
[CATransaction setAnimationDuration:_animationDuration];
CGRect layerBounds = _layer.bounds;
- layerBounds.size.width = (layerBounds.size.width == layerBounds.size.height) ? 250 : 200;
+ layerBounds.size.width = (layerBounds.size.width == layerBounds.size.height) ? 250.0 : 200.0;
[_layer setBounds:layerBounds];
BTSAnchorPointLayer *anchorPointLayer = [[_layer sublayers] objectAtIndex:0];
@@ -20,8 +20,6 @@ @interface BTSBezierPathViewController() {
CALayer *_layer;
}
-- (void)updateAnimationForPath:(CGPathRef)path;
-
@end
@implementation BTSBezierPathViewController
@@ -35,8 +33,8 @@ - (void)viewDidLoad
// This is the layer that will animate along the path when the user presses the "animateButton".
_layer = [CALayer layer];
[_layer setContentsScale:[[UIScreen mainScreen] scale]];
- [_layer setContents:(id)[UIImage imageNamed:@"american-flag.png"].CGImage];
- [_layer setBounds:CGRectMake(0, 0, 60, 60)];
+ [_layer setContents:(__bridge id)[UIImage imageNamed:@"american-flag.png"].CGImage];
+ [_layer setBounds:CGRectMake(0.0, 0.0, 60.0, 60.0)];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
@@ -2,6 +2,8 @@
// Copyright (c) 2011 Brian Coyner. All rights reserved.
//
+#import <CoreGraphics/CoreGraphics.h>
+#import <stdio.h>
#import "BTSCoreGraphics.h"
static void BTSPrintCurrentCTM(CGContextRef context)
@@ -46,8 +46,6 @@ @interface BTSCubicBezierPathView() {
CGPathRef BTSPathCreateForCurrentControlPointPositions(CALayer *beginPointLayer, CALayer *endPointLayer, CALayer *beginPointControlPointLayer, CALayer *endPointControlPointLayer);
-- (void)initLayers;
-
@end
@implementation BTSCubicBezierPathView
@@ -100,7 +98,7 @@ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
// to pick up and move a control point layer.
CGRect hitTestRect = [layer convertRect:[layer bounds] toLayer:[layer superlayer]];
- CGRect hitBounds = CGRectInset(hitTestRect, -20, -20);
+ CGRect hitBounds = CGRectInset(hitTestRect, -20.0, -20.0);
if (CGRectContainsPoint(hitBounds, touchLocationInView)) {
CFDictionarySetValue(_touchesToLayers, (__bridge CFTypeRef)touch, (__bridge CFTypeRef)layer);
@@ -132,7 +130,12 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
CGPoint locationInView = [currentTouch locationInView:self];
CGPoint offsetFromCenter = [(NSValue *)[layerToMove valueForKey:kBTSCubicBezierPathLocationOffset] CGPointValue];
- CGPoint newPosition = CGPointMake(MIN(width, MAX(0, locationInView.x + offsetFromCenter.x)), MIN(height, MAX(0, locationInView.y + offsetFromCenter.y)));
+ CGFloat x = MAX(0, locationInView.x + offsetFromCenter.x);
+ x = MIN(width, x);
+
+ CGFloat y = MAX(0, locationInView.y + offsetFromCenter.y);
+ y = MIN(height, y);
+ CGPoint newPosition = CGPointMake(x, y);
[layerToMove setPosition:newPosition];
}
@@ -170,16 +173,16 @@ - (void)initLayers
CGFloat midY = CGRectGetMidY([self bounds]);
_beginPointLayer = [BTSEndPointLayer layer];
- [_beginPointLayer setPosition:CGPointMake(midX, 40)];
+ [_beginPointLayer setPosition:CGPointMake(midX, 40.0)];
_endPointLayer = [BTSEndPointLayer layer];
- [_endPointLayer setPosition:CGPointMake(midX, [self bounds].size.height - 40)];
+ [_endPointLayer setPosition:CGPointMake(midX, [self bounds].size.height - 40.0)];
_beginPointControlPointLayer = [BTSControlPointLayer layer];
- [_beginPointControlPointLayer setPosition:CGPointMake(40, midY)];
+ [_beginPointControlPointLayer setPosition:CGPointMake(40.0, midY)];
_endPointControlPointLayer = [BTSControlPointLayer layer];
- [_endPointControlPointLayer setPosition:CGPointMake([self bounds].size.width - 40, midY)];
+ [_endPointControlPointLayer setPosition:CGPointMake([self bounds].size.width - 40.0, midY)];
// create the initial path
CGPathRef path = BTSPathCreateForCurrentControlPointPositions(_beginPointLayer, _endPointLayer, _beginPointControlPointLayer, _endPointControlPointLayer);
@@ -208,7 +211,6 @@ CGPathRef BTSPathCreateForCurrentControlPointPositions(CALayer *beginPointLayer,
CGPathMoveToPoint(path, NULL, [beginPointLayer position].x, [beginPointLayer position].y);
CGPathAddCurveToPoint(path, NULL, [beginPointControlPointLayer position].x, [beginPointControlPointLayer position].y, [endPointControlPointLayer position].x, [endPointControlPointLayer position].y, [endPointLayer position].x, [endPointLayer position].y);
return path;
-
}
@end
@@ -222,7 +224,7 @@ - (id)init
{
self = [super init];
if (self) {
- [self setBounds:CGRectMake(0, 0, 20, 20)];
+ [self setBounds:CGRectMake(0.0, 0.0, 20.0, 20.0)];
[self setContentsScale:[[UIScreen mainScreen] scale]];
[self setNeedsDisplay];
}
@@ -237,14 +239,14 @@ - (void)drawInContext:(CGContextRef)context
CGFloat centerX = CGRectGetMidX([self bounds]);
CGFloat centerY = CGRectGetMidY([self bounds]);
- CGFloat radius = MIN(CGRectGetWidth([self bounds]) / 2, CGRectGetHeight([self bounds]) / 2) - 2;
+ CGFloat radius = MIN(CGRectGetWidth([self bounds]) / 2.0, CGRectGetHeight([self bounds]) / 2.0) - 2.0;
- CGContextAddArc(context, centerX, centerY, radius, 0.0, M_PI * 2, 0);
+ CGContextAddArc(context, centerX, centerY, radius, 0.0, (CGFloat) (M_PI * 2.0), 0);
CGContextFillPath(context);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
- CGContextAddArc(context, centerX, centerY, radius, 0.0, M_PI * 2, 0);
- CGContextSetLineWidth(context, 2);
+ CGContextAddArc(context, centerX, centerY, radius, 0.0, (CGFloat) (M_PI * 2.0), 0);
+ CGContextSetLineWidth(context, 2.0);
CGContextStrokePath(context);
}
@@ -256,7 +258,7 @@ - (id)init
{
self = [super init];
if (self) {
- [self setBounds:CGRectMake(0, 0, 30, 20)];
+ [self setBounds:CGRectMake(0.0, 0.0, 30.0, 20.0)];
[self setContentsScale:[[UIScreen mainScreen] scale]];
[self setNeedsDisplay];
}
@@ -271,14 +273,14 @@ - (void)drawInContext:(CGContextRef)context
CGFloat centerX = CGRectGetMidX([self bounds]);
CGFloat centerY = CGRectGetMidY([self bounds]);
- CGFloat radius = MIN(CGRectGetWidth([self bounds]) / 2, CGRectGetHeight([self bounds]) / 2) - 2;
+ CGFloat radius = MIN(CGRectGetWidth([self bounds]) / 2.0, CGRectGetHeight([self bounds]) / 2.0) - 2.0;
- CGContextAddArc(context, centerX, centerY, radius, 0.0, M_PI * 2, 0);
+ CGContextAddArc(context, centerX, centerY, radius, 0.0, (CGFloat) (M_PI * 2.0), 0);
CGContextFillPath(context);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
- CGContextAddArc(context, centerX, centerY, radius, 0.0, M_PI * 2, 0);
- CGContextSetLineWidth(context, 2);
+ CGContextAddArc(context, centerX, centerY, radius, 0.0, (CGFloat) (M_PI * 2.0), 0);
+ CGContextSetLineWidth(context, 2.0);
CGContextStrokePath(context);
}
@@ -8,16 +8,18 @@
#import "BTSLissajousLayer.h"
-#import <QuartzCore/QuartzCore.h>
-
static NSString* const kBTSLissajouseLayerAmplitude = @"amplitude";
static NSString* const kBTSLissajouseLayerA = @"a";
static NSString* const kBTSLissajouseLayerB = @"b";
static NSString* const kBTSLissajouseLayerDelta = @"delta";
-static const CGFloat TWO_PI = M_PI * 2.0f;
+static const CGFloat TWO_PI = (CGFloat) (M_PI * 2.0f);
+
+// NOTE: Sometimes the 'needsDisplayForKey:' (as described in 'BTSSineWaveLayer.m') can produce undesired 'flickering' effects.
+// I have yet to see any undesired 'flickering' effects using the CADisplayLink approach.
@interface BTSLissajousLayer() {
+ CADisplayLink *_displayLink;
NSMutableArray *_currentAnimations;
}
@end
@@ -29,7 +31,7 @@ @implementation BTSLissajousLayer
@dynamic b;
@dynamic delta;
-+ (NSSet *)keyPathsForCustomDisplayDrawing
++ (NSSet *)keyPathsForDynamicProperties
{
static NSSet *keys = nil;
if (keys == nil) {
@@ -38,11 +40,6 @@ + (NSSet *)keyPathsForCustomDisplayDrawing
return keys;
}
-+ (BOOL)needsDisplayForKey:(NSString *)key
-{
- return [[self keyPathsForCustomDisplayDrawing] containsObject:key];
-}
-
#pragma mark - Layer Drawing
- (id)init {
@@ -101,7 +98,7 @@ - (void)drawInContext:(CGContextRef)context
{
// Called when a property changes.
- if ([[BTSLissajousLayer keyPathsForCustomDisplayDrawing] member:event]) {
+ if ([[BTSLissajousLayer keyPathsForDynamicProperties] member:event]) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:event];
NSValue *valueForKey = [[self presentationLayer] valueForKey:event];
@@ -117,4 +114,41 @@ - (void)drawInContext:(CGContextRef)context
}
}
+#pragma mark - Animation Delegate Callbacks
+
+- (void)animationDidStart:(CAAnimation *)anim
+{
+ if ([anim isKindOfClass:[CAPropertyAnimation class]]) {
+ NSSet *internalKeys = [BTSLissajousLayer keyPathsForDynamicProperties];
+ if ([internalKeys member:[(CAPropertyAnimation *)anim keyPath]]) {
+
+ [_currentAnimations addObject:anim];
+ if (_displayLink == nil) {
+ _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animationTimerFired:)];
+ [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
+ }
+ }
+ }
+}
+
+- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag
+{
+ [_currentAnimations removeObject:animation];
+ if ([_currentAnimations count] == 0) {
+ [_displayLink invalidate];
+ _displayLink = nil;
+
+ // hmmm... the use of CADisplayLink seems to miss the final set of interpolated values... let's force a final paint.
+ // note... this was not necessary when using an explicit NSTimer (need to investigate more).
+ [self setNeedsDisplay];
+ }
+}
+
+#pragma mark - Timer Callback
+
+- (void)animationTimerFired:(CADisplayLink *)displayLink
+{
+ [self setNeedsDisplay];
+}
+
@end
Oops, something went wrong.

0 comments on commit 3442c07

Please sign in to comment.