2

I've read the "What's new in iOS 5" documentation and there it is stated, that changing the background of some UI-Elements is now better supported.

I couldn't find the correct way for iOS 5 to change the background image of an UIToolbar. Is there a special new iOS 5 way of doing this? Or do i still have to subclass the UIToolbar?

MadMaxAPP
  • 1,035
  • 2
  • 16
  • 39

2 Answers2

13

Yes, there is a new way to do this. You can use appearance to make all UIToolBars have the same appearance.

First, you have to make sure your class follows the UIAppearanceContainer protocol. Here I have done it in my app delegate:

@interface AppDelegate : UIResponder <UIApplicationDelegate, UIAppearanceContainer>

@property (strong, nonatomic) UIWindow *window;

@end

Then you can set the appearance in, for example, application:didFinishLaunchingWithOptions: or viewDidLoad. Like this:

UIImage *image = [UIImage imageNamed:@"myimage.png"];
[[UIToolbar appearance] setBackgroundImage:image forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];

You only have to do this once to get the same appearance for all UIToolBars in your app. You can also set many of (if not all?) the properties of your UIToolBar.

As a sidenote, there are many classes that can follow the UIAppearanceContainer protocol. To find out what can be customized using the appearance protocol, you can open the header file of the class you want to customize, if you can set a property with UIAppearance, then the property has UI_APPEARANCE_SELECTOR written behind the property declaration.

matsr
  • 4,302
  • 3
  • 21
  • 36
  • 1
    I get an error in console right after start of the app in simulator: `-[_UIAppearance setBackgroundImage:forBarMetrics:]: unrecognized selector sent to instance 0x903b8d0 2011-11-29 16:05:04.469 CatalogService[2998:fb03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UIAppearance setBackgroundImage:forBarMetrics:]: unrecognized selector sent to instance 0x903b8d0'` the code i used is: `[[UIToolbar appearance] setBackgroundImage:gradientImage44 forBarMetrics:UIBarMetricsDefault];` – MadMaxAPP Nov 29 '11 at 15:06
  • Ok. Did you make sure the image you used actually was loaded? But first, try first to just set the tintColor, to see if the methods you use actually get called, and that the `UIToolBar` responds to your method calls. For example: `[UIToolBar appearance].tintColor = [UIColor redColor];` – matsr Nov 29 '11 at 15:17
  • If i try to set the tintColor, it says `Property 'tintColor' not found on Object of type 'id'` ... looks like there's the Problem. UINaviagtionBar works in this context. I can set all propertys as needed. – MadMaxAPP Nov 29 '11 at 15:24
  • Ok. found the problem! The UIToolbar is contained within a ViewController. I cannot change the UIToolbar within AppDelegate if the UIToolbar is contained in a ViewController. Thanks for your help matsr! – MadMaxAPP Nov 29 '11 at 15:40
  • 1
    There is still a problem! I can set the TintColor and also Alpha Value. But as soon as i try to set the BackgroundImage, i recieve the above mentioned error in console. The image i try to assign is a valid ressource, as i also set it for UINavigationBar without any problem or error! – MadMaxAPP Nov 29 '11 at 15:51
  • I see now that the method I mentioned is not mentioned in the `UIToolBar` docs. Try this instead: `[[UIToolbar appearance] setBackgroundImage:image forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];` – matsr Nov 29 '11 at 16:01
  • @MadMaxAPP, did you make it work? Note that I changed the method you should use in my answer. I would suggest that you take a look inside UIToolBar.h. :-) – matsr Nov 30 '11 at 14:07
  • Using a smaller image than the size of the toolbar, is there a way to stop the image tiling/stretching? – Danyal Aytekin Nov 12 '13 at 23:14
  • @DanyalAytekin: from the top of my head, try setting the `contentMode` of the `UIToolBar` or the `UIImage` to something like `UIViewContentModeCenter` or `UIViewContentModeLeft`, etc. I can't test this at the moment, but it's worth a try. The default is `UIViewContentModeScaleToFill`.. See the reference and search for "contentMode": [link to reference](https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/UIView/UIView.html#//apple_ref/occ/instp/UIView/contentMode) – matsr Nov 13 '13 at 00:33
2

Here's a great tutorial: http://www.raywenderlich.com/4344/user-interface-customization-in-ios-5

Basically, it looks like this:

UIImage *gradientImage32 = [[UIImage imageNamed:@"surf_gradient_textured_32"] 
    resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];

[[UINavigationBar appearance] setBackgroundImage:gradientImage32 
    forBarMetrics:UIBarMetricsDefault];
Senior
  • 2,259
  • 1
  • 20
  • 31