UINavigationItem以标题为中心

我有一个左侧和右侧栏button两侧的导航栏。 我有一个customTitlelabel ,我设置为UINavigationItem的titleView。

[self.navigationItem setTitleView:customTitleLabel];

现在一切正常。 问题是,rightbarButton的大小是基于我在其中一个文本字段中得到的input是dynamic的。

因此标题会根据button之间的可用空间自动居中。

我如何将标题设置为固定位置?

你不能直接做你想要的东西 – 标题视图的位置超出了你的控制范围(当被UINavigationBarpipe理时)。

但是,至less有两种策略可以达到你想要的效果:

1)添加标题视图不是导航栏的“正确”标题视图,而是作为UINavigationBar的子视图。 (注意:这并不是“官方”认可的,但是我已经看到它已经完成并且工作了。显然,你必须注意标题标签覆盖button的位,并且处理不同尺寸的导航条以适应不同的方向等等。 – 有点烦躁。)

2)制作一个智能的UIView子类,在显示一个给定的子视图(这将是你的UILabel)的位置计算,以有效地显示在屏幕上完美居中的子视图。 为了做到这一点,您的智能UIView子类将通过更改标签子视图的位置( frame )来响应布局事件(或frame属性更改等)。

就我个人而言,我喜欢方法2)最好的想法。

设置导航栏的titleView属性工作得很好 – 不需要对自定义视图以外的任何框架进行子类化或改变。

相对于UINavigationBar的整体宽度来说,获取它的技巧是:

  1. 根据文本的大小设置视图的宽度
  2. 将alignment设置为居中和
  3. 设置autoresizingmask,以便将其调整到可用空间

下面是一些示例代码,创build一个自定义titleView,标签保持居中在UINavigationBar中,而不pipe方向,左或右barbutton宽度:

 self.title = @"My Centered Nav Title"; // Init views with rects with height and y pos CGFloat titleHeight = self.navigationController.navigationBar.frame.size.height; UIView *titleView = [[UIView alloc] initWithFrame:CGRectZero]; UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; // Set font for sizing width titleLabel.font = [UIFont boldSystemFontOfSize:20.f]; // Set the width of the views according to the text size CGFloat 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 restricted titleLabel.numberOfLines = 1; titleLabel.lineBreakMode = UILineBreakModeTailTruncation; titleLabel.textAlignment = NSTextAlignmentCenter; // Use autoresizing to restrict the bounds to the area that the titleview allows titleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; titleView.autoresizesSubviews = YES; titleLabel.autoresizingMask = titleView.autoresizingMask; // Set the text titleLabel.text = self.title; // Add as the nav bar's titleview [titleView addSubview:titleLabel]; self.navigationItem.titleView = titleView; 
 override func viewDidLoad() { super.viewDidLoad() navigationController?.navigationBar.topItem?.title = "" } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) navigationItem.title = "Make peace soon" } 

正确的答案是覆盖你的自定义titleView sizeThatFits:并返回它的内容大小。 导航栏中心自定义标题视图,直到它没有空间去做。

例如,如果你有UILabel里面的UIView容器:

 @interface CustomTitleView : UIView @property UILabel* textLabel; @end @implementation CustomTitleView - (CGSize)sizeThatFits:(CGSize)size { CGSize textSize = [self.textLabel sizeThatFits:size]; CGSize contentSize = size; contentSize.width = MIN( size.width, textSize.width ); return contentSize; } @end 

我试过aopsfan的答案,但没有奏效。 一个断点显示,酒吧的中心是“(480.0,22.0)”(X坐标的方式)。

所以我把它改成了这个:

 - (void)layoutSubviews { [super layoutSubviews]; // Center Title View UINavigationItem* item = [self topItem]; // (Current navigation item) [item.titleView setCenter:CGPointMake(160.0, 22.0)]; // (...Hard-coded; Assuming portrait iPhone/iPod touch) } 

…它就像一个魅力。 推视图控制器时的幻灯片/淡入淡出效果完好无损。 (iOS 5.0)

我有类似的问题。 在这里输入图像说明 我的解决scheme是隐藏原来的后退button,添加你自己的实现。 由于系统将为左边的物品预留空间。

 UIImage* cancelIcon = [UIImage imageNamed:@"ic_clear"]; UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc] initWithImage:cancelIcon style:UIBarButtonItemStylePlain target:self action:@selector(back:)]; 

而select器很简单

 - (void)back:(UIButton *) sender { [self.navigationController popViewControllerAnimated:YES]; } 

现在看起来像这样: 在这里输入图像说明

哦…不要忘记在自定义标题视图中使用自动布局,如果你有dynamic长度的内容,如标签。 我在自定义视图中添加了一个额外的布局,在Android中将其设置为“wrap_content”,方法是将其设置为居中,并将前后空格“> =”0

在这里输入图像说明

我有一个类似的情况,一个titleView应该居中在UINavigationBar中。 我喜欢occulus的子类UIView和重写setFrame: 。 然后,我可以将框架放在UINavigationBar的尺寸内。

在UIView子类中:

 -(void)setFrame:(CGRect)frame{ super.frame = CGRectMake(320 / 2 - 50, 44 / 2 - 15, 100, 30); } 

然后,UIView子类可以正常分配给每个navigationItem的titleView 。 开发人员不必以编程方式从UINavigationBar添加和删除特殊的子视图。