ios UINavigationItem 居中标题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8258879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UINavigationItem centering the title
提问by Neelesh
I have a navigationBar with both Left and Right bar buttons on each side. I have a customTitlelabel
which I set as the titleView of the UINavigationItem
.
我有一个带有左右栏按钮的导航栏。我有一个customTitlelabel
我设置为UINavigationItem
.
[self.navigationItem setTitleView:customTitleLabel];
[self.navigationItem setTitleView:customTitleLabel];
All is fine now. The problem, the size of the rightbarButton is dynamic based on the input I get in one of the text fields.
现在一切都很好。问题是,rightbarButton 的大小是基于我在其中一个文本字段中获得的输入而动态变化的。
Therefore the title is automatically centered based on the available space between the buttons.
因此,标题会根据按钮之间的可用空间自动居中。
how can i set the title to a fixed position?
如何将标题设置为固定位置?
采纳答案by occulus
You can't do what you want directly -- the position of your title view is out of your control (when managed by UINavigationBar
).
你不能直接做你想做的——你的标题视图的位置不受你的控制(当由 管理时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.)
1) 添加标题视图不是作为导航栏的“正确”标题视图,而是作为UINavigationBar
. (注意:这不是“官方”批准的,但我已经看到它完成并工作。显然你必须注意你的标题标签覆盖按钮的位,并处理不同方向的不同大小的导航栏等。 ——有点啰嗦。)
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.
2)创建一个智能的 UIView 子类,在计算出的位置显示给定的子视图(这将是您的 UILabel),以有效地在屏幕上完美地显示子视图。为此,您的智能 UIView 子类将frame
通过更改frame
标签子视图的位置 ( )来响应布局事件(或属性更改等)。
Personally, I like the idea of approach 2) the best.
就个人而言,我最喜欢方法 2) 的想法。
回答by followben
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.
设置导航栏的 titleView 属性工作正常 - 除了自定义视图的框架之外,无需子类化或更改任何框架。
The trick to getting it centered relative to the overall width of UINavigationBar is to:
让它相对于 UINavigationBar 的整体宽度居中的技巧是:
- set the width of your view according to the size of the text
- set the alignment to centered and
- set the autoresizingmask so it gets resized to the available space
- 根据文本的大小设置视图的宽度
- 将对齐设置为居中并
- 设置 autoresizingmask 使其调整到可用空间
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:
下面是一些示例代码,它创建一个带有标签的自定义 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;
回答by neoneye
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.topItem?.title = ""
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
navigationItem.title = "Make peace soon"
}
回答by Ben Sinclair
The right answer is to override sizeThatFits:
of your custom titleView
and return its content size. Navigation bar centers custom title view until it has no space left to do that.
正确的答案是覆盖sizeThatFits:
您的自定义titleView
并返回其内容大小。导航栏将自定义标题视图居中,直到没有剩余空间来执行此操作。
For example if you have UIView
container with UILabel
inside:
例如,如果您有内部的UIView
容器UILabel
:
@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
回答by Nicolas Miari
I tried aopsfan's answer but it didn't work. A breakpoint revealed that the bar's center was "(480.0, 22.0)" (The X coordinate way off) .
我尝试了 aopsfan 的回答,但没有用。断点显示条形的中心是 "(480.0, 22.0)" (X 坐标偏离)。
So I changed it into this:
所以我把它改成了这样:
- (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)
}
...and it works like a charm. The slide/fade effect when pushing view controllers is intact. (iOS 5.0)
...它就像一个魅力。推送视图控制器时的滑动/淡入淡出效果完好无损。(iOS 5.0)
回答by Nevin Chen
I had similar problem.
My solution is do hide the original back button, add add your own implementation. Since the system will reserve space for the left items.
我有类似的问题。
我的解决方案是隐藏原来的后退按钮,添加添加您自己的实现。因为系统会为剩下的物品保留空间。
UIImage* cancelIcon = [UIImage imageNamed:@"ic_clear"];
UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc] initWithImage:cancelIcon style:UIBarButtonItemStylePlain target:self action:@selector(back:)];
and the selector is simple
选择器很简单
- (void)back:(UIButton *) sender
{
[self.navigationController popViewControllerAnimated:YES];
}
oh...and don't forget to use autolayout in your custom title view if you have dynamic length content like label in it. I add an additional layout in the customview to give it like "wrap_content" in Android by setting it centered to parent , and leading and trailing space ">=" 0
哦...如果您有动态长度内容(如标签),请不要忘记在自定义标题视图中使用自动布局。我在 customview 中添加了一个额外的布局,通过将它设置为以 parent 为中心,并在前导和尾随空间 ">=" 0
回答by Richard H Fung
I had a similar situation where a titleView
should be centered in UINavigationBar. I like occulus's approach of subclassing a UIView and overriding setFrame:
. Then, I can center the frame inside the dimensions of UINavigationBar.
我有一个类似的情况,atitleView
应该以 UINavigationBar 为中心。我喜欢 occulus 将 UIView 子类化并覆盖setFrame:
. 然后,我可以在 UINavigationBar 的维度内将框架居中。
In the UIView subclass:
在 UIView 子类中:
-(void)setFrame:(CGRect)frame{
super.frame = CGRectMake(320 / 2 - 50, 44 / 2 - 15, 100, 30);
}
The UIView subclass can then be assigned normally to titleView
for each navigationItem. The developer does not have to programmatically add and remove special subviews from UINavigationBar.
然后可以titleView
为每个导航项正常分配 UIView 子类。开发人员不必以编程方式从 UINavigationBar 中添加和删除特殊子视图。