我想在我的UINavigationBar里面有一个titleView,它有两行文字而不是一行
当我有一个“Back”-Button和一个“Edit”按钮时,我当前的实现效果很好,因为它看起来几乎居中。问题是我只有一个按钮。它看起来非常奇怪和错误,因为视图集中在可用空间上。
UINavigationBar with left and right Button
UINavigationBar with only one Button
这是我目前的实施:
CGRect frame = self.navigationController.navigationBar.frame;
UIView *twoLineTitleView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetWidth(frame), 0, CGRectGetWidth(frame), CGRectGetHeight(frame))];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 8, CGRectGetWidth(frame), 14)];
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
titleLabel.textAlignment = UITextAlignmentCenter;
titleLabel.text = self.title;
[twoLineTitleView addSubview:titleLabel];
UILabel *subTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 23, CGRectGetWidth(frame), 14)];
subTitleLabel.backgroundColor = [UIColor clearColor];
subTitleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
subTitleLabel.textAlignment = UITextAlignmentCenter;
subTitleLabel.text = self.subTitle;
[twoLineTitleView addSubview:subTitleLabel];
self.navigationItem.titleView = twoLineTitleView;
答案 0 :(得分:29)
我将如何做到这一点:
此代码适用于您:
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.textColor = [UIColor whiteColor];
titleLabel.font = [UIFont boldSystemFontOfSize:20];
titleLabel.text = @"Your Title";
[titleLabel sizeToFit];
UILabel *subTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 22, 0, 0)];
subTitleLabel.backgroundColor = [UIColor clearColor];
subTitleLabel.textColor = [UIColor whiteColor];
subTitleLabel.font = [UIFont systemFontOfSize:12];
subTitleLabel.text = @"Your subtitle";
[subTitleLabel sizeToFit];
UIView *twoLineTitleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, MAX(subTitleLabel.frame.size.width, titleLabel.frame.size.width), 30)];
[twoLineTitleView addSubview:titleLabel];
[twoLineTitleView addSubview:subTitleLabel];
float widthDiff = subTitleLabel.frame.size.width - titleLabel.frame.size.width;
if (widthDiff > 0) {
CGRect frame = titleLabel.frame;
frame.origin.x = widthDiff / 2;
titleLabel.frame = CGRectIntegral(frame);
}else{
CGRect frame = subTitleLabel.frame;
frame.origin.x = abs(widthDiff) / 2;
subTitleLabel.frame = CGRectIntegral(frame);
}
self.navigationItem.titleView = twoLineTitleView;
Swift 3变体:
let titleLabel = UILabel.init(frame: CGRect.zero)
titleLabel.backgroundColor = UIColor.clear
titleLabel.textColor = UIColor.schBlack
titleLabel.font = UIFont.schTextStyle2Font()
titleLabel.text = titleString;
titleLabel.sizeToFit()
let subTitleLabel = UILabel.init(frame: CGRect.init(x: 0, y: 22, width: 0, height: 0))
subTitleLabel.backgroundColor = UIColor.clear
subTitleLabel.textColor = UIColor.schBrownishGrey
subTitleLabel.font = UIFont.schTextStyle3Font()
subTitleLabel.text = subTitleString;
subTitleLabel.sizeToFit()
let twoLineTitleView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: self.view.frame.width-40, height: 30))
twoLineTitleView.addSubview(titleLabel)
twoLineTitleView.addSubview(subTitleLabel)
/*
float widthDiff = subTitleLabel.frame.size.width - titleLabel.frame.size.width;
if (widthDiff > 0) {
CGRect frame = titleLabel.frame;
frame.origin.x = widthDiff / 2;
titleLabel.frame = CGRectIntegral(frame);
}else{
CGRect frame = subTitleLabel.frame;
frame.origin.x = abs(widthDiff) / 2;
subTitleLabel.frame = CGRectIntegral(frame);
}
*/
self.navigationItem.titleView = twoLineTitleView;
答案 1 :(得分:12)
另一种方法可能是使用prompt。
答案 2 :(得分:9)
Brian van den hovel为更好地集中标题和副标题提供了一些补充。
func setTitle(title:String, subtitle:String) -> UIView {
//Create a label programmatically and give it its property's
let titleLabel = UILabel(frame: CGRectMake(0, 0, 0, 0)) //x, y, width, height where y is to offset from the view center
titleLabel.backgroundColor = UIColor.clearColor()
titleLabel.textColor = UIColor.blackColor()
titleLabel.font = UIFont.boldSystemFontOfSize(17)
titleLabel.text = title
titleLabel.sizeToFit()
//Create a label for the Subtitle
let subtitleLabel = UILabel(frame: CGRectMake(0, 18, 0, 0))
subtitleLabel.backgroundColor = UIColor.clearColor()
subtitleLabel.textColor = UIColor.lightGrayColor()
subtitleLabel.font = UIFont.systemFontOfSize(12)
subtitleLabel.text = subtitle
subtitleLabel.sizeToFit()
// Create a view and add titleLabel and subtitleLabel as subviews setting
let titleView = UIView(frame: CGRectMake(0, 0, max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), 30))
// Center title or subtitle on screen (depending on which is larger)
if titleLabel.frame.width >= subtitleLabel.frame.width {
var adjustment = subtitleLabel.frame
adjustment.origin.x = titleView.frame.origin.x + (titleView.frame.width/2) - (subtitleLabel.frame.width/2)
subtitleLabel.frame = adjustment
} else {
var adjustment = titleLabel.frame
adjustment.origin.x = titleView.frame.origin.x + (titleView.frame.width/2) - (titleLabel.frame.width/2)
titleLabel.frame = adjustment
}
titleView.addSubview(titleLabel)
titleView.addSubview(subtitleLabel)
return titleView
}
答案 3 :(得分:9)
您还可以使用属性字符串来获得相同的结果:
let subtitleAttribute = [NSForegroundColorAttributeName: UIColor.grayColor() , NSFontAttributeName: UIFont.systemFontOfSize(12.0)]
let titleString = NSMutableAttributedString(string: "title" + "\n", attributes: [NSFontAttributeName: UIFont.boldSystemFontOfSize(17.0)])
let subtitleString = NSAttributedString(string: "subtitle", attributes: subtitleAttribute)
titleString.appendAttributedString(subtitleString)
let label = UILabel(frame: CGRectMake(0, 0, titleString.size().width, 44))
label.numberOfLines = 0
label.textAlignment = NSTextAlignment.Center
label.attributedText = titleString
self.navigationItem.titleView = label
Swift 3
let subtitleAttribute = [NSForegroundColorAttributeName: UIColor.gray , NSFontAttributeName: UIFont.systemFont(ofSize: 12.0)]
let titleString = NSMutableAttributedString(string: "title" + "\n", attributes: [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 17.0)])
let subtitleString = NSAttributedString(string: "subtitle", attributes: subtitleAttribute)
titleString.append(subtitleString)
let label = UILabel(frame: CGRect(x: 0, y: 0, width: titleString.size().width, height: 44))
label.numberOfLines = 0
label.textAlignment = NSTextAlignment.center
label.attributedText = titleString
self.navigationItem.titleView = label
答案 4 :(得分:3)
除github之外!这里。
我发现当我的字幕小于我的标题时,它不会正确格式化,这是正确的代码。
//Usage:
self.navigationItem.titleView = setTitle(varDec.currentDate(), subtitle: varDec.currentDay())
func setTitle(title:String, subtitle:String) -> UIView {
//Create a label programmatically and give it its property's
let titleLabel = UILabel(frame: CGRectMake(0, -5, 0, 0)) //x, y, width, height where y is to offset from the view center
titleLabel.backgroundColor = UIColor.clearColor()
titleLabel.textColor = UIColor.blackColor()
titleLabel.font = UIFont.boldSystemFontOfSize(17)
titleLabel.text = title
titleLabel.sizeToFit()
//Create a label for the Subtitle
// x, y, width, height where x is set to be half the size of the title (100/4 = 25%) as it starts all the way left.
let subtitleLabel = UILabel(frame: CGRectMake(titleLabel.frame.size.width / 4, 18, 0, 0))
subtitleLabel.backgroundColor = UIColor.clearColor()
subtitleLabel.textColor = UIColor.lightGrayColor()
subtitleLabel.font = UIFont.systemFontOfSize(12)
subtitleLabel.text = subtitle
subtitleLabel.sizeToFit()
/*Create a view and add titleLabel and subtitleLabel as subviews setting
* its width to the bigger of both
* this will crash the program if subtitle is bigger then title
*/
let titleView = UIView(frame: CGRectMake(0, 0, max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), 30))
titleView.addSubview(titleLabel)
titleView.addSubview(subtitleLabel)
return titleView
}
答案 5 :(得分:2)
https://www.reddit.com/r/swift/comments/3izq7b/style_guidelines_for_navigation_bar_prompts/
extension UINavigationItem {
//Make the title 2 lines with a title and a subtitle
func addTitleAndSubtitleToNavigationBar (title: String, subtitle: String) {
var label = UILabel(frame: CGRectMake(10.0, 0.0, 50.0, 40.0))
label.font = UIFont.boldSystemFontOfSize(14.0)
label.numberOfLines = 2
label.text = "\(title)\n\(subtitle)"
label.textColor = UIColor.blackColor()
label.sizeToFit()
label.textAlignment = NSTextAlignment.Center
self.titleView = label
}
}
答案 6 :(得分:1)
我通过完全替换标题视图来完成此操作。最终结果如下:
可以使用viewDidLoad
方法中的以下代码实现。
UIView * containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 220, 40)];
UILabel * titleLabel = [[UILabel alloc] init];
titleLabel.text = @"Ttitle";
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.font = [UIFont boldSystemFontOfSize:titleLabel.font.pointSize];
[containerView addSubview:titleLabel];
titleLabel.keepInsets.equal = 0;
titleLabel.keepBottomInset.equal = 10;
UILabel * subtitleLabel = [[UILabel alloc] init];
subtitleLabel.textAlignment = NSTextAlignmentCenter;
subtitleLabel.font = [UIFont italicSystemFontOfSize:12.0];
subtitleLabel.textColor = [UIColor lightGrayColor];
[containerView addSubview:subtitleLabel];
subtitleLabel.keepHeight.equal = 15;
subtitleLabel.keepWidth.equal = 200;
subtitleLabel.keepBottomInset.equal = 0;
subtitleLabel.keepHorizontalCenter.equal = 0.5;
subtitleLabel.text = @"Subtitle";
[self.navigationItem setTitleView:containerView];
为此,我使用了优秀的KeepLayout库。它产生如下结果:
答案 7 :(得分:0)
我正在使用罗德里戈·佩德罗索的answer,但事实上它没有截断长标题就成了问题。我制作了一个版本,用于衡量条形按钮项目之间标题的空间大小,然后手动截断标题以适应该空间。截断代码改编自this answer,有点乱 - 也许有人可以帮助找出一种方法来使用UILabel的内置截断方法(即.ByTruncatingTail)。我已经花了太多时间在这上面。
以下是我所拥有的:
extension UIViewController {
private var availableWidthForTitle: CGFloat {
get {
var total = UIScreen.mainScreen().bounds.width
if let navigationBar = navigationController?.navigationBar {
var maxYLeft: CGFloat = 0
var minYRight: CGFloat = 0
for subview in navigationBar.subviews.dropFirst()
where !subview.hidden {
if subview.frame.origin.x < total / 2 {
let rightEdge = subview.frame.origin.x + subview.frame.size.width
if rightEdge < total / 2 {
maxYLeft = max(maxYLeft, rightEdge)
}
} else {
let leftEdge = subview.frame.origin.x
if leftEdge > total / 2 {
minYRight = min(minYRight, total - leftEdge)
}
}
}
total = total - maxYLeft - minYRight
}
return total
}
}
func setTitle(title:String, subtitle:String?) {
if (subtitle == nil) {
self.title = title.uppercaseString
} else {
let titleLabel = UILabel(frame: CGRectMake(0, -2, 0, 0))
titleLabel.backgroundColor = UIColor.clearColor()
titleLabel.textColor = MaterialColor.white
titleLabel.font = RobotoFont.boldWithSize(17)
titleLabel.textAlignment = .Center
let availableWidth = availableWidthForTitle
let titleUppercase = NSString(string: title.uppercaseString)
if titleUppercase.boundingRectWithSize(
// if title needs to be truncated
CGSize(width: CGFloat.max, height: CGFloat.max),
options: NSStringDrawingOptions.UsesLineFragmentOrigin,
attributes: [NSFontAttributeName : titleLabel.font],
context: nil).width > availableWidth {
let truncTitle: NSMutableString = ""
for nextChar in title.uppercaseString.characters {
if truncTitle.boundingRectWithSize(
CGSize(width: CGFloat.max, height: CGFloat.max),
options: NSStringDrawingOptions.UsesLineFragmentOrigin,
attributes: [NSFontAttributeName : titleLabel.font],
context: nil).width > availableWidth - 16 { // for ellipsis + some margin
truncTitle.appendString("...")
break
} else {
truncTitle.appendString(String(nextChar))
}
}
titleLabel.text = truncTitle as String
} else {
// use title as-is
titleLabel.text = titleUppercase as String
}
titleLabel.sizeToFit()
let subtitleLabel = UILabel(frame: CGRectMake(0, 18, 0, 0))
subtitleLabel.backgroundColor = UIColor.clearColor()
subtitleLabel.textColor = MaterialColor.white
subtitleLabel.font = MaterialFont.italicSystemFontWithSize(10)
subtitleLabel.text = subtitle
subtitleLabel.sizeToFit()
let titleView = UIView(frame: CGRectMake(0, 0, max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), 30))
// Center title or subtitle on screen (depending on which is larger)
if titleLabel.frame.width >= subtitleLabel.frame.width {
var adjustment = subtitleLabel.frame
adjustment.origin.x = titleView.frame.origin.x + (titleView.frame.width/2) - (subtitleLabel.frame.width/2)
subtitleLabel.frame = adjustment
} else {
var adjustment = titleLabel.frame
adjustment.origin.x = titleView.frame.origin.x + (titleView.frame.width/2) - (titleLabel.frame.width/2)
titleLabel.frame = adjustment
}
titleView.addSubview(titleLabel)
titleView.addSubview(subtitleLabel)
self.navigationItem.titleView = titleView
}
}
}
答案 8 :(得分:0)
受@Ben Smiley的启发,我添加了一个砌体实现。
CGFloat width = 200;
CGFloat titleHeight = 25;
CGFloat containerHeight = 40;
UIView * containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, containerHeight)];
UILabel * titleLabel = [[UILabel alloc] init];
titleLabel.text = @"Title";
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.font = [UIFont boldSystemFontOfSize:titleLabel.font.pointSize];
[containerView addSubview:titleLabel];
[titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(0);
make.left.mas_equalTo(0);
make.right.mas_equalTo(0);
make.width.mas_equalTo(width);
make.height.mas_equalTo(titleHeight);
}];
UILabel * subtitleLabel = [[UILabel alloc] init];
subtitleLabel.textAlignment = NSTextAlignmentCenter;
subtitleLabel.font = [UIFont systemFontOfSize:12];
[containerView addSubview:subtitleLabel];
[subtitleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(0);
make.right.mas_equalTo(0);
make.top.mas_equalTo(titleLabel.mas_bottom);
make.width.mas_equalTo(width);
make.height.mas_equalTo(containerHeight - titleHeight);
}];
subtitleLabel.text = @"Subtitle";
[self.navigationItem setTitleView:containerView];