From 5d1c7916979b2b0a28797376d4872c1bbdf69323 Mon Sep 17 00:00:00 2001 From: Eric Rolf Date: Fri, 11 Jan 2013 07:33:29 -0500 Subject: [PATCH 1/6] Updated Example for Tinted Background. --- GIKPopoverBackgroundView-Example/GIKViewController.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/GIKPopoverBackgroundView-Example/GIKViewController.m b/GIKPopoverBackgroundView-Example/GIKViewController.m index b8b3a5f..312c2a2 100644 --- a/GIKPopoverBackgroundView-Example/GIKViewController.m +++ b/GIKPopoverBackgroundView-Example/GIKViewController.m @@ -36,7 +36,8 @@ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { segueIdentifier = segue.identifier; popoverController = [(UIStoryboardPopoverSegue *)segue popoverController]; - popoverController.popoverBackgroundViewClass = [GIKPopoverBackgroundView class]; +// popoverController.popoverBackgroundViewClass = [GIKPopoverBackgroundView class]; + popoverController.popoverBackgroundViewClass = [GIKPopoverBackgroundView classWithTintColor:[UIColor redColor]]; if ([segue.identifier isEqualToString:@"popover2"]) { @@ -49,9 +50,9 @@ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender - (void)applyTitleTextAttributesToNavigationBar:(UINavigationBar *)navBar { NSDictionary *attributes = @{ UITextAttributeTextColor : [UIColor colorWithRed:122.0/255.0 green:120.0/255.0 blue:114.0/255.0 alpha:1.0], - UITextAttributeTextShadowColor : [UIColor whiteColor], - UITextAttributeTextShadowOffset : [NSValue valueWithCGSize:(CGSize){ .width = 0.0, .height = 1.0}] }; - + UITextAttributeTextShadowColor : [UIColor whiteColor], + UITextAttributeTextShadowOffset : [NSValue valueWithCGSize:(CGSize){ .width = 0.0, .height = 1.0}] }; + [navBar setTitleTextAttributes:attributes]; } From f7243818df5099ee8e7c13d006b221d0b22deb01 Mon Sep 17 00:00:00 2001 From: Eric Rolf Date: Fri, 11 Jan 2013 07:34:10 -0500 Subject: [PATCH 2/6] Updated BackgroundViewClass to support tinting of the standard images included. --- .../GIKPopoverBackgroundView.h | 3 +- .../GIKPopoverBackgroundView.m | 45 ++++++++++++++++--- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/GIKPopoverBackgroundView/GIKPopoverBackgroundView.h b/GIKPopoverBackgroundView/GIKPopoverBackgroundView.h index 211bdb0..b461371 100644 --- a/GIKPopoverBackgroundView/GIKPopoverBackgroundView.h +++ b/GIKPopoverBackgroundView/GIKPopoverBackgroundView.h @@ -12,7 +12,7 @@ // Layout of images will be handled automatically, and it works with all values of UIPopoverArrowDirection. #import - +#import /** Image-specific values for calulating the background's layout. */ @@ -60,6 +60,7 @@ static const CGFloat kSecondHalfRightInset = 9.0; // Value for .right i @property (nonatomic, assign) CGFloat arrowOffset; @property (nonatomic, assign) UIPopoverArrowDirection arrowDirection; ++ (id)classWithTintColor:(UIColor*)color; + (CGFloat)arrowHeight; + (CGFloat)arrowBase; + (UIEdgeInsets)contentViewInsets; diff --git a/GIKPopoverBackgroundView/GIKPopoverBackgroundView.m b/GIKPopoverBackgroundView/GIKPopoverBackgroundView.m index ebbc93a..55131d1 100644 --- a/GIKPopoverBackgroundView/GIKPopoverBackgroundView.m +++ b/GIKPopoverBackgroundView/GIKPopoverBackgroundView.m @@ -6,7 +6,6 @@ // #import "GIKPopoverBackgroundView.h" -#import // A struct containing the min and max horizontal and vertical positions for the popover arrow. If the arrow's position exceeds these limits, the PopoverBackgroundArrow[UpRight|DownRight|SideTop|SideBottom].png images are drawn. struct GIKPopoverExtents { @@ -27,6 +26,7 @@ @interface GIKPopoverBackgroundView () { @end +static UIColor *tintColor = nil; @implementation GIKPopoverBackgroundView @@ -36,6 +36,15 @@ @implementation GIKPopoverBackgroundView #pragma mark - UIPopoverBackgroundView required values ++ (id)classWithTintColor:(UIColor*)color +{ + Class class = [super class]; + if (class) { + tintColor = color; + } + return class; +} + + (UIEdgeInsets)contentViewInsets { return kPopoverEdgeInsets; @@ -119,7 +128,7 @@ - (void)addDropShadowIfNecessary - (void)layoutSubviews { [super layoutSubviews]; - + _popoverExtents = (GIKPopoverExtents){ .left = CGRectGetMinX(self.bounds) + kPopoverCornerRadius, .right = CGRectGetMaxX(self.bounds) - kPopoverCornerRadius, @@ -134,7 +143,7 @@ - (void)layoutSubviews self.popoverBackground.center = self.center; self.popoverBackground.bounds = self.bounds; - self.popoverBackground.image = [self wantsUpOrDownArrow] ? [self upOrDownArrowImage] : [self sideArrowImage]; + self.popoverBackground.image = [self wantsUpOrDownArrow] ? [self upOrDownArrowImage] : [self sideArrowImage]; } @@ -220,7 +229,7 @@ - (BOOL)isArrowAtBottomEdgeOfPopover { return (_arrowCenter + _halfBase > _popov - (void)adjustCentersIfNecessary { - // fix centers of left-pointing popovers so that their shadows are drawn correctly. + // fix centers of left-pointing popovers so that their shadows are drawn correctly. if (self.arrowDirection == UIPopoverArrowDirectionLeft) { self.center = (CGPoint){ .x = self.center.x + [GIKPopoverBackgroundView arrowHeight], .y = self.center.y }; @@ -233,13 +242,13 @@ - (void)adjustCentersIfNecessary - (UIImage *)stretchableImageNamed:(NSString *)name insets:(UIEdgeInsets)insets mirrored:(BOOL)mirrored { - UIImage *image = [UIImage imageNamed:name]; + UIImage *image = (tintColor) ? [self tintedImage:[UIImage imageNamed:name] usingColor:tintColor] : [UIImage imageNamed:name]; return (mirrored) ? [[self mirroredImage:image] resizableImageWithCapInsets:[self mirroredInsets:insets]] : [image resizableImageWithCapInsets:insets]; } - (UIImage *)twoPartStretchableImageNamed:(NSString *)name insets:(UIEdgeInsets)insets { - UIImage *image = [UIImage imageNamed:name]; + UIImage *image = (tintColor) ? [self tintedImage:[UIImage imageNamed:name] usingColor:tintColor] : [UIImage imageNamed:name]; if (self.arrowDirection == UIPopoverArrowDirectionLeft) { @@ -300,4 +309,28 @@ - (UIImage *)imageFromImageContextWithSourceImage:(UIImage *)image size:(CGSize) return result; } +- (UIImage *)tintedImage:(UIImage*)image usingColor:(UIColor *)tintColor; +{ + UIGraphicsBeginImageContextWithOptions(image.size, NO, 1.0); + CGContextRef context = UIGraphicsGetCurrentContext(); + CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); + + // draw original image + [image drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0f]; + + // tint image (loosing alpha). + // kCGBlendModeOverlay is the closest I was able to match the + // actual process used by apple in navigation bar + CGContextSetBlendMode(context, kCGBlendModeMultiply); + [tintColor setFill]; + CGContextFillRect(context, rect); + + // mask by alpha values of original image + [image drawInRect:rect blendMode:kCGBlendModeDestinationIn alpha:1.0f]; + + UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return tintedImage; +} + @end From 340190da89a78be6e6be8acd7214772fc0ea4463 Mon Sep 17 00:00:00 2001 From: Eric Rolf Date: Fri, 11 Jan 2013 07:45:15 -0500 Subject: [PATCH 3/6] Added explanation for using BlendModeMultiply over BlendModeOverlay. --- GIKPopoverBackgroundView/GIKPopoverBackgroundView.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/GIKPopoverBackgroundView/GIKPopoverBackgroundView.m b/GIKPopoverBackgroundView/GIKPopoverBackgroundView.m index 55131d1..0e51196 100644 --- a/GIKPopoverBackgroundView/GIKPopoverBackgroundView.m +++ b/GIKPopoverBackgroundView/GIKPopoverBackgroundView.m @@ -321,6 +321,9 @@ - (UIImage *)tintedImage:(UIImage*)image usingColor:(UIColor *)tintColor; // tint image (loosing alpha). // kCGBlendModeOverlay is the closest I was able to match the // actual process used by apple in navigation bar + // kCGBlendModeMultiply is used currently because it provides + // the best replacement of image. The overlay mode will create + // just that an overlay, the color will seem washed out. CGContextSetBlendMode(context, kCGBlendModeMultiply); [tintColor setFill]; CGContextFillRect(context, rect); From 63230b90014ddb23986e520ee0fa61244d25bc80 Mon Sep 17 00:00:00 2001 From: Eric Rolf Date: Fri, 11 Jan 2013 07:50:07 -0500 Subject: [PATCH 4/6] Updated ReadMe --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/README.md b/README.md index fe831ec..de3a3ad 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,40 @@ The documentation for `UIPopoverBackgroundView` states that `-setArrowOffset:` i } ``` +### Tint support + +PopoverControls have historically never supported tinting of the view. This fork contains the ability to use the tint function added. + +Tinting was achieved by adding a method to modify the images that are included on the fly. + +``` objective-c +- (UIImage *)tintedImage:(UIImage*)image usingColor:(UIColor *)tintColor; +{ + UIGraphicsBeginImageContextWithOptions(image.size, NO, 1.0); + CGContextRef context = UIGraphicsGetCurrentContext(); + CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); + + // draw original image + [image drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0f]; + + // tint image (loosing alpha). + // kCGBlendModeOverlay is the closest I was able to match the + // actual process used by apple in navigation bar + CGContextSetBlendMode(context, kCGBlendModeMultiply); + [tintColor setFill]; + CGContextFillRect(context, rect); + + // mask by alpha values of original image + [image drawInRect:rect blendMode:kCGBlendModeDestinationIn alpha:1.0f]; + + UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return tintedImage; +} +``` + +From the method above we can see that we are modifying the image by setting the blend mode of the image to multiply for a better color replacement. Overlay mode is included but commented out because it creates a more washed out image. + ## Usage To use, add GIKPopoverBackgroundView.h and GIKPopoverBackgroundView.m to your Xcode project. Feel free to use the supplied images (found in the example project) and their default `UIEdgeInsets` values. In the view controller which manages your popover controller, set the popover controller's `popoverBackgroundViewClass` property: @@ -84,9 +118,23 @@ popoverController = [(UIStoryboardPopoverSegue *)segue popoverController]; popoverController.popoverBackgroundViewClass = [GIKPopoverBackgroundView class]; ``` +to use the tint option, add GIKPopoverBackgroundView.h and .m as you would before. + +``` objective-c +popoverController = [(UIStoryboardPopoverSegue *)segue popoverController]; +popoverController.popoverBackgroundViewClass = [GIKPopoverBackgroundView classWithTintColor:(UIColor*)]; +``` + ## Sample Project The included sample project covers a number of scenarios where source images are stretched twice, mirrored, and animated in response to keyboard appearance. +The original images can be seen by uncommenting the line in the GIKViewController.m + +```objective-c +popoverController.popoverBackgroundViewClass = [GIKPopoverBackgroundView class]; +``` + + ## Requirements @@ -107,6 +155,10 @@ GIKPopoverBackgroundView was created by [Gordon Hughes](https://github.com/gik/) [@gordonhughes](http://twitter.com/gordonhughes) +[Eric Rolf](https://github.com/koolstar/) + +[@Eric_Rolf](https://twitter.com/eric_rolf) + ## License GIKPopoverBackgroundView is available under the MIT license. See the LICENSE file for more information. From a3bd31068136d33c252cb84acedf6d01466c15be Mon Sep 17 00:00:00 2001 From: Eric Rolf Date: Fri, 11 Jan 2013 07:51:03 -0500 Subject: [PATCH 5/6] Updated ReadMe --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index de3a3ad..08bc1f3 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,8 @@ GIKPopoverBackgroundView uses ARC and requires iOS 5.0 or above. GIKPopoverBackgroundView was created by [Gordon Hughes](https://github.com/gik/). +Tint Support Added By [Eric Rolf](https://github.com/koolstar/). + ## Contact [Gordon Hughes](https://github.com/gik/) From ea6ba27f2e87bc4386ce6c85f7cb5e4c782270f9 Mon Sep 17 00:00:00 2001 From: Eric Rolf Date: Fri, 11 Jan 2013 08:06:55 -0500 Subject: [PATCH 6/6] Updated ReadMe --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 08bc1f3..d61a3de 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ GIKPopoverBackgroundView uses ARC and requires iOS 5.0 or above. GIKPopoverBackgroundView was created by [Gordon Hughes](https://github.com/gik/). -Tint Support Added By [Eric Rolf](https://github.com/koolstar/). +Tint Support Added By [Eric Rolf](https://github.com/xrolfex/). ## Contact @@ -157,7 +157,7 @@ Tint Support Added By [Eric Rolf](https://github.com/koolstar/). [@gordonhughes](http://twitter.com/gordonhughes) -[Eric Rolf](https://github.com/koolstar/) +[Eric Rolf](https://github.com/xrolfex/) [@Eric_Rolf](https://twitter.com/eric_rolf)