UINavigationItem centering the title UINavigationItem centering the title ios ios

UINavigationItem centering the title


Setting the titleView property of the nav bar works just fine - no need to subclass or alter any frames other than those of your custom view.

The trick to getting it centered relative to the overall width of UINavigationBar is to:

  1. set the width of your view according to the size of the text
  2. set the alignment to centered and
  3. set the autoresizingmask so it gets resized to the available space

Here's some example code that creates a custom titleView with a label which remains centred in UINavigationBar irrespective of orientation, left or right barbutton width:

self.title = @"My Centered Nav Title";// Init views with rects with height and y posCGFloat titleHeight = self.navigationController.navigationBar.frame.size.height;UIView *titleView = [[UIView alloc] initWithFrame:CGRectZero];UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];// Set font for sizing widthtitleLabel.font = [UIFont boldSystemFontOfSize:20.f];// Set the width of the views according to the text sizeCGFloat desiredWidth = [self.title sizeWithFont:titleLabel.font                            constrainedToSize:CGSizeMake([[UIScreen mainScreen] applicationFrame].size.width, titleLabel.frame.size.height)                                lineBreakMode:UILineBreakModeCharacterWrap].width;CGRect frame;frame = titleLabel.frame;frame.size.height = titleHeight;frame.size.width = desiredWidth;titleLabel.frame = frame;frame = titleView.frame;frame.size.height = titleHeight;frame.size.width = desiredWidth;titleView.frame = frame;// Ensure text is on one line, centered and truncates if the bounds are restrictedtitleLabel.numberOfLines = 1;titleLabel.lineBreakMode = UILineBreakModeTailTruncation;titleLabel.textAlignment = NSTextAlignmentCenter;// Use autoresizing to restrict the bounds to the area that the titleview allowstitleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;titleView.autoresizesSubviews = YES;titleLabel.autoresizingMask = titleView.autoresizingMask;// Set the texttitleLabel.text = self.title;// Add as the nav bar's titleview[titleView addSubview:titleLabel];self.navigationItem.titleView = titleView;


You can't do what you want directly -- the position of your title view is out of your control (when managed by UINavigationBar).

However, there are at least two strategies to get the effect you want:

1) Add the title view not as the 'proper' title view of the nav bar, but as a subview of the UINavigationBar. (Note: this is not 'officially' sanctioned, but I've seen it done, and work. Obviously you have to watch out for your title label overwriting bits of the buttons, and handle different size nav bars for different orientations, etc. -- a bit fiddly.)

2) Make an intelligent UIView subclass that displays a given subview (which would be your UILabel) at a position calculated to effectively show the subview perfectly centered on the screen. In order to do this, your intelligent UIView subclass would respond to layout events (or frame property changes etc.) by changing the position (frame) of the label subview.

Personally, I like the idea of approach 2) the best.


override func viewDidLoad() {    super.viewDidLoad()    navigationController?.navigationBar.topItem?.title = ""}override func viewWillAppear(animated: Bool) {    super.viewWillAppear(animated)    navigationItem.title = "Make peace soon"}