web-dev-qa-db-ja.com

UINavigationBarのカスタムタイトルを中央に配置しますか?

カスタムのUINavigationBarタイトルとカスタムの戻るボタンがあります。私の問題は、タイトルがiPhoneの中央に配置されていないことです。それはまるで私の戻るボタンがタイトルを右に押しているかのようです。どのように私はそれを中心にすることができますか?

int height = self.navigationController.navigationBar.frame.size.height;
int width = self.navigationController.navigationBar.frame.size.width;


UILabel *navLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width + 300, 20)];
navLabel.backgroundColor = [UIColor whiteColor];
navLabel.textColor = [UIColor redColor];
navLabel.font = [UIFont fontWithName:@"Helvetica" size:30];
navLabel.textAlignment = UITextAlignmentCenter;
self.navigationItem.titleView = navLabel;
[navLabel release];
((UILabel *)self.navigationItem.titleView).text = self.title;

ありがとう!

編集不要なコードを削除して、この画像を追加しました:

Picture of title off ceter

タイトルがボタンに対応するように押し込まれていることに注意してください。

17
itgiawa

初期化するフレームは常に300+幅ピクセルであるため、iOSはこれを実行しています。それは完全なフレームを中央に配置しようとしています、フレームはそれが収まりたいスペースよりも大きいので(ボタンのため)、ラベルは右に押し出されます。あなたがする必要があるのは、navLabelのフレームに必要な最小サイズを与えることです。

したがって、テキストの幅が100pxのみでフレームが400pxの場合、iOSは400pxをナビゲーションヘッダーの中央に配置しようとしているため、十分なスペースがありません。サイズを実際に必要な100pxに設定すると、100pxを中央に配置するための十分なスペースがあるため、iOSはヘッダーを正しく中央に配置します。

以下のコードスニペットは、挿入するフォントとテキストに応じて、フレームに必要な最小サイズを検出するのに役立ちます。ラベルのフレームはできるだけ小さくし、最大幅を超えないようにしてください。 (ナビゲーションバーの幅)。

UIFont* titleFont = [UIFont fontWithName:@"Helvetica" size:30];
CGSize requestedTitleSize = [titleText sizeWithAttributes:@{NSFontAttributeName: titleFont}]; 
CGFloat titleWidth = MIN(maxTitleWidth, requestedTitleSize.width);

UILabel *navLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleWidth, 20)];
navLabel.backgroundColor = [UIColor whiteColor];
navLabel.textColor = [UIColor redColor];
navLabel.font = [UIFont fontWithName:@"Helvetica" size:30];
navLabel.textAlignment = NSTextAlignmentCenter;
navLabel.text = titleText;
self.navigationItem.titleView = navLabel;

Swift 5.0

    let titleFont = UIFont.systemFont(ofSize: 17.0)
    let title = "My Title"
    let titleSize = title.size(withAttributes: [.font: titleFont])

    let frame = CGRect(x: 0, y: 0, width: titleSize.width, height: 20.0)
    let titleLabel = UILabel(frame: frame)
    titleLabel.font = titleFont
    titleLabel.textColor = .red
    titleLabel.textAlignment = .center
    titleLabel.text = title
    navigationItem.titleView = titleLabel
41
Bocaxica

以前にも同じ問題がありました。右ボタンと左ボタンのあるUINavigationbarがありました。画像をUINavigationbarの中央に配置したい。したがって、UIView 0を使用してwidthに画像を配置する必要がありました。画像自体は、独自のwidthの半分であるx値を取得します。

UINavigationItem *item = navigationController.topViewController.navigationItem;
UIView *backView =[[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 30)];
[img_logo setFrame:CGRectMake(-45, 5, 90, 20)];
[backView addSubview:img_logo];
item.titleView = backView;
5
BHuelse

素敵な答え!ただし、sizeWithFontは非推奨になりました。あなたは今、このようなことをしたいと思うでしょう。

NSDictionary *textTitleOptions = [NSDictionary dictionaryWithObjectsAndKeys:  [UIFont fontWithName:@"Helvetica" size:30], NSFontAttributeName, nil];

CGSize requestedTitleSize = [[NSString stringWithFormat:@"Your String"] sizeWithAttributes:textTitleOptions];

CGFloat titleWidth = MIN(self.view.frame.size.width, requestedTitleSize.width);

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, titleWidth, 44)];
3
Luke

この問題を解決するために自動レイアウト制約を使用しました:

  1. UILabelをUIViewに追加します。
  2. UILabelのcenterXの制約を設定します。

    _self.titleLabelCenterXConstraint = [NSLayoutConstraint constraintWithItem:self.titleLabel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f];_

  3. UIView layoutSubViewsで、centerXオフセット値を調整します。

    - (void)layoutSubviews { [super layoutSubviews]; CGFloat screenCenter = CGRectGetMidX([UIScreen mainScreen].bounds); CGFloat diffCenter = screenCenter - CGRectGetMidX(self.frame); self.titleLabelCenterXConstraint.constant = diffCenter; }

  4. uIViewをnavigationItem titleViewに設定します

2
Yang Young

@BHuelseの回答に対するSwift 3:

let image = UIImage(named: "logo")
let logoView = UIView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 30))
let imageView = UIImageView(frame: CGRect(x: -45, y: 5, width: 90, height: 20))
imageView.image = image
imageView.contentMode = .scaleAspectFit
logoView.addSubview(imageView)
self.navigationItem.titleView = logoView
1

Swift 2.3:

    let tlabel = UILabel(frame: CGRectMake(0, 0, 200, 40))
    tlabel.text = self.title
    tlabel.textColor = UIColor.whiteColor()
    tlabel.font = UIFont.boldSystemFontOfSize(17) //UIFont(name: "Helvetica", size: 17.0)
    tlabel.backgroundColor = UIColor.clearColor()
    tlabel.adjustsFontSizeToFitWidth = true
    tlabel.textAlignment = .Center
    self.navigationItem.titleView = tlabel
1
Unit Testing

タイトルはナビゲーションバー自体の中央に配置されません。ナビゲーションバーの左ボタンと右ボタンの中央に配置されます。つまり、左側に大きなボタンがある場合、タイトルは右側に移動します。

タイトルに中央揃えの制約を追加し、それを変更して実際にナビゲーションバーの中央になるように、中央を変更できます。

// Position the title in the middle of the navbar and not in the middle of buttons
fileprivate func centerTitle () {
    if let navigation = self.navigationController {
        let titleMiddle = navigation.navigationBar.convert(titleViewLabel.frame, from: titleViewLabel.superview).midX
        let diff = navigation.navigationBar.center.x - titleMiddle
        constraintTitleViewCentered.constant += diff
    }
}
0
CedricSoubrie