Navigation Controller内のNavigation Barで現在のNavigation Bar項目のtitleViewをオーバーライドする簡単な方法はありますか?新しいUIViewを作成し、topViewのtitleViewプロパティを自分のUIVIewに置き換えようとしましたが、成功しませんでした。
基本的に、ナビゲーションバーのタイトルに複数行のタイトルが必要です。助言がありますか?
titleView
のUINavigationItem
プロパティを設定します。たとえば、View ControllerのviewDidLoad
メソッドでは、次のようなことができます。
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 480, 44)];
label.backgroundColor = [UIColor clearColor];
label.numberOfLines = 2;
label.font = [UIFont boldSystemFontOfSize: 14.0f];
label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
label.textAlignment = UITextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.text = @"This is a\nmultiline string";
self.navigationItem.titleView = label;
#if !__has_feature(objc_arc)
[label release];
#endif
次のように表示されます。
titleView
プロパティが 無視 である場合、leftBarButtonItem
がnil
ではないことに注意してください。
swiftの場合:
let label = UILabel(frame: CGRectMake(0, 0, UIScreen.main.bounds.width, 44))
label.backgroundColor = UIColor.clearColor()
label.numberOfLines = 0
label.textAlignment = NSTextAlignment.Center
label.text = "multiline string"
self.navigationItem.titleView = label
for Swift 4:
let label = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: 44.0))
label.backgroundColor = UIColor.clear
label.numberOfLines = 0
label.textAlignment = NSTextAlignment.center
label.text = "first line\nsecond line"
self.navigationItem.titleView = label
迅速なソリューション:
NavigationBar
の2行:
private func setupTitleView() {
let topText = NSLocalizedString("key", comment: "")
let bottomText = NSLocalizedString("key", comment: "")
let titleParameters = [NSForegroundColorAttributeName : UIColor.<Color>(),
NSFontAttributeName : UIFont.<Font>]
let subtitleParameters = [NSForegroundColorAttributeName : UIColor.<Color>(),
NSFontAttributeName : UIFont.<Font>]
let title:NSMutableAttributedString = NSMutableAttributedString(string: topText, attributes: titleParameters)
let subtitle:NSAttributedString = NSAttributedString(string: bottomText, attributes: subtitleParameters)
title.appendAttributedString(NSAttributedString(string: "\n"))
title.appendAttributedString(subtitle)
let size = title.size()
let width = size.width
guard let height = navigationController?.navigationBar.frame.size.height else {return}
let titleLabel = UILabel(frame: CGRectMake(0,0, width, height))
titleLabel.attributedText = title
titleLabel.numberOfLines = 0
titleLabel.textAlignment = .Center
navigationItem.titleView = titleLabel
}
BarButton
の2行
let string = NSLocalizedString("key", comment: "")
let attributes = [NSForegroundColorAttributeName : UIColor.<Color>,
NSFontAttributeName : UIFont.<Font>]
let size = (string as NSString).sizeWithAttributes(attributes)
guard let height = navigationController?.navigationBar.frame.size.height else {return}
let button:UIButton = UIButton(frame: CGRectMake(0, 0, size.width, height))
button.setAttributedTitle(NSAttributedString(string: string, attributes: attributes), forState: .Normal)
button.addTarget(self, action: #selector(<SELECTOR>), forControlEvents: .TouchUpInside)
button.titleLabel?.numberOfLines = 0
button.titleLabel?.textAlignment = .Right
let rightBarButton = UIBarButtonItem(customView: button)
navigationItem.rightBarButtonItem = rightBarButton
結果-
多くの調整を行った後、私はまだiOS 8でpetertのソリューションを動作させることができませんでした。iOS8/9のコピーアンドペースト可能なソリューションを次に示します。クレジットは Matt Curtisのgithub投稿
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if(!self.navigationItem.titleView){
self.navigationItem.titleView = ({
UILabel *titleView = [UILabel new];
titleView.numberOfLines = 0;
titleView.textAlignment = NSTextAlignmentCenter;
titleView.attributedText = [[NSAttributedString alloc] initWithString:@"2\nLINES" attributes:
self.navigationController.navigationBar.titleTextAttributes
];
[titleView sizeToFit];
// You'll need to set your frame otherwise if your line breaks aren't explcit.
titleView;
});
}
}
ラベルが中央にない場合の対処方法
私と同じ問題が発生した場合、そのラベルは戻るボタンのためにnavigationItemの中央に配置されません。UILabelをUIViewに埋め込みます。 UILabelは、テキストで拡大することを強制されませんが、幅がビューの幅を上げると拡大を停止します。この問題の詳細については、こちらをご覧ください。 戻るボタンがあるため、ナビゲーションバーの中央にtitleViewを設定できません (ダレンの答え)
中央揃えではありません:
- (void)setTwoLineTitle:(NSString *)titleText color:(UIColor *)color font:(UIFont *)font {
CGFloat titleLabelWidth = [UIScreen mainScreen].bounds.size.width/2;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)];
label.backgroundColor = [UIColor clearColor];
label.numberOfLines = 2;
label.font = font;
label.adjustsFontSizeToFitWidth = YES;
label.textAlignment = UITextAlignmentCenter;
label.textColor = color;
label.text = titleText;
self.navigationItem.titleView = label;
}
中央揃え:
- (void)setTwoLineTitle:(NSString *)titleText color:(UIColor *)color font:(UIFont *)font {
CGFloat titleLabelWidth = [UIScreen mainScreen].bounds.size.width/2;
UIView *wrapperView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleLabelWidth, 44)];
label.backgroundColor = [UIColor clearColor];
label.numberOfLines = 2;
label.font = font;
label.adjustsFontSizeToFitWidth = YES;
label.textAlignment = UITextAlignmentCenter;
label.textColor = color;
label.text = titleText;
[wrapperView addSubview:label];
self.navigationItem.titleView = wrapperView;
}
Swift複数行タイトルを処理するバージョンは次のとおりです。
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
label.backgroundColor = .clear
label.numberOfLines = 0
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 14.0)
label.text = "This is a Multi-Line title of UINavigationBar"
self.navigationItem.titleView = label
}
ここにSwift 4の方法があります-
let upperTitle = NSMutableAttributedString(string: "\(text1)", attributes: [NSAttributedStringKey.font: UIFont(name: "SFProDisplay-Heavy", size: 17)!])
let lowerTitle = NSMutableAttributedString(string: "\n\((text2)!)", attributes: [NSAttributedStringKey.font: UIFont(name: "SFProText-Light", size: 11)! , NSAttributedStringKey.foregroundColor: UIColor(hex: "#607D8B")])
upperTitle.append(lowerTitle)
let label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 400, height:44))
label1.numberOfLines = 0
label1.textAlignment = .center
label1.attributedText = upperTitle //assign it to attributedText instead of text
self.navigationItem.titleView = label1
Swift 4
extension UINavigationItem {
@objc func setTwoLineTitle(lineOne: String, lineTwo: String) {
let titleParameters = [NSAttributedStringKey.foregroundColor : UIColor.white,
NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 17)] as [NSAttributedStringKey : Any]
let subtitleParameters = [NSAttributedStringKey.foregroundColor : UIColor.flatWhite(),
NSAttributedStringKey.font : UIFont.systemFont(ofSize: 12)] as [NSAttributedStringKey : Any]
let title:NSMutableAttributedString = NSMutableAttributedString(string: lineOne, attributes: titleParameters)
let subtitle:NSAttributedString = NSAttributedString(string: lineTwo, attributes: subtitleParameters)
title.append(NSAttributedString(string: "\n"))
title.append(subtitle)
let size = title.size()
let width = size.width
let height = CGFloat(44)
let titleLabel = UILabel(frame: CGRect.init(x: 0, y: 0, width: width, height: height))
titleLabel.attributedText = title
titleLabel.numberOfLines = 0
titleLabel.textAlignment = .center
titleView = titleLabel
}
}
フォント、色、ナビゲーションバーの高さはここにハードコードされています。
@gbkのソリューションを除くほとんどのソリューションでは、UIView(ラッパービュー)とUILabelにハードコーディングされた高さ44ptを使用します。すべてはコードによって作成されます。ナビゲーションバーの高さを動的に読み取る@gbkソリューションを見落としていました。
IOS 11(iPhone 5s)でorientation = landscape
のときに問題に遭遇しました。ラベルの高さは調整されず、横方向に1行のテキストを設定すると、テキストはナビゲーションバーの下部に揃えられます。
どういうわけか、StoryboardにUILabelを追加して、そのためのIBOutletを作成できることがわかりました。もっといいじゃないですか?
Navigation Item
の下に表示されます。IBOutlet
を作成し、通常どおり使用できます。テキストのサイズを変えるには、属性文字列を使用します(上記の解決策がたくさんあります)。IOS 11.2.6を搭載したiPhone 5sでテストしました。テキストは問題なく中央に配置され、ポートレートとランドスケープで正常に動作します。