Thursday, May 19, 2011

UIImage and UIColor

I just got asked a question about setting the background of a UISearchBar to an image. Something like this:
When using an image as a repeating pattern, for a background on a view, for instance, check out
+ (UIColor *)colorWithPatternImage:(UIImage *)image
The resulting UIColor is similar to a graphics engine or Photoshop brush loaded with an image.

For the UISearchBar, we found that setting the tint color property to our image brush did not cause the desired effect. So we painted a normal view and slipped it in just above the default view. Here's a snippet of the code. I'll leave it to you to make your own Xcode project, build the NIB and use your own image. I grabbed an outrageous polka dot image from Google image search.
tintyViewController.h
@interface tintyViewController : UIViewController

@property (nonatomic, retain) IBOutlet UISearchBar *searchBar;

@end
tintyViewController.m
#import "tintyViewController.h">@implementation tintyViewController

@synthesize searchBar;


#pragma mark -
#pragma mark NSObject
- (void)dealloc {
[searchBar release];
[super dealloc];
}


#pragma UIViewController
- (void)viewDidLoad {

UIImage *image = [UIImage imageNamed:@"Polka_dots"];
UIColor *col = [UIColor colorWithPatternImage:image];
[searchBar setTintColor:[UIColor purpleColor]];


UIView *searchBack = (UIView *)[searchBar.subviews objectAtIndex:0];
CGRect backFrame = searchBack.frame;
UIView *newBack = [[UIView alloc] initWithFrame:backFrame];
[newBack setBackgroundColor:col];
[searchBar insertSubview:newBack aboveSubview:searchBack];
[newBack release];
}

@end
UPDATE: According to this guy using colorWithPatternImage is dangerous. I profiled the sample in Instruments, got this result (1.65MB):fixed it to not use colorWithPatternImage, profiled it again and got this result(956.82KB). Sure enough, he's right.
Here's the fixed code:tintyViewController.m (try two)
- (void)viewDidLoad {

UIImage *image = [UIImage imageNamed:@"Polka_dots"];
[searchBar setTintColor:[UIColor purpleColor]];

UIView *searchBack = (UIView *)[searchBar.subviews objectAtIndex:0];
CGRect backFrame = searchBack.frame;
UIView *newBack = [[UIView alloc] initWithFrame:backFrame];
UIImageView *imageBack = [[UIImageView alloc] initWithImage:image];
[newBack addSubview:imageBack];
[newBack setClipsToBounds:YES];
[searchBar insertSubview:newBack aboveSubview:searchBack];
[imageBack release];
[newBack release];
}