With the new iOS7 UIView tint color it becomes pretty easy to theme an entire app quickly. It even changes the color of the text caret when editing UITextFields.
However, the keyboard's bottom right 'dismiss' button (can be Done, Search, etc) is always blue. Is there any way to change this? It would look really nice if it matched the tint color of the rest of the app.
With a little hack maybe you can achieve the effect you are looking for. But it might not be able to pass the app review.
-(NSArray*)subviewsOfView:(UIView*)view withType:(NSString*)type{
NSString *prefix = [NSString stringWithFormat:#"<%#",type];
NSMutableArray *subviewArray = [NSMutableArray array];
for (UIView *subview in view.subviews) {
NSArray *tempArray = [self subviewsOfView:subview withType:type];
for (UIView *view in tempArray) {
[subviewArray addObject:view];
}
}
if ([[view description]hasPrefix:prefix]) {
[subviewArray addObject:view];
}
return [NSArray arrayWithArray:subviewArray];
}
-(void)addColorToUIKeyboardButton{
for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) {
for (UIView *keyboard in [keyboardWindow subviews]) {
for (UIView *view in [self subviewsOfView:keyboard withType:#"UIKBKeyplaneView"]) {
UIView *newView = [[UIView alloc] initWithFrame:[(UIView *)[[self subviewsOfView:keyboard withType:#"UIKBKeyView"] lastObject] frame]];
newView.frame = CGRectMake(newView.frame.origin.x + 2, newView.frame.origin.y + 1, newView.frame.size.width - 4, newView.frame.size.height -3);
[newView setBackgroundColor:[UIColor greenColor]];
newView.layer.cornerRadius = 4;
[view insertSubview:newView belowSubview:((UIView *)[[self subviewsOfView:keyboard withType:#"UIKBKeyView"] lastObject])];
}
}
}
}
The app I used to decode the view hierarchy was : http://revealapp.com/
The end result is like this:
You can not change button tint color but you can set keyboard Tint color by using UIKeyboardAppearance
Example: yourTextField.keyboardAppearance = UIKeyboardAppearanceDark;
Here is a very nice document provided by Apple, take a look here:
Managing the Keyboard
let colors: [UIColor] = [.red, .blue, .green, .purple, .yellow, .orange, .brown]
if let window = UIApplication.shared.windows.first(where: {
$0.isType(string: "UIRemoteKeyboardWindow")
}) {
if let keyplaneView = window.subview(ofType: "UIKBKeyplaneView") {
for (i, keyView) in keyplaneView.subviews.filter({
$0.isType(string: "UIKBKeyView")
}).enumerated() {
let view = UIView(frame: keyView.bounds)
view.backgroundColor = colors[i].withAlphaComponent(0.5)
keyView.addSubview(view)
}
}
}
Here is a color map of the keys in the UIKBKeyplaneView:
Related
I'm trying to make a UISearchBar rectangular instead of rounded, but all the solutions I found so far (mostly iterating through subviews) seem broken on iOS 7.
I did some research myself and as it turns out, it only has a UIView subview, which has additional subviews, a UISearchBarBackground and a UISearchBarTextField (both of them are private classes).
I tried
if ([view isKindOfClass:NSClassFromString(#"UISearchBarBackground")]) {
[view removeFromSuperview];
}
and
if ([view conformsToProtocol:#protocol(UITextInputTraits)]) {
#try {
[(UITextField *)view setBorderStyle:UITextBorderStyleRoundedRect];
}
#catch (NSException * e) {
// ignore exception
}
}
where view is the subview of that one UIView subview but none of them seems to work.
Try this... (I know it is also using subview but it is working in ios7)
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 20, 320, 49)];
[self.view addSubview:searchBar];
[self checkSubViewsOfView:searchBar WithTabIndex:#""];
and Add this method
-(void)checkSubViewsOfView:(UIView *)view WithTabIndex:(NSString *)strTab
{
if ([view isKindOfClass:NSClassFromString(#"UISearchBarTextField")])
{
view.layer.borderWidth = 1;
view.layer.borderColor = [[UIColor whiteColor] CGColor];
return;
}
for (UIView *vvv in view.subviews)
{
NSLog(#"%#%#",strTab,[vvv description]);
if (vvv.subviews > 0)
{
NSString *str = [NSString stringWithFormat:#"____%#",strTab];
[self checkSubViewsOfView:vvv WithTabIndex:str];
}
}
}
you can set the searchfield-background like this:
[self.searchBar setSearchFieldBackgroundImage:[[UIImage imageNamed:#"searchbar_stretch-0-10-0-10"]resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10)] forState:UIControlStateNormal];
and the searchbar-background like this:
[self.searchBar setBackgroundImage:[UIImage imageNamed:#"categories_navbar"]];
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
How do remove the gradient from a UIWebView - the one that you see if you overscroll the top or bottom.
This code
webView.backgroundColor = [UIColor whiteColor];
just changes the color of the gradient, it doesn't removes it. How can this be done?
(note: not the same question as UIWebView underside)
Aha, yes terminology fail. I wouldn't call that a shadow at all, but c'est la vie. Here is my type-safe code to achieve the effect. To summarise: this will hide any image-view children of the scroll view. It's not as vulnerable to change as the (objectAtIndex:0) methods, so if Apple re-order the children of the webView control it will work fine, but still relies on the fact that the gradient effect is applied by imageviews parented to the scroll view (and that there is indeed a scrollview underpinning the web view).
{
webView.backgroundColor = [UIColor whiteColor];
for (UIView* subView in [webView subviews])
{
if ([subView isKindOfClass:[UIScrollView class]]) {
for (UIView* shadowView in [subView subviews])
{
if ([shadowView isKindOfClass:[UIImageView class]]) {
[shadowView setHidden:YES];
}
}
}
}
}
To transparent the UIWebView and remove the scrolls.
webView.opaque = NO;
webView.backgroundColor = [UIColor clearColor];
for(UIView *view in webView.subviews){
if ([view isKindOfClass:[UIImageView class]]) {
// to transparent
[view removeFromSuperview];
}
if ([view isKindOfClass:[UIScrollView class]]) {
UIScrollView *sView = (UIScrollView *)view;
for (UIView* shadowView in [sView subviews]){
//to remove shadow
if ([shadowView isKindOfClass:[UIImageView class]]) {
[shadowView setHidden:YES];
}
}
}
}
for hide scroll indicators
You mean the shadow? Remove UIWebView Shadow?
The only way I found how to do this was :
for(UIView *aView in [[[webView subviews] objectAtIndex:0] subviews]) {
if([aView isKindOfClass:[UIImageView class]]) { aView.hidden = YES; }
}
It just just steps thru the subviews of UIWebView and removes the view if it is an image view.
I haven't put this in any App Store apps, so I don't know if Apple would accept it.
EDIT: Brian's link provides more details.
Using method suggested above you won't be able to edit your scroll indicator/insets later. They appear as UIImageView also, so you should check for last object:
UIView* lastView = [[subView subviews] lastObject];
for (UIView* shadowView in [subView subviews])
{
if(shadowView!=lastView) ... <-this one is a scroll
}
I was able to do this by adding white subviews to the top and bottom of the WebView’s scrollView. I control the content of the WebView, so I know that white is OK - this won’t work if you are loading arbitrary content.
// _topCover and _bottomCover are ivar UIViews
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
// with cover views 300pt high, I couldn't scroll far enough to see the shadow,
// even in portrait on an iPad, which gives you the longest scroll distance
CGFloat coverage = 300;
_topCover = [[UIView alloc] initWithFrame:CGRectMake(0, -coverage, webView.bounds.size.width, coverage)];
_bottomCover = [[UIView alloc] initWithFrame:CGRectMake(0, webView.scrollView.contentSize.height, webView.bounds.size.width, coverage)];
_topCover.backgroundColor = [UIColor whiteColor];
_bottomCover.backgroundColor = [UIColor whiteColor];
// in case the webView is resized, e.g. by rotating the device
_topCover.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth;
_bottomCover.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
[webView.scrollView addSubview:_topCover];
[webView.scrollView addSubview:_bottomCover];
}
I run it it after the page loads so that webView.scrollView.contentSize.height will give me the correct height. I’m not sure how this will work if your pages are dynamically changing height. My page loads only once; if yours is reloading, you will want to skip running alloc/init on _topCover and _bottomCover after the first time for efficiency.
Update: I’m not sure that my use of autoresizingMask, above, is sufficient when the view rotates. You may need to put this in the UIViewController that contains your UIWebView to resize the covers after rotating:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
CGFloat coverage = 300;
_topCover.frame = CGRectMake(0, -coverage, self.webView.bounds.size.width, coverage);
_bottomCover.frame = CGRectMake(0, self.webView.scrollView.contentSize.height, self.webView.bounds.size.width, coverage);
}
I've built upon #damithH 's answer
#implementation UIWebView (Extensions)
- (void)setBackgroundAndShadowVisible:(BOOL)visible
{
self.opaque = !visible;
self.backgroundColor = [self.backgroundColor colorWithAlphaComponent:visible ? 1.0 : 0.0];
for(UIView *view in [self subviews])
{
if([view isKindOfClass:[UIImageView class]])
{
view.hidden = !visible;
}
if([view isKindOfClass:[UIScrollView class]])
{
UIScrollView *scrollView = (UIScrollView *)view;
for (UIView *shadowView in [scrollView subviews])
{
if ([shadowView isKindOfClass:[UIImageView class]])
{
shadowView.hidden = !visible;
}
}
}
}
}
#end
if (UIDevice.currentDevice.systemVersion.intValue < 7)
for (UIImageView *imageView in webView.scrollView.subviews)
if ([imageView isKindOfClass:[UIImageView class]] && imageView.image.size.width == 1)
imageView.hidden = YES;
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];
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
}