Is it possible to set some image as title of Navigation bar?
I think NYTimes application used a Navigation bar and title is look like image file (the reason why it's seems UINavigationBar is because they use right button to search).
You can use an UIImageView for the UINavigationItem.titleView property, something like:
self.navigationItem.titleView = myImageView;
I find that a transparent .png at about 35px in height has worked well.
- (void)awakeFromNib {
//put logo image in the navigationBar
UIImageView* img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"logo.png"]];
self.navigationItem.titleView = img;
[img release];
}
You can do it right from storyboard (as of Xcode 7):
Create a view outside main view of view controller. It can be a nested view or just an image
Add navigation item to your view controller
Ctrl+ drag from navigation item and drop on outside view
4.select title view
I have created a custom category for UINavigationBar as follows
UINavigationBar+CustomImage.h
#import <UIKit/UIKit.h>
#interface UINavigationBar (CustomImage)
- (void) setBackgroundImage:(UIImage*)image;
- (void) clearBackgroundImage;
- (void) removeIfImage:(id)sender;
#end
UINavigationBar+CustomImage.m
#import "UINavigationBar+CustomImage.h"
#implementation UINavigationBar (CustomImage)
- (void) setBackgroundImage:(UIImage*)image {
if (image == NULL) return;
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(110,5,100,30);
[self addSubview:imageView];
[imageView release];
}
- (void) clearBackgroundImage {
NSArray *subviews = [self subviews];
for (int i=0; i<[subviews count]; i++) {
if ([[subviews objectAtIndex:i] isMemberOfClass:[UIImageView class]]) {
[[subviews objectAtIndex:i] removeFromSuperview];
}
}
}
#end
I invoke it from my UINavigationController
[[navController navigationBar] performSelectorInBackground:#selector(setBackgroundImage:) withObject:image];
This line will work for you, I always use this
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"imageNavBar.png"] forBarMetrics:UIBarMetricsDefault];
I modified the UINavigationBar+CustomImage.m to have the title still visible to the user. Just use insertSubview: atIndex: instead of addSubview:
UINavigationBar+CustomImage.m
#import "UINavigationBar+CustomImage.h"
#implementation UINavigationBar (CustomImage)
- (void) setBackgroundImage:(UIImage*)image {
if (image == NULL) return;
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(0, 0, 320, 44);
[self insertSubview:imageView atIndex:0];
[imageView release];
}
- (void) clearBackgroundImage {
NSArray *subviews = [self subviews];
for (int i=0; i<[subviews count]; i++) {
if ([[subviews objectAtIndex:i] isMemberOfClass:[UIImageView class]]) {
[[subviews objectAtIndex:i] removeFromSuperview];
}
}
}
#end
This also works well too
[self.navigationController.navigationBar.topItem setTitleView:[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"YourLogo"]]];
Do it quickly using storyboard and #IBDesignable:
#IBDesignable class AttributedNavigationBar: UINavigationBar {
#IBInspectable var imageTitle: UIImage? = nil {
didSet {
guard let imageTitle = imageTitle else {
topItem?.titleView = nil
return
}
let imageView = UIImageView(image: imageTitle)
imageView.frame = CGRect(x: 0, y: 0, width: 40, height: 30)
imageView.contentMode = .scaleAspectFit
topItem?.titleView = imageView
}
}
}
Then in attributes inspector just select an image:
and wait a second for result:
So setting view is there where it should be... in storyboard.
For those who have the same error but in Xamarin Forms, the solution is to create a Renderer in iOS app and set the image like so :
[assembly: Xamarin.Forms.ExportRenderer(typeof(Xamarin.Forms.Page), typeof(MyApp.Renderers.NavigationPageRenderer))]
namespace MyApp.Renderers
{
#region using
using UIKit;
using Xamarin.Forms.Platform.iOS;
#endregion
public class NavigationPageRenderer : PageRenderer
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
SetTitleImage();
}
private void SetTitleImage()
{
UIImage logoImage = UIImage.FromFile(ResourceFiles.ImageResources.LogoImageName);
UIImageView logoImageView = new UIImageView(logoImage);
if (this.NavigationController != null)
{
this.NavigationController.NavigationBar.TopItem.TitleView = logoImageView;
}
}
}
}
Hope it helps someone!
I modified the UINavigationBar+CustomImage code to properly work without leaking memory.
- (void)setBackgroundImage:(UIImage *)image
{
if (! image) return;
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
[self addSubview:imageView];
[imageView release];
}
- (void) clearBackgroundImage
{
// This runs on a separate thread, so give it it's own pool
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *mySubviews = self.subviews;
// Move in reverse direction as not to upset the order of elements in the array
for (int i = [mySubviews count] - 1; i >= 0; i--)
{
if ([[mySubviews objectAtIndex:i] isMemberOfClass:[UIImageView class]])
{
[[mySubviews objectAtIndex:i] removeFromSuperview];
}
}
[pool release];
}
The following is how you would do this in (Xamarin's) MonoTouch with C#.NET
Create a UIViewConvrtoller that is in a NavigationController then call this at any time:
someNiceViewControllerYouMade.NavigationController.NavigationBar
.InsertSubview(new UIImageView
(MediaProvider.GetImage(ImageGeneral.navBar_667x44)),0);
Note: MediaProvider is just a class that fetches images.
This example allows for the view to fill the full Navigation Bar , and lets the text for the items caption appear too.
If your buttons disappear when you navigate back and forth the navigation, this fixed it for me:
NSArray *mySubviews = navigationBar.subviews;
UIImageView *iv = nil;
// Move in reverse direction as not to upset the order of elements in the array
for (int i = [mySubviews count] - 1; i >= 0; i--)
{
if ([[mySubviews objectAtIndex:i] isMemberOfClass:[UIImageView class]])
{
NSLog(#"found background at index %d",i);
iv = [mySubviews objectAtIndex:i];
[[mySubviews objectAtIndex:i] removeFromSuperview];
[navigationBar insertSubview:iv atIndex:0];
}
}
Just use
[navController.navigationBar insertSubview:myImage atIndex:0] ;
where myImage is of type UIImageView
and navController is of type UINavigationController
ios5.0 introduced a heap of features to customise the appearance of standard elements. If you didn't want to use an ImageView for the title, an alternative would be to customise the appearance of all UINavbars using a background image and a custom font/colour.
- (void) customiseMyNav
{
// Create resizable images
UIImage *portraitImage = [[UIImage imageNamed:#"nav_bar_bg_portrait"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
UIImage *landscapeImage = [[UIImage imageNamed:#"nav_bar_bg_landscape"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
// Set the background image
[[UINavigationBar appearance] setBackgroundImage:portraitImage forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:landscapeImage forBarMetrics:UIBarMetricsLandscapePhone];
// set the title appearance
[[UINavigationBar appearance] setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor colorWithRed:50.0/255.0 green:150.0/255.0 blue:100/255.0 alpha:1.0],
UITextAttributeTextColor,
[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.6],
UITextAttributeTextShadowColor,
[NSValue valueWithUIOffset:UIOffsetMake(0, -1)],
UITextAttributeTextShadowOffset,
[UIFont fontWithName:#"Arial-Bold" size:0.0],
UITextAttributeFont,
nil]];
}
In MonoTouch you can use this:
this.NavigationItem.TitleView = myImageView;
Add image to naviagtionBar with SWIFT that scales to fit and clips to bounds. You can call this function inside the view controllers viewDidLoad() function.
func setupNavigationBarWithTitleImage(titleImage: UIImage) {
let imageView = UIImageView(image: titleImage)
imageView.contentMode = .ScaleAspectFit
imageView.clipsToBounds = true
navigationItem.titleView = imageView
}
Related
I added a category to navigationBar to change backgroundImage, image may be gradient or transparent.
Interestingly, it works on Xcode9, but doesn't work on Xcode10. Does not matter with iOS version.
codes:
#implementation UINavigationBar (Category)
static char overlayKey;
- (UIImageView *)overlay
{
return objc_getAssociatedObject(self, &overlayKey);
}
- (void)setOverlay:(UIImageView *)overlay
{
objc_setAssociatedObject(self, &overlayKey, overlay, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)el_setBackgroundImage:(UIImage *)backgroundImage
{
[self initOverlay];
self.overlay.image = backgroundImage;
}
- (void)initOverlay
{
if (!self.overlay) {
[self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) + kWindow_StatusBarHeight)];
imgView.userInteractionEnabled = NO;
imgView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[[self.subviews firstObject] insertSubview:imgView atIndex:0];
self.overlay = imgView;
}
}
#end
use:
[self.navigationController.navigationBar el_setBackgroundImage:[UIImage imageWithColor:[UIColor redColor] size:CGSizeMake(kScreenWidth, kWindow_NavigationBarHeight)]];
Any Ideas as to why this could be happening?
Only need to add a line of judgment statements:
- (void)initOverlay
{
if (!self.overlay &&
self.subviews.count > 0) {
...
Xcode10 is too strange.
I am setting the SelectionIndicatorImage as a stretchable image (to accommodate for various device widths) via UITabBar appearance:
UIImage *selectedImage = [[UIImage imageNamed:#"SelectedTab"] stretchableImageWithLeftCapWidth:0 topCapHeight:0];
[[UITabBar appearance] setSelectionIndicatorImage:selectedImage];
As a result I get a 2pt padding on the screen edges. I am basically trying to use selection indicator as a background for currently selected UITabBarItem.
http://i.stack.imgur.com/qFHEk.png
What would be an easy way to solve this?
If you want to use UITabBarController in your app with selection and unselection feature then you should this code
[[self.tabBarController tabBar] setBackgroundImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"bg_tabBar" ofType:#"png"]]];
[[self.tabBarController tabBar] setSelectionIndicatorImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"bg_tabItem_selected" ofType:#"png"]]];
NSArray *arrTabItems = [[self.tabBarController tabBar] items];
UITabBarItem *tabBarItem = [arrTabItems objectAtIndex:0];
[tabBarItem setFinishedSelectedImage:[UIImage imageNamed:#"img_selected.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"img_unselected.png"]];
[tabBarItem setImageInsets:UIEdgeInsetsMake(5, 5, 0, 5)];
I've tried something similar. Ended up this way:
Subclass UITabBarController and add property:
#property(nonatomic, readonly) UIImageView *imageView;
Setup your image as you want:
- (void)viewDidLoad {
[super viewDidLoad];
_imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tabbaritem"]];
[self.tabBar addSubview:self.imageView];
}
Place your subview in correct position:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// get all UITabBarButton views
NSMutableArray *tabViews = [NSMutableArray new];
for (UIView *view in self.tabBar.subviews) {
if ([view isKindOfClass:[UIControl class]]) {
[tabViews addObject:[NSValue valueWithCGRect:view.frame]];
}
}
// sort them from left to right
NSArray *sortedArray = [tabViews sortedArrayUsingComparator:^NSComparisonResult(NSValue *firstValue, NSValue *secondValue) {
CGRect firstRect = [firstValue CGRectValue];
CGRect secondRect = [secondValue CGRectValue];
return CGRectGetMinX(firstRect) > CGRectGetMinX(secondRect);
}];
// place your imageView on selected index button frame
CGRect frame = self.tabBar.bounds;
CGSize imageSize = CGSizeMake(CGRectGetWidth(frame) / self.tabBar.items.count, self.imageView.image.size.height);
CGRect selectedRect = sortedArray.count > self.selectedIndex ? [sortedArray[self.selectedIndex] CGRectValue] : CGRectZero;
[self.imageView setFrame:CGRectIntegral(CGRectMake(CGRectGetMinX(selectedRect), CGRectGetMaxY(frame) - imageSize.height,
CGRectGetWidth(selectedRect), imageSize.height))];
}
Then you only need to refresh layout on each tab change:
- (void)setSelectedIndex:(NSUInteger)selectedIndex {
[super setSelectedIndex:selectedIndex];
[self.view setNeedsLayout];
}
- (void)setSelectedViewController:(UIViewController *)selectedViewController {
[super setSelectedViewController:selectedViewController];
[self.view setNeedsLayout];
}
Old answer how to remove padding (this is what I firstly understood as your question, I'm leaving it as a reference for other people).
In iOS 7+ UITabBar has following property:
/*
Set the itemSpacing to a positive value to be used between tab bar items
when they are positioned as a centered group.
Default of 0 or values less than 0 will be interpreted as a system-defined spacing.
*/
#property(nonatomic) CGFloat itemSpacing NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
This should enable you to get rid of padding between items.
I am trying to move a UIImage, first button press creates the image and second press moves it.
The image only needs to exist upon pressing the button.
In the simulator it creates the button and places it, the second time it click just doesn't do anything.
This is my Code
- (IBAction) btn:(id)sender {
UIImageView *myImage = [[UIImageView alloc] init];
myImage.image = [UIImage imageNamed:#"keyframe"];
if (startUp == 1){
//Create Image and add to view
myImage.frame = CGRectMake(200, 300, 10, 10);
myImage.image = [UIImage imageNamed:#"keyframe"];
[self.view addSubview:myImage];
//Set startUp to 0 and output rect value
startUp = 0;
NSLog(#"currentFrame %#", NSStringFromCGRect(myImage.frame));
}else if (startUp == 0){
//Change position, size and log to debug
myImage.frame = CGRectMake(500,100 ,20, 20);
NSLog(#"newFrame %#", NSStringFromCGRect(myImage.frame));
}
}
How do you programmatically move a programmatically added UIimage?
I tried changing the center value but that doesn't work either.
Try something like this – tested and working sample:
#import "ViewController.h"
#interface ViewController () {
BOOL startUp;
UIImageView *myImage;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
startUp = YES;
}
- (IBAction)doWork:(id)sender {
if (startUp) {
UIImage *img = [UIImage imageNamed: #"keyframe"];
myImage = [[UIImageView alloc] initWithImage: img];
[myImage sizeToFit];
[myImage setCenter: CGPointMake(200, 300)];
[self.view addSubview: myImage];
startUp = NO;
} else {
[myImage setCenter: CGPointMake(400, 500)];
}
}
#end
I have a singlton object. Is there any simple way to determine if current screen contains a navigation bar within singlton methods?
The singleton is UIView subclass. It's designed for showing prorgess activity, e.g. network exchange. It looks like black rectangle dropping down from top and hiding when the work is done. Why singleton? It's easy to call it from any place of code
The followed snippet is showing the initialization of activity singleton and published here just for better understaning my idea.
-(void) showUpdatingView:(NSString *) msg {
[self initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44)];
activity = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite] autorelease];
activity.frame = CGRectMake(5, 10, 22, 22);
labelView = [[[UILabel alloc] initWithFrame:CGRectMake(35, 10, [UIScreen mainScreen].bounds.size.width - 10, 22)] autorelease];
labelView.font = [UIFont boldSystemFontOfSize:12];
labelView.backgroundColor = [UIColor clearColor];
labelView.textColor = [UIColor whiteColor];
labelView.text = msg;
[self addSubview:activity];
[self addSubview:labelView];
self.backgroundColor = [UIColor blackColor];
self.alpha = 0.7;
}
The activity can be called by
[[ActivitySingleton getInstance] showUpdatingView:#"Getting data."];
it's not all.
The singleton is being created in AppDelegate object and the view is added to
inlineActivity = [[CHInlineActivityView alloc] initView];
[self.window.rootViewController.view addSubview:inlineActivity];
I know it may look crazy. But when I was designing it seemed to me reasonable
if you have all in one navigationController:
BOOL navHidden = self.window.rootViewController.navigationController.navigatonBarHidden;
if you don't it is a bit harder.. you could check the window's subviews and see if you can find a UINavigationBar
id navbar = [self.window firstSubviewOfKind:[UINavigationBar class] withTag:NSNotFound];
BOOL navHidden = navbar == nil;
#implementation NSView (findSubview)
- (NSArray *)findSubviewsOfKind:(Class)kind withTag:(NSInteger)tag inView:(NSView*)v {
NSMutableArray *array = [NSMutableArray array];
if(kind==nil || [v isKindOfClass:kind]) {
if(tag==NSNotFound || v.tag==tag) {
[array addObject:v];
}
}
for (id subview in v.subviews) {
NSArray *vChild = [self findSubviewsOfKind:kind withTag:tag inView:subview];
[array addObjectsFromArray:vChild];
}
return array;
}
#pragma mark -
- (NSView *)firstSubviewOfKind:(Class)kind withTag:(NSInteger)tag {
NSArray *subviews = [self findSubviewsOfKind:kind withTag:tag inView:self];
return subviews.count ? subviews[0] : nil;
}
#end
This question already has answers here:
How to change inside background color of UISearchBar component on iOS
(26 answers)
Closed 7 years ago.
How can set the background image, or clear the background, of a search bar, like the note application?
A future-proof way:
[searchBar setBackgroundImage:[UIImage new]];
[searchBar setTranslucent:YES];
mj_ has the answer that i used. i was just going to comment as such but i can't yet. So i'll just post my own answer with my implementation where I add a search bar to the top of a table view with a semi-transparent BG.
DLog(#" Add search bar to table view");
//could be a UIImageView to display an image..?
bg = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 45)] autorelease];
bg.backgroundColor = [UIColor blackColor];
UISearchBar *sb = [[[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, 290, 45)] autorelease];
sb.barStyle = UIBarStyleBlackTranslucent;
sb.showsCancelButton = NO;
sb.autocorrectionType = UITextAutocorrectionTypeNo;
sb.autocapitalizationType = UITextAutocapitalizationTypeNone;
sb.delegate = self;
[bg addSubview:sb];
table.tableHeaderView = bg;
for (UIView *subview in sb.subviews) {
if ([subview isKindOfClass:NSClassFromString(#"UISearchBarBackground")]) {
[subview removeFromSuperview];
break;
}
}
I had problems w/ the answer above. I used the following.
for (UIView *subview in searchBar.subviews) {
if ([subview isKindOfClass:NSClassFromString(#"UISearchBarBackground")]) {
[subview removeFromSuperview];
break;
}
}
This worked for me (ios4.2+)
// Change the search bar background
-(void)viewWillAppear:(BOOL)animated {
for (UIView *subview in self.searchBar.subviews) {
if ([subview isKindOfClass:NSClassFromString(#"UISearchBarBackground")]) {
UIView *bg = [[UIView alloc] initWithFrame:subview.frame];
bg.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"search_bar_bg"]];
[self.searchBar insertSubview:bg aboveSubview:subview];
[subview removeFromSuperview];
break;
}
}
}
I just came up with a solution that works really well. You have to override the UISearchBar and then hide both the Background and Segment Control layers. Then Draw the background.
# .m
#import "UISearchBar.h"
#import <QuartzCore/QuartzCore.h>
#implementation UISearchBar(CustomBackground)
- (id)init
{
for ( UIView * subview in self.subviews )
{
if ([subview isKindOfClass:NSClassFromString(#"UISearchBarBackground") ] )
subview.alpha = 0.0;
if ([subview isKindOfClass:NSClassFromString(#"UISegmentedControl") ] )
subview.alpha = 0.0;
}
return self;
}
+ (UIImage *) bgImagePortrait
{
static UIImage *image = nil;
if (image == nil)
image = [[UIImage imageNamed:#"UISearchBarBack.png"] retain ];
return image;
}
+ (UIImage *) bgImageLandscape
{
static UIImage *image = nil;
if (image == nil)
image = [[UIImage imageNamed:#"UISearchBarBack.png"] retain];
return image;
}
- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)contenxt
{
if ([self isMemberOfClass:[UISearchBar class]] == NO)
return;
UIImage * image = ( self.frame.size.width > 320 ) ? [UISearchBar bgImageLandscape ] : [UISearchBar bgImagePortrait ];
for ( UIView * subview in self.subviews ) {
if ([subview isKindOfClass:NSClassFromString(#"UISearchBarBackground") ] )
subview.alpha = 0.0;
if ([subview isKindOfClass:NSClassFromString(#"UISegmentedControl") ] )
subview.alpha = 0.0;
}
CGContextTranslateCTM( contenxt , 0 , image.size.height );
CGContextScaleCTM( contenxt, 1.0, -1.0 );
CGContextDrawImage( contenxt , CGRectMake( 0 , 0 , image.size.width , image.size.height ), image.CGImage );
}
#end
# .h
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#interface UISearchBar(CustomBackground)
#end
Hope this helps!
You have two questions here:
1.UISearchBar clear background color:
See my answer here
2.Set background image
Solution:(If you are in iOS 5.0 +)
[[UISearchBar appearance]setSearchFieldBackgroundImage:[navBarGradImage resizableImageWithCapInsets:inset2] forState:UIControlStateNormal];
NOTE: You can also try using a transparent image as a background.
Hope this helps.
I prefer to just set the alpha to 0 so you can hide/show on demand.
// Hide
[[self.theSearchBar.subviews objectAtIndex:0] setAlpha:0.0];
// Show
[[self.theSearchBar.subviews objectAtIndex:0] setAlpha:1.0];
How to set background color in UISearchBar:
#import <QuartzCore/QuartzCore.h>
Then make an outlet connection to search bar (say, objSearchbar), and use these lines :
for (UIView *subview in self.objSearchbar.subviews)
{
if ([subview isKindOfClass:NSClassFromString(#"UISearchBarBackground")])
{
[subview removeFromSuperview];
break;
}
}
self.tweetSearchbar.layer.backgroundColor = [UIColor blueColor].CGColor;
searchBar.searchBarStyle = UISearchBarStyleMinimal;
Look here: UISearchbar background image change
with iOS8 sdks apple moved #"UISearchBarBackground" view one level deeper, so have will need to look at subviews of the child-views as bellow,
for (UIView *subview in searchBar.subviews) {
for(UIView* grandSonView in subview.subviews){
if ([grandSonView isKindOfClass:NSClassFromString(#"UISearchBarBackground")]) {
grandSonView.alpha = 0.0f;
}else if([grandSonView isKindOfClass:NSClassFromString(#"UISearchBarTextField")] ){
NSLog(#"Keep textfiedld bkg color");
}else{
grandSonView.alpha = 0.0f;
}
}//for cacheViews
}//subviews
Set background image
UIImageView *backgroundView = [[UIImageView alloc] initWithFrame:searchBar.bounds];
backgroundView.image = [UIImage imageNamed:#"xxxx.png"];
[searchBar insertSubview:backgroundView atIndex:1]; // at index 1 but not 0
[backgroundView release];
One liner:
[[self.theSearchBar.subviews objectAtIndex:0] removeFromSuperview];