我有一个导航栏,每侧都有左右两个按钮。我有一个customTitlelabel
,我将其设置为UINavigationItem
的titleView。
[self.navigationItem setTitleView:customTitleLabel];
一切都很好。问题是,rightbarButton的大小是动态的,基于我在其中一个文本字段中得到的输入。
因此,标题会根据按钮之间的可用空间自动居中。
如何将标题设置为固定位置?
答案 0 :(得分:28)
设置导航栏的titleView属性可以正常工作 - 无需子类化或更改自定义视图以外的任何帧。
让它相对于UINavigationBar的整体宽度居中的技巧是:
下面是一些示例代码,它创建一个带有标签的自定义titleView,该标签在UINavigationBar中保持居中,无论方向,左侧或右侧条形图宽度如何:
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;
答案 1 :(得分:15)
您无法直接执行所需内容 - 标题视图的位置超出您的控制范围(由UINavigationBar
管理时)。
但是,至少有两种策略可以达到你想要的效果:
1)将标题视图添加为导航栏的“正确”标题视图,但作为UINavigationBar
的子视图。 (注意:这不是'正式'批准,但我已经看到它完成了,并且工作。显然你必须注意你的标题标签覆盖按钮的位,并处理不同方向的不同尺寸的导航条等。 - 有点繁琐。)
2)制作一个智能的UIView子类,在一个计算的位置显示一个给定的子视图(可能是你的UILabel),以有效地显示子视图完全居中在屏幕上。为此,您的智能UIView子类将通过更改标签子视图的位置(frame
)来响应布局事件(或frame
属性更改等)。
就个人而言,我最喜欢方法2)的想法。
答案 2 :(得分:12)
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.topItem?.title = ""
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
navigationItem.title = "Make peace soon"
}
答案 3 :(得分:3)
正确的答案是覆盖自定义sizeThatFits:
的{{1}}并返回其内容大小。导航栏将自定义标题视图居中,直到它没有空间来执行此操作。
例如,如果您的titleView
容器内有UIView
:
UILabel
答案 4 :(得分:2)
我尝试了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)
答案 5 :(得分:1)
我有类似的问题。 我的解决方案是隐藏原始的后退按钮,添加添加自己的实现。由于系统将为左侧物品预留空间。
UIImage* cancelIcon = [UIImage imageNamed:@"ic_clear"];
UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc] initWithImage:cancelIcon style:UIBarButtonItemStylePlain target:self action:@selector(back:)];
,选择器很简单
- (void)back:(UIButton *) sender
{
[self.navigationController popViewControllerAnimated:YES];
}
哦...如果你有像标签一样的动态长度内容,请不要忘记在自定义标题视图中使用自动布局。我在customview中添加了一个额外的布局,以便像#34; wrap_content"在Android中,通过将其设置为父级,以及前导和尾随空格"> =" 0
答案 6 :(得分:0)
我有类似的情况,titleView
应该在UINavigationBar中居中。我喜欢occulus的子类化UIView并覆盖setFrame:
的方法。然后,我可以将框架置于UINavigationBar维度的中心。
在UIView子类中:
-(void)setFrame:(CGRect)frame{
super.frame = CGRectMake(320 / 2 - 50, 44 / 2 - 15, 100, 30);
}
然后可以为每个navigationItem将UIView子类正常分配给titleView
。开发人员不必以编程方式添加和删除UINavigationBar中的特殊子视图。