可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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
.
[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.
Therefore the title is automatically centered based on the available space between the buttons.
how can i set the title to a fixed position?
回答1:
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.
回答2:
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:
- 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
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 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;
回答3:
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.topItem?.title = ""
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
navigationItem.title = "Make peace soon"
}
回答4:
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.
For example if you have UIView
container with UILabel
inside:
@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
回答5:
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) .
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)
回答6:
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];
}
now it looks like this:
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
回答7:
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.
In the UIView subclass:
-(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.