Can I set image as a title to UINavigationBar?
IosCocoa TouchIos Problem Overview
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).
Ios Solutions
Solution 1 - Ios
You can use an UIImageView
for the UINavigationItem.titleView
property, something like:
self.navigationItem.titleView = myImageView;
Solution 2 - Ios
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];
}
Solution 3 - Ios
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
Solution 4 - Ios
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];
Solution 5 - Ios
This line will work for you, I always use this
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"imageNavBar.png"] forBarMetrics:UIBarMetricsDefault];
Solution 6 - Ios
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
Solution 7 - Ios
This also works well too
[self.navigationController.navigationBar.topItem setTitleView:[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"YourLogo"]]];
Solution 8 - Ios
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.
Solution 9 - Ios
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!
Solution 10 - Ios
Just use
[navController.navigationBar insertSubview:myImage atIndex:0] ;
where myImage is of type UIImageView and navController is of type UINavigationController
Solution 11 - Ios
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];
}
Solution 12 - Ios
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.
Solution 13 - Ios
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];
}
}
Solution 14 - Ios
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]];
}
Solution 15 - Ios
In MonoTouch you can use this:
this.NavigationItem.TitleView = myImageView;
Solution 16 - Ios
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
}