Amit Vaghela
Amit Vaghela

Reputation: 2970

Can I set image as a title to UINavigationBar?

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).

Upvotes: 67

Views: 54168

Answers (16)

You can use an UIImageView for the UINavigationItem.titleView property, something like:

self.navigationItem.titleView = myImageView;

Upvotes: 132

Bartłomiej Semańczyk
Bartłomiej Semańczyk

Reputation: 61880

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:

enter image description here

and wait a second for result:

enter image description here

So setting view is there where it should be... in storyboard.

Upvotes: 3

user3378170
user3378170

Reputation: 2387

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

}

Upvotes: 0

Dr TJ
Dr TJ

Reputation: 3354

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!

Upvotes: 2

Cinoss
Cinoss

Reputation: 340

You can do it right from storyboard (as of Xcode 7):

  1. Create a view outside main view of view controller. It can be a nested view or just an image
  2. Add navigation item to your view controller
  3. Ctrl+ drag from navigation item and drop on outside view

enter image description here

4.select title view

enter image description here

Upvotes: 13

MrChrisBarker
MrChrisBarker

Reputation: 141

This also works well too

[self.navigationController.navigationBar.topItem setTitleView:[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"YourLogo"]]];

Upvotes: 5

user1711665
user1711665

Reputation:

This line will work for you, I always use this

[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"imageNavBar.png"]  forBarMetrics:UIBarMetricsDefault];

Upvotes: 7

Ian Vink
Ian Vink

Reputation: 68840

In MonoTouch you can use this:

 this.NavigationItem.TitleView = myImageView;

Upvotes: 0

joneswah
joneswah

Reputation: 2798

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]];
}

Upvotes: 0

J.Raza
J.Raza

Reputation: 1

Just use

[navController.navigationBar insertSubview:myImage atIndex:0] ;

where myImage is of type UIImageView and navController is of type UINavigationController

Upvotes: 0

snez
snez

Reputation: 2480

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];
    }
}

Upvotes: 0

Ian Vink
Ian Vink

Reputation: 68840

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.

Upvotes: 0

Clifton Burt
Clifton Burt

Reputation: 366

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];

}

Upvotes: 16

Mr. Propa
Mr. Propa

Reputation: 31

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];
}

Upvotes: 0

ck.
ck.

Reputation: 327

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

Upvotes: 5

adam
adam

Reputation: 22597

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];

Upvotes: 8

Related Questions