diff --git a/CRGradientNavigationBar/CAGradientLayer+Extension.h b/CRGradientNavigationBar/CAGradientLayer+Extension.h new file mode 100644 index 0000000..dba2b4c --- /dev/null +++ b/CRGradientNavigationBar/CAGradientLayer+Extension.h @@ -0,0 +1,15 @@ +// +// CAGradientLayer+Extension.h +// GradientNavigationBarDemo +// +// Created by Sergey Popov on 30.03.15. +// Copyright (c) 2015 Sergey Popov. All rights reserved. +// + +#import + +@interface CAGradientLayer (Extension) + +@property (nonatomic, assign) CGFloat gradientAngle; + +@end diff --git a/CRGradientNavigationBar/CAGradientLayer+Extension.m b/CRGradientNavigationBar/CAGradientLayer+Extension.m new file mode 100644 index 0000000..aa64500 --- /dev/null +++ b/CRGradientNavigationBar/CAGradientLayer+Extension.m @@ -0,0 +1,76 @@ +// +// CAGradientLayer+Extension.m +// GradientNavigationBarDemo +// +// Created by Sergey Popov on 30.03.15. +// Copyright (c) 2015 Sergey Popov. All rights reserved. +// + +#import "CAGradientLayer+Extension.h" +#import + +#define SWAP(x, y) do { typeof(x) SWAP = x; x = y; y = SWAP; } while (0) + +@implementation CAGradientLayer (Extension) + +static void *CAGradientLayerGradientAnglePropertyKey; + +- (void)setGradientAngle:(CGFloat)gradientAngle +{ + gradientAngle = fmod(gradientAngle, 360); + if (gradientAngle < 0) + gradientAngle += 360; + + CGFloat rad = gradientAngle * M_PI / 180.f; + + CGFloat xa =0, ya=0, xb=0, yb=0; + + for (int n = 0; n < 4; n++) + { + if ((-M_PI_4+M_PI*n) <= rad && rad < (M_PI_4+M_PI*n)) + { + xa = 0; + xb = 1; + ya = (1 - tan(rad))/2; + yb = 1 - ya; + + if (n % 2) { + SWAP(xa, xb); + SWAP(ya, yb); + } + + break; + } + else if ((M_PI_4+M_PI*n) <= rad && rad < (M_PI_4*3+M_PI*n)) + { + yb = 1; + ya = 0; + + // xb > xa + xb = (1/tan(rad) + 1)/2; + + if (n > 0) + { + // xb +#import "CAGradientLayer+Extension.h" @interface CRGradientNavigationBar () @@ -17,16 +18,42 @@ @interface CRGradientNavigationBar () @implementation CRGradientNavigationBar -static CGFloat const kDefaultOpacity = 0.5f; +- (instancetype)initWithCoder:(NSCoder *)coder +{ + self = [super initWithCoder:coder]; + if (self) + { + [self performInit]; + } + return self; +} -- (void)setBarTintGradientColors:(NSArray *)barTintGradientColors +- (instancetype)initWithFrame:(CGRect)frame { - // create the gradient layer - if (self.gradientLayer == nil) { - self.gradientLayer = [CAGradientLayer layer]; - self.gradientLayer.opacity = self.translucent ? kDefaultOpacity : 1.0f; + self = [super initWithFrame:frame]; + if (self) + { + [self performInit]; } - + return self; +} + +#pragma mark - Properties + +- (void)setOpacity:(CGFloat)opacity +{ + self.gradientLayer.opacity = self.translucent ? opacity : 1.0f; + _opacity = opacity; +} + +- (void)setTranslucent:(BOOL)translucent +{ + [super setTranslucent:translucent]; + self.opacity = _opacity; +} + +- (void)setBarTintGradientColors:(NSArray *)barTintGradientColors +{ NSMutableArray * colors = nil; if (barTintGradientColors != nil) { @@ -35,6 +62,7 @@ - (void)setBarTintGradientColors:(NSArray *)barTintGradientColors // determine elements in the array are colours // and add them to the colors array [barTintGradientColors enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if ([obj isKindOfClass:[UIColor class]]) { // UIColor class @@ -69,6 +97,13 @@ - (void)setBarTintGradientColors:(NSArray *)barTintGradientColors // set the graident colours to the laery self.gradientLayer.colors = colors; + _barTintGradientColors = barTintGradientColors; +} + +- (void)setGradientAngle:(CGFloat)gradientAngle +{ + self.gradientLayer.gradientAngle = gradientAngle; + _gradientAngle = gradientAngle; } #pragma mark - UIView @@ -97,4 +132,12 @@ - (void)layoutSubviews } } +#pragma mark - Private + +- (void)performInit +{ + _gradientLayer = [CAGradientLayer layer]; + self.opacity = .5f; +} + @end diff --git a/GradientNavigationBarDemo/GradientNavigationBarDemo.xcodeproj/project.pbxproj b/GradientNavigationBarDemo/GradientNavigationBarDemo.xcodeproj/project.pbxproj index 2493350..27819f8 100644 --- a/GradientNavigationBarDemo/GradientNavigationBarDemo.xcodeproj/project.pbxproj +++ b/GradientNavigationBarDemo/GradientNavigationBarDemo.xcodeproj/project.pbxproj @@ -22,6 +22,7 @@ 228F3D761814750100DB93BA /* DemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 228F3D751814750100DB93BA /* DemoViewController.m */; }; 228F3D7E1814756C00DB93BA /* CRGradientNavigationBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 228F3D7D1814756C00DB93BA /* CRGradientNavigationBar.m */; }; 22A74011181999FF008F2C92 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A74010181999FF008F2C92 /* QuartzCore.framework */; }; + 5203F5D61AC95860001331DB /* CAGradientLayer+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 5203F5D51AC95860001331DB /* CAGradientLayer+Extension.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -56,6 +57,8 @@ 228F3D7C1814756C00DB93BA /* CRGradientNavigationBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CRGradientNavigationBar.h; sourceTree = ""; }; 228F3D7D1814756C00DB93BA /* CRGradientNavigationBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CRGradientNavigationBar.m; sourceTree = ""; }; 22A74010181999FF008F2C92 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 5203F5D41AC95860001331DB /* CAGradientLayer+Extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CAGradientLayer+Extension.h"; sourceTree = ""; }; + 5203F5D51AC95860001331DB /* CAGradientLayer+Extension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CAGradientLayer+Extension.m"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -162,6 +165,8 @@ children = ( 228F3D7C1814756C00DB93BA /* CRGradientNavigationBar.h */, 228F3D7D1814756C00DB93BA /* CRGradientNavigationBar.m */, + 5203F5D41AC95860001331DB /* CAGradientLayer+Extension.h */, + 5203F5D51AC95860001331DB /* CAGradientLayer+Extension.m */, ); name = CRGradientNavigationBar; path = ../CRGradientNavigationBar; @@ -266,6 +271,7 @@ 228F3D761814750100DB93BA /* DemoViewController.m in Sources */, 228F3D56181474AE00DB93BA /* AppDelegate.m in Sources */, 228F3D52181474AE00DB93BA /* main.m in Sources */, + 5203F5D61AC95860001331DB /* CAGradientLayer+Extension.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/GradientNavigationBarDemo/GradientNavigationBarDemo/AppDelegate.m b/GradientNavigationBarDemo/GradientNavigationBarDemo/AppDelegate.m index f492d7c..4d6cf22 100644 --- a/GradientNavigationBarDemo/GradientNavigationBarDemo/AppDelegate.m +++ b/GradientNavigationBarDemo/GradientNavigationBarDemo/AppDelegate.m @@ -21,14 +21,17 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; UINavigationController *navigationController = [[UINavigationController alloc] initWithNavigationBarClass:[CRGradientNavigationBar class] toolbarClass:nil]; +// +// UIColor *firstColor = [UIColor colorWithRed:255.0f/255.0f green:42.0f/255.0f blue:104.0f/255.0f alpha:1.0f]; +// UIColor *secondColor = [UIColor colorWithRed:255.0f/255.0f green:90.0f/255.0f blue:58.0f/255.0f alpha:1.0f]; +// +// NSArray *colors = [NSArray arrayWithObjects:(id)firstColor.CGColor, (id)secondColor.CGColor, nil]; + NSArray *colors = [NSArray arrayWithObjects:(id)UIColorFromRGB(0x0000ff).CGColor, (id)UIColorFromRGB(0xff0000).CGColor, nil]; - UIColor *firstColor = [UIColor colorWithRed:255.0f/255.0f green:42.0f/255.0f blue:104.0f/255.0f alpha:1.0f]; - UIColor *secondColor = [UIColor colorWithRed:255.0f/255.0f green:90.0f/255.0f blue:58.0f/255.0f alpha:1.0f]; + [[CRGradientNavigationBar appearance] setBarTintGradientColors:colors]; - NSArray *colors = [NSArray arrayWithObjects:(id)firstColor.CGColor, (id)secondColor.CGColor, nil]; - //NSArray *colors = [NSArray arrayWithObjects:(id)UIColorFromRGB(0xf16149).CGColor, (id)UIColorFromRGB(0xf14959).CGColor, nil]; + [[CRGradientNavigationBar appearance] setGradientAngle:30]; - [[CRGradientNavigationBar appearance] setBarTintGradientColors:colors]; [[navigationController navigationBar] setTranslucent:NO]; // Remember, the default value is YES. DemoViewController *viewController = [[DemoViewController alloc] init]; diff --git a/GradientNavigationBarDemo/GradientNavigationBarDemo/DemoViewController.m b/GradientNavigationBarDemo/GradientNavigationBarDemo/DemoViewController.m index a3f8bee..d6330c0 100644 --- a/GradientNavigationBarDemo/GradientNavigationBarDemo/DemoViewController.m +++ b/GradientNavigationBarDemo/GradientNavigationBarDemo/DemoViewController.m @@ -7,10 +7,12 @@ // #import "DemoViewController.h" +#import "CRGradientNavigationBar.h" @interface DemoViewController () @property (nonatomic, strong) NSArray *items; +@property (nonatomic, strong) NSTimer *timer; @end @@ -46,6 +48,18 @@ - (void)viewDidLoad self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]}; + + self.timer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(updateGradient:) userInfo:nil repeats:YES]; +} + +- (void)updateGradient:(NSTimer *)timer +{ + static double angle = 0.f; + + CRGradientNavigationBar *bar = (CRGradientNavigationBar *)self.navigationController.navigationBar; + bar.gradientAngle = angle; + + angle+=3.f; } - (void)didReceiveMemoryWarning diff --git a/GradientNavigationBarDemo/GradientNavigationBarDemoTests/GradientNavigationBarDemoTests.m b/GradientNavigationBarDemo/GradientNavigationBarDemoTests/GradientNavigationBarDemoTests.m index aff2d71..35dcfc3 100644 --- a/GradientNavigationBarDemo/GradientNavigationBarDemoTests/GradientNavigationBarDemoTests.m +++ b/GradientNavigationBarDemo/GradientNavigationBarDemoTests/GradientNavigationBarDemoTests.m @@ -31,4 +31,79 @@ - (void)testExample XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); } +#define degreesToRadians(angleDegrees) (angleDegrees * M_PI / 180.0) +#define radiansToDegrees(angleRadians) (angleRadians * 180.0 / M_PI) +#define SWAP(x, y) do { typeof(x) SWAP = x; x = y; y = SWAP; } while (0) + +- (void)testNormalizeAngle +{ + + for (int i = 0; i < 720; i = i + 5) + { + [self printCoordinates:i]; + } + + +} + +- (void)printCoordinates:(double)angle +{ + + angle = constrainAngle(angle); + + double rad = degreesToRadians(angle); + + double xa, ya, xb, yb; + + for (int N = 0; N < 2; N++) + { + if ((-M_PI_4+M_PI*N) <= rad && rad < (M_PI_4+M_PI*N)) + { + xa = 0; + xb = 1; + ya = (1 - tan(rad))/2; + yb = 1 - ya; + + if (N > 0) { + SWAP(xa, xb); + SWAP(ya, yb); + } + + NSLog(@"First condition %d, (%f, %f) (%f, %f)", (int)angle, xa, ya, xb, yb); + + break; + } + else if ((M_PI_4+M_PI*N) <= rad && rad < (M_PI_4*3+M_PI*N)) + { + yb = 1; + ya = 0; + + // xb > xa + xb = (1/tan(rad) + 1)/2; + + if (N > 0) + { + // xb