From 71885df10c9011500c18e2153fb492409109a80d Mon Sep 17 00:00:00 2001 From: JARinteractive Date: Mon, 22 Jul 2013 18:28:30 -0500 Subject: [PATCH] fixed bugs with hue. improved touch area of sliders. --- .../ESCColorPicker.xcodeproj/project.pbxproj | 8 +- example/ESCColorPicker/ESCColorControlThumb.m | 2 +- .../ESCColorPicker/ESCColorPicker-Info.plist | 2 +- .../ESCColorPicker/ESCColorPicker-Prefix.pch | 5 +- example/ESCColorPicker/ESCColorPickerView.m | 27 +++- example/ESCColorPicker/ESCGradientSlider.m | 2 +- example/ESCColorPicker/ESCHueWheel.h | 2 + example/ESCColorPicker/ESCHueWheel.m | 120 +++++++++++++++++- 8 files changed, 150 insertions(+), 18 deletions(-) diff --git a/example/ESCColorPicker.xcodeproj/project.pbxproj b/example/ESCColorPicker.xcodeproj/project.pbxproj index 01978cc..1d747f8 100644 --- a/example/ESCColorPicker.xcodeproj/project.pbxproj +++ b/example/ESCColorPicker.xcodeproj/project.pbxproj @@ -267,6 +267,9 @@ LastUpgradeCheck = 0500; ORGANIZATIONNAME = Escappe; TargetAttributes = { + 4DD5C9D01794EA3200BB1615 = { + DevelopmentTeam = CAFGS5263J; + }; 4DD5C9EB1794EA3200BB1615 = { TestTargetID = 4DD5C9D01794EA3200BB1615; }; @@ -408,7 +411,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: James Rantanen (5Z3434WNR8)"; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; @@ -429,6 +432,7 @@ "-all_load", "-ObjC", ); + "PROVISIONING_PROFILE[sdk=iphoneos*]" = "EBE838DE-CFC8-4C79-9DC4-FEED8E294C77"; SDKROOT = iphoneos; }; name = Debug; @@ -473,7 +477,6 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CODE_SIGN_IDENTITY = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ESCColorPicker/ESCColorPicker-Prefix.pch"; INFOPLIST_FILE = "ESCColorPicker/ESCColorPicker-Info.plist"; @@ -488,7 +491,6 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CODE_SIGN_IDENTITY = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ESCColorPicker/ESCColorPicker-Prefix.pch"; INFOPLIST_FILE = "ESCColorPicker/ESCColorPicker-Info.plist"; diff --git a/example/ESCColorPicker/ESCColorControlThumb.m b/example/ESCColorPicker/ESCColorControlThumb.m index f4e8d56..b180e1d 100644 --- a/example/ESCColorPicker/ESCColorControlThumb.m +++ b/example/ESCColorPicker/ESCColorControlThumb.m @@ -11,7 +11,7 @@ - (id)initWithFrame:(CGRect)frame { self.layer.shadowColor = [UIColor blackColor].CGColor; self.layer.shadowOpacity = 0.5; self.layer.shadowRadius = 2.0; - self.layer.shadowOffset = CGSizeMake(0.0, 1.0); + self.layer.shadowOffset = CGSizeZero; self.backgroundColor = [UIColor colorWithWhite:0.98 alpha:1.0]; } diff --git a/example/ESCColorPicker/ESCColorPicker-Info.plist b/example/ESCColorPicker/ESCColorPicker-Info.plist index 3928b46..d4890c3 100644 --- a/example/ESCColorPicker/ESCColorPicker-Info.plist +++ b/example/ESCColorPicker/ESCColorPicker-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.escappe.${PRODUCT_NAME:rfc1034identifier} + com.bwater.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/example/ESCColorPicker/ESCColorPicker-Prefix.pch b/example/ESCColorPicker/ESCColorPicker-Prefix.pch index 2f331ed..ba89bcf 100644 --- a/example/ESCColorPicker/ESCColorPicker-Prefix.pch +++ b/example/ESCColorPicker/ESCColorPicker-Prefix.pch @@ -5,6 +5,7 @@ #endif #ifdef __OBJC__ - #import - #import +#import +#import +#import #endif diff --git a/example/ESCColorPicker/ESCColorPickerView.m b/example/ESCColorPicker/ESCColorPickerView.m index c200ec6..53593fd 100644 --- a/example/ESCColorPicker/ESCColorPickerView.m +++ b/example/ESCColorPicker/ESCColorPickerView.m @@ -17,6 +17,8 @@ @implementation ESCColorPickerView - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { + self.backgroundColor = [UIColor colorWithWhite:0.1 alpha:1.0]; + [self escRegisterObserverProtocol:@protocol(ESCColorPickerViewObserver)]; self.hueWheel = [[ESCHueWheel alloc] init]; @@ -31,8 +33,8 @@ - (instancetype)initWithFrame:(CGRect)frame { [self.brightnessSlider escAddObserver:self forSelector:@selector(sliderValueDidChange:) forwardingToSelector:@selector(brightnessDidChange:)]; [self addSubview:self.brightnessSlider]; - self.colorView = [[UIView alloc] init]; - [self addSubview:self.colorView]; + //self.colorView = [[UIView alloc] init]; + //[self addSubview:self.colorView]; } return self; } @@ -41,12 +43,16 @@ - (void)layoutSubviews { [super layoutSubviews]; CGRect contentRect = CGRectInset(self.bounds, PADDING, PADDING); + CGFloat sliderHeight = 40.0; + + self.brightnessSlider.frame = CGRectMake(CGRectGetMinX(contentRect), CGRectGetMaxY(contentRect) - sliderHeight, CGRectGetWidth(contentRect), sliderHeight); + self.saturationSlider.frame = CGRectMake(CGRectGetMinX(contentRect), CGRectGetMinY(self.brightnessSlider.frame) - PADDING - sliderHeight, CGRectGetWidth(contentRect), sliderHeight); + self.colorView.frame = CGRectMake(CGRectGetMinX(self.bounds), CGRectGetMinY(contentRect), CGRectGetWidth(self.bounds), 80.0); - self.hueWheel.frame = CGRectMake(CGRectGetMinX(contentRect) + 10.0, CGRectGetMaxY(self.colorView.frame) + PADDING, CGRectGetWidth(contentRect) - 20.0, CGRectGetWidth(contentRect) - 20.0); - self.saturationSlider.frame = CGRectMake(CGRectGetMinX(contentRect), CGRectGetMaxY(self.hueWheel.frame) + PADDING, CGRectGetWidth(contentRect), 40.0); - self.brightnessSlider.frame = CGRectMake(CGRectGetMinX(contentRect), CGRectGetMaxY(self.saturationSlider.frame) + PADDING, CGRectGetWidth(contentRect), 40.0); + CGFloat hueWheelSide = CGRectGetWidth(contentRect) - 40.0; + self.hueWheel.frame = CGRectMake(CGRectGetMidX(contentRect) - hueWheelSide / 2.0, CGRectGetMinY(self.saturationSlider.frame) - PADDING - hueWheelSide, hueWheelSide, hueWheelSide); } - (void)saturationDidChange:(CGFloat)saturation { @@ -72,6 +78,17 @@ - (void)setHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)b self.colorView.backgroundColor = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1.0]; + [self.hueWheel setHue:hue saturation:saturation brightness:brightness]; +} + +- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { + UIView *hitView = [super hitTest:point withEvent:event]; + if (CGRectContainsPoint(CGRectInset(self.saturationSlider.frame, -20.0, -5.0), point)) { + hitView = self.saturationSlider; + } else if (CGRectContainsPoint(CGRectInset(self.brightnessSlider.frame, -20.0, -5.0), point)) { + hitView = self.brightnessSlider; + } + return hitView; } @end diff --git a/example/ESCColorPicker/ESCGradientSlider.m b/example/ESCColorPicker/ESCGradientSlider.m index 5e1b161..1cf5819 100644 --- a/example/ESCColorPicker/ESCGradientSlider.m +++ b/example/ESCColorPicker/ESCGradientSlider.m @@ -40,7 +40,7 @@ - (void)panGesture:(UIPanGestureRecognizer *)panGestureRecognizer { - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { CGFloat touchLocationOnThumb = [touch locationInView:self.thumb].x; - return touchLocationOnThumb > -20.0 && touchLocationOnThumb < CGRectGetMaxX(self.thumb.bounds) + 20.0; + return touchLocationOnThumb > -40.0 && touchLocationOnThumb < CGRectGetMaxX(self.thumb.bounds) + 40.0; } - (void)layoutSubviews { diff --git a/example/ESCColorPicker/ESCHueWheel.h b/example/ESCColorPicker/ESCHueWheel.h index 6cc88d1..e66006a 100644 --- a/example/ESCColorPicker/ESCHueWheel.h +++ b/example/ESCColorPicker/ESCHueWheel.h @@ -9,4 +9,6 @@ @interface ESCHueWheel : UIView +- (void)setHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness; + @end diff --git a/example/ESCColorPicker/ESCHueWheel.m b/example/ESCColorPicker/ESCHueWheel.m index b970eda..01c3835 100644 --- a/example/ESCColorPicker/ESCHueWheel.m +++ b/example/ESCColorPicker/ESCHueWheel.m @@ -1,9 +1,17 @@ #import "ESCHueWheel.h" +#import "ESCColorControlThumb.h" -@interface ESCHueWheel() +@interface ESCHueWheel() @property (nonatomic) UIView *wheel; @property (nonatomic) UIView *wheelCenter; +@property (nonatomic) UIView *wheelCenterBorder; +@property (nonatomic) NSArray *colorSwatchViews; +@property (nonatomic) UIView *thumb; +@property (nonatomic) CGFloat hue; +@property (nonatomic, readonly) CGFloat angle; + +@property (nonatomic) CGFloat relativeTouchAngle; @end @@ -11,25 +19,127 @@ @implementation ESCHueWheel - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { + [self escRegisterObserverProtocol:@protocol(ESCHueWheelObserver)]; + self.wheel = [[UIView alloc] init]; - self.wheel.backgroundColor = [UIColor colorWithWhite:0.85 alpha:1.0]; + self.wheel.backgroundColor = [UIColor colorWithWhite:0.25 alpha:1.0]; + self.wheel.clipsToBounds = YES; [self addSubview:self.wheel]; + NSInteger numberOfSwatches = 12; + NSMutableArray *colorSwatchViews = [NSMutableArray arrayWithCapacity:numberOfSwatches]; + for (NSInteger i = 0; i < numberOfSwatches; i++) { + UIView *colorSwatchView = [[UIView alloc] init]; + colorSwatchView.backgroundColor = [UIColor orangeColor]; + //colorSwatchView.layer.edgeAntialiasingMask = kCALayerBottomEdge | kCALayerLeftEdge | kCALayerRightEdge | kCALayerTopEdge; + colorSwatchView.layer.shouldRasterize = YES; + colorSwatchView.layer.rasterizationScale = [[UIScreen mainScreen] scale]; + [self.wheel addSubview:colorSwatchView]; + [colorSwatchViews addObject:colorSwatchView]; + } + self.colorSwatchViews = colorSwatchViews; + + + self.wheelCenterBorder = [[UIView alloc] init]; + self.wheelCenterBorder.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0]; + self.wheelCenterBorder.layer.shadowColor = [UIColor blackColor].CGColor; + self.wheelCenterBorder.layer.shadowOpacity = 0.5; + self.wheelCenterBorder.layer.shadowRadius = 2.0; + self.wheelCenterBorder.layer.shadowOffset = CGSizeZero; + [self addSubview:self.wheelCenterBorder]; + + self.thumb = [[UIView alloc] init]; + self.thumb.layer.borderColor = self.wheelCenterBorder.backgroundColor.CGColor; + self.thumb.layer.borderWidth = 3.0; + self.thumb.layer.shouldRasterize = YES; + self.thumb.layer.rasterizationScale = [[UIScreen mainScreen] scale]; + [self.wheelCenterBorder addSubview:self.thumb]; + self.wheelCenter = [[UIView alloc] init]; self.wheelCenter.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0]; - [self addSubview:self.wheelCenter]; + [self.wheelCenterBorder addSubview:self.wheelCenter]; + + UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)]; + panGestureRecognizer.delegate = self; + [self addGestureRecognizer:panGestureRecognizer]; } return self; } +- (void)panGesture:(UIPanGestureRecognizer *)panGestureRecognizer { + CGPoint touchLocation = [panGestureRecognizer locationInView:self.wheel]; + touchLocation.x -= CGRectGetMidX(self.wheel.bounds); + touchLocation.y -= CGRectGetMidY(self.wheel.bounds); + CGFloat touchAngle = atan(touchLocation.y / touchLocation.x); + touchAngle += touchLocation.x < 0.0 ? M_PI : 0.0; + if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { + self.relativeTouchAngle = self.angle - touchAngle; + } else if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) { + CGFloat hue = (touchAngle + self.relativeTouchAngle + M_PI_2) / (M_PI * 2); + hue = fmod(hue + 1.0, 1.0); //correct if hue is negative + self.hue = hue; + [self.escNotifier hueDidChange:self.hue]; + } +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { + return CGRectContainsPoint(CGRectInset(self.thumb.bounds, -20.0, -20.0), [touch locationInView:self.thumb]); +} + +- (void)setHue:(CGFloat)hue { + _hue = hue; + [self setNeedsLayout]; +} + +- (CGFloat)angle { + return self.hue * 2 * M_PI - M_PI_2; +} + - (void)layoutSubviews { [super layoutSubviews]; self.wheel.frame = CGRectInset(self.bounds, 5.0, 5.0); - self.wheel.layer.cornerRadius = CGRectGetWidth(self.wheel.frame) / 2.0; + CGFloat radius = CGRectGetWidth(self.wheel.frame) / 2.0; + self.wheel.layer.cornerRadius = radius; - self.wheelCenter.frame = CGRectInset(self.bounds, 35.0, 35.0); + self.wheelCenterBorder.frame = CGRectInset(self.bounds, 35.0, 35.0); + self.wheelCenterBorder.layer.cornerRadius = CGRectGetWidth(self.wheelCenterBorder.frame) / 2.0; + self.wheelCenter.frame = CGRectInset(self.wheelCenterBorder.bounds, 3.0, 3.0); self.wheelCenter.layer.cornerRadius = CGRectGetWidth(self.wheelCenter.frame) / 2.0; + + NSInteger i = 0; + CGFloat colorSwatchRadius = radius - ((radius - CGRectGetWidth(self.wheelCenter.frame) / 2.0)) / 2.0; + for (UIView *colorSwatchView in self.colorSwatchViews) { + CGFloat angle = (CGFloat)i / [self.colorSwatchViews count] * 2 * M_PI - M_PI_2; + CGFloat x = cos(angle) * colorSwatchRadius + CGRectGetMidX(self.wheel.bounds); + CGFloat y = sin(angle) * colorSwatchRadius + CGRectGetMidY(self.wheel.bounds); + colorSwatchView.center = CGPointMake(x, y); + colorSwatchView.bounds = CGRectMake(0.0, 0.0, 36.0, 10.0); + colorSwatchView.transform = CGAffineTransformMakeRotation(angle); + i++; + } + + CGFloat thumbRadius = CGRectGetWidth(self.wheelCenterBorder.frame) / 2.0 + 10.0; + CGFloat x = cos(self.angle) * thumbRadius + CGRectGetMidX(self.wheelCenterBorder.bounds); + CGFloat y = sin(self.angle) * thumbRadius + CGRectGetMidY(self.wheelCenterBorder.bounds); + self.thumb.center = CGPointMake(x, y); + self.thumb.bounds = CGRectMake(0.0, 0.0, 16.0, 64.0); + self.thumb.transform = CGAffineTransformMakeRotation(self.angle + M_PI_2); + self.thumb.layer.cornerRadius = 16.0; +} + +- (void)setHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness { + UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1.0]; + self.wheelCenter.backgroundColor = color; + self.thumb.backgroundColor = color; + + NSInteger i = 0; + for (UIView *colorSwatchView in self.colorSwatchViews) { + colorSwatchView.backgroundColor = [UIColor colorWithHue:(CGFloat)i / [self.colorSwatchViews count] saturation:saturation brightness:brightness alpha:1.0]; + i++; + } + + self.hue = hue; } @end