sensorario
sensorario

Reputation: 21620

How to put an image in the center of navigationBar of a UIViewController?

I have this snippet of code used in viewDidLoad of a UIViewController. I'va no errors. Images exists. I get the background but not the image. Image is a sort of logo.

if ([self.navigationController.navigationBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)] ) {

    /* Background of navigationBar. */
    UIImage * navigationBarImage = [UIImage imageNamed:@"01_navbar_portrait.png"];
    [self.navigationController.navigationBar setBackgroundImage:navigationBarImage forBarMetrics:UIBarMetricsDefault];

    /* Image in navigationBar */
    UIImage * logoInNavigationBar = [UIImage imageNamed:@"01_logo.png"];
    UIImageView * logoView = [[UIImageView alloc] init];
    [logoView setImage:logoInNavigationBar];
    self.navigationController.navigationItem.titleView = logoView;

}

Upvotes: 22

Views: 34173

Answers (7)

Steve B
Steve B

Reputation: 911

func centeredNavBarImage (){
    let navcontroller = navigationController!
    let image = #imageLiteral(resourceName: "yourImage")
    let imageView = UIImageView(image:image)

    let bannerWidth = navcontroller.navigationItem.accessibilityFrame.size.width
    let bannerHeight = navcontroller.navigationBar.frame.size.height


    let bannerX = bannerWidth / 2 - image.size.width / 2
    let bannerY = bannerHeight / 2 - image.size.height / 2

    imageView.frame = CGRect(x: bannerX, y: bannerY, width: bannerWidth, height: bannerHeight)
    imageView.contentMode = .scaleAspectFit

    navigationItem.titleView = imageView

}

This is a modified code from https://youtu.be/bLkuu_fmlsU

The bannerWidth takes into account a refresh button item I have on the right side of the navbar. Seems to work.

Run the function on ViewDidLoad

Upvotes: 1

Andrew
Andrew

Reputation: 3241

extension UINavigationController {
func addLogoImage(image: UIImage, navItem: UINavigationItem) {
    let imageView = UIImageView(image: image)
    imageView.contentMode = .scaleAspectFit
    imageView.translatesAutoresizingMaskIntoConstraints = false

    let view = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 44))
    view.addSubview(imageView)

    navItem.titleView = view
    imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    imageView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
    imageView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true

    view.heightAnchor.constraint(equalTo: navigationBar.heightAnchor).isActive = true
    view.centerXAnchor.constraint(equalTo: navigationBar.centerXAnchor).isActive = true
    view.centerYAnchor.constraint(equalTo: navigationBar.centerYAnchor).isActive = true
}
}

Here's what I'm using.

Of course, you might need a bit more constraints, so as to not clash with the right and left bar button items.

Upvotes: 4

beOn
beOn

Reputation: 1899

Perhaps not what you meant, but I ran into this page looking for a way to provide a centered background image for the navigation bar, so in case you're here for that... here's one way.

Stealing a little bit from another answer, you can break your image into foreground and background, then build a new image that stretches the background and centers the foreground, and then set that as your nav bar's background image. Building the image works like so:

// build an image by stretching the bg, then merging it with the fg
CGSize barSize = self.navController.navigationBar.frame.size;
UIImage *fg = [UIImage imageNamed:@"some_fg"];
UIImage *bg = [[UIImage imageNamed:@"some_bg"]
               resizableImageWithCapInsets:UIEdgeInsetsMake(0.f,1.f,0.f,1.f)];
UIGraphicsBeginImageContextWithOptions(barSize, NO, 0.0);
[bg drawInRect:CGRectMake(0, 0, barSize.width, barSize.height)];
[fg drawInRect:CGRectMake((barSize.width-fg.size.width)/2.f,
                          0,
                          fg.size.width,
                          fg.size.height)];
// grab the merged images
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Upvotes: 2

Esqarrouth
Esqarrouth

Reputation: 39181

Swift:

var logoImage:UIImage = UIImage(named: "logo_text")!
self.navigationItem.titleView = UIImageView(image: logoImage)

Upvotes: 7

AG29
AG29

Reputation: 127

First we have to create a view which have size as same as navigation bar then add an image view and set set its frame as it looks center in the navigation bar.It works for all ios version and it automatically takes frame size as per device (retina or normal) and works like magic.

UIView *headerView = [[UIView alloc] init];
headerView.frame = CGRectMake(0, 0, 320, 44);

UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Header.png"]];
imgView.frame = CGRectMake(75, 0, 150, 44);
imgView.contentMode = UIViewContentModeScaleAspectFit;

[headerView addSubview:imgView];

navigationCtrl.navigationBar.topItem.titleView = headerView;

[headerView release];
[imgView release];

Upvotes: 9

jhabbott
jhabbott

Reputation: 19281

The UINavigationController manages the navigation bar by looking at the navigationItem property of the top-most view controller on the navigation stack. So to change the view to a logo, you need to set this up in the view controller that uses the logo (i.e. the root view controller or another one that gets pushed on the stack).

Do something like this in viewDidLoad of your view controller:

UIImage* logoImage = [UIImage imageNamed:@"logo.png"];
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:logoImage];

In your case, you are setting the wrong navigation item:

// Oops...
self.navigationController.navigationItem.titleView = logoView;
// Should be this:
self.navigationItem.titleView = logoView;

Upvotes: 54

manujmv
manujmv

Reputation: 6445

You just specify it's frame by

logoView.frame = CGRectMake(initialize frame here);

Then use the following

[self.navigationItem setTitleView:logoView];

Upvotes: 1

Related Questions