Any way you can tint a UIView? Not the background color, but the entire UIView with all its subviews.
e.g - A UIView with an animation of a star rotating , i.e The UIView shape is constantly changing.
Eventually I created a UIView category that enables tinting of a UIView, without filling the UIView rectangle, here it is :
Takes an image representation of the UIView, then colors it in the given UIColor, this category was created to replicate a UIButton default highlight behavior, so it also comes with a method that can activate that behavior and let the category handle all touch methods.
//------------------ .h Interface file ------- //
//
// UIView UIView_Tint.h
// BabyQA
//
// Created by yogev shelly on 8/10/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
#define tintColorClassicUIButton [UIColor colorWithWhite:0.0 alpha:0.5]
@interface UIView(Tint)
//proprties should not be used, use the methods decalred bellow
@property (nonatomic,retain) UIColor* tintColor;
@property(nonatomic,retain) UIImageView* tintImageView;
@property(nonatomic,assign) BOOL tintOnTouchActive;
-(void)tintToColor:(UIColor*)color;
-(void)clearTint;
-(void)enableTintOnTouchWithColor:(UIColor*)color;
-(void)disableTintOnTouch;
-(UIImage *)imageRepresentation;
-(UIImage*)imageRepresentationWithTintColor:(UIColor*)color;
@end
//------------------ .m Implementation file ------- //
// UIView UIView_Tint.m
// BabyQA
//
// Created by yogev shelly on 8/10/12.
// Copyright (c) 2012 __MyCompanyName__. All rights not reserved - go wild!
//
#import "UIView Tint.h"
#import <objc/runtime.h>
#import <QuartzCore/QuartzCore.h>
static char const * const tintImageViewKey = "tintImageView";
static char const * const tintColorKey = "tintColorKey";
static char const * const tintOnTouchActiveKey = "tintOnTouchActive";
@implementation UIView (Tint)
@dynamic tintImageView;
@dynamic tintColor;
@dynamic tintOnTouchActive;
-(void)enableTintOnTouchWithColor:(UIColor*)color
{
self.tintColor = color;
self.tintOnTouchActive = TRUE;
}
-(void)disableTintOnTouch
{
self.tintOnTouchActive = FALSE;
}
-(void)tintToColor:(UIColor*)color
{
if(![self.tintColor isEqual:color] || !self.tintImageView)
{
self.tintColor = color;
UIImage* tintImage = [self imageRepresentationWithTintColor:self.tintColor];
self.tintImageView = [[[UIImageView alloc] initWithImage:tintImage] autorelease];
}
[self addSubview:self.tintImageView];
}
-(void)clearTint
{
[self.tintImageView removeFromSuperview];
}
-(void)clearTintWithSecondsDelay:(float)delay
{
[self performSelector:@selector(clearTint) withObject:self afterDelay:delay];
}
#pragma mark - TouchToggling
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
if(self.tintOnTouchActive)
[self tintToColor:self.tintColor];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
if(self.tintOnTouchActive)
[self clearTintWithSecondsDelay:0.05];
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
if(self.tintOnTouchActive)
[self clearTintWithSecondsDelay:0.05];
}
#pragma mark - TintingPart
-(UIImage *)imageRepresentation
{
UIGraphicsBeginImageContext(self.bounds.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
-(UIImage*)imageRepresentationWithTintColor:(UIColor*)color
{
UIImage* viewImage = [self imageRepresentation];
viewImage = [self tintedImage:viewImage UsingColor:color];
return viewImage;
}
-(UIImage *)tintedImage:(UIImage*)image UsingColor:(UIColor *)tintColor {
UIGraphicsBeginImageContextWithOptions(image.size, NO, [[UIScreen mainScreen] scale]);
CGRect drawRect = CGRectMake(0, 0, image.size.width, image.size.height);
[image drawInRect:drawRect];
[tintColor set];
UIRectFillUsingBlendMode(drawRect, kCGBlendModeSourceAtop);
UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return tintedImage;
}
#pragma mark - Dynamic setters/getters for Associative References
-(void)setTintImageView:(UIImageView *)tintImageView
{
objc_setAssociatedObject(self, tintImageViewKey, tintImageView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIImageView*)tintImageView
{
return objc_getAssociatedObject(self , tintImageViewKey);
}
-(UIColor*)tintColor
{
return objc_getAssociatedObject(self , tintColorKey);
}
-(void)setTintColor:(UIColor *)tintColor
{
objc_setAssociatedObject(self, tintColorKey, tintColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(BOOL)tintOnTouchActive
{
return [objc_getAssociatedObject(self, tintOnTouchActiveKey) boolValue];
}
-(void)setTintOnTouchActive:(BOOL)tintOnTouchActive
{
objc_setAssociatedObject(self, tintOnTouchActiveKey, [NSNumber numberWithBool:tintOnTouchActive], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
To tint a UIView
, add another subview on top of it with the same frame
and an alpha transparency set.
For example let's say your container type view is called containerView
, you'd do as follows:
CGRect overlayFrame = containerView.frame;
UIView *overlayView = [UIView alloc] initWithFrame:overlayFrame];
overlayView.alpha = 0.5f;
overlayView.color = [UIColor blackColor];
[containerView addSubview:overlayView];
This gives you a semi transparent (0.5f) black tint that will give a tint like appearance to all the subviews underneath.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With