web-dev-qa-db-ja.com

戻るボタンがあるため、ナビゲーションバーの中央にtitleViewを設定できません

画像ビューを使用して、ナビゲーションバーに画像を表示しています。問題は、戻るボタンが原因で中央に正しく設定できないことです。関連する質問を確認し、以前に解決した問題とほぼ同じ問題がありましたが、今回はわかりません。

以前、私はこの問題を偽のバーボタンで解決しました。そのため、右側(および左側)に偽のバーボタンを追加しようとしましたが、助けにはなりませんでした。

- (void) searchButtonNavBar {


    CGRect imageSizeDummy = CGRectMake(0, 0, 25,25);

    UIButton *dummy = [[UIButton alloc] initWithFrame:imageSizeDummy];

    UIBarButtonItem
    *searchBarButtonDummy =[[UIBarButtonItem alloc] initWithCustomView:dummy];
    self.navigationItem.rightBarButtonItem = searchBarButtonDummy;

}


- (void)setNavBarLogo {

    [self setNeedsStatusBarAppearanceUpdate];
    CGRect myImageS = CGRectMake(0, 0, 44, 44);
    UIImageView *logo = [[UIImageView alloc] initWithFrame:myImageS];
    [logo setImage:[UIImage imageNamed:@"color.png"]];
    logo.contentMode = UIViewContentModeScaleAspectFit;
    self.navigationItem.titleView = logo;
    [[UIBarButtonItem appearance] setTitlePositionAdjustment:UIOffsetMake(0.0f, 0.0f) forBarMetrics:UIBarMetricsDefault];

}

この場合、titleViewの同じ側にバーボタンがあるため、正常に機能するはずです。プログラムで作成されたバーボタンで機能するが、一般的な戻るボタンでは機能しない理由はありますか?

48
rihe

Swift Darrenの2番目の方法のバージョンの例:

let imageView = UIImageView(image: UIImage(named: "test"))
    imageView.contentMode = UIViewContentMode.scaleAspectFit
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
    imageView.frame = titleView.bounds
    titleView.addSubview(imageView)

self.navigationItem.titleView = titleView
16
pedrouan

関数をオーバーライドすることをお勧めします-(void)setFrame:(CGRect)framこのように:

- (void)setFrame:(CGRect)frame  { 

    [super setFrame:frame]; //systom function

    self.center = CGPointMake(self.superview.center.x, self.center.y);   //rewrite function 

}

titleView.centerが常に正しい場所になるように

7
Qun Li

TitleViewを使用しないでください。

画像をnavigationController.navigationBarに追加するだけです

CGRect myImageS = CGRectMake(0, 0, 44, 44);
UIImageView *logo = [[UIImageView alloc] initWithFrame:myImageS];
[logo setImage:[UIImage imageNamed:@"color.png"]];
logo.contentMode = UIViewContentModeScaleAspectFit;
logo.center = CGPointMake(self.navigationController.navigationBar.width / 2.0, self.navigationController.navigationBar.height / 2.0);
logo.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
[self.navigationController.navigationBar addSubview:logo];
5
PowHu

Qun Liは私にとって完璧に働いた。 Swift 2.3コード:

override var frame: CGRect {
    set(newValue) {
        super.frame = newValue

        if let superview = self.superview {
            self.center = CGPoint(x: superview.center.x, y: self.center.y)
        }
    }

    get {
        return super.frame
    }
}
5
mikezs

Nibからカスタムビューを使用している場合は、nibファイルの自動レイアウトを必ず無効にしてください。

3
joslinm

私はカスタムUINavigationControllerを作成しました。ドロップイン後、あなたがしなければならないのは、表示したいときにshowNavBarTitle(title:font:)を、非表示にしたいときにremoveNavBarTitle()を呼び出すことだけです:

_class NavigationController: UINavigationController {

    private static var mTitleFont = UIFont(name: <your desired font (String)> , size: <your desired font size -- however, font size will automatically adjust so the text fits in the label>)!
    private static var mNavBarLabel: UILabel = {

        let x: CGFloat = 60
        let y: CGFloat = 7
        let label = UILabel(frame: CGRect(x: x, y: y, width: UIScreen.main.bounds.size.width - 2 * x, height: 44 - 2 * y))

        label.adjustsFontSizeToFitWidth = true
        label.minimumScaleFactor = 0.5
        label.font = NavigationController.mTitleFont
        label.numberOfLines = 0
        label.textAlignment = .center

        return label
    }()

    func showNavBarLabel(title: String, font: UIFont = mTitleFont) {
        NavigationController.mNavBarLabel.text = title
        NavigationController.mNavBarLabel.font = font
        navigationBar.addSubview(NavigationController.mNavBarLabel)
    }

    func removeNavBarLabel() {
        NavigationController.mNavBarLabel.removeFromSuperview()
    }
}
_

showNavBarTitle(title:font:)removeNavBarTitle()を呼び出す最適な場所は、それぞれView ControllerのviewWillAppear()viewWillDisappear()メソッドにあります。

_class YourViewController: UIViewController {

    func viewWillAppear() {
        (navigationController as! NavigationController).showNavBarLabel(title: "Your Title")
    }

    func viewWillDisappear() {
        (navigationController as! NavigationController).removeNavBarLabel()
    }
}
_
2
shoe

1)を呼び出して、画像をUINavigationBarの背景画像として設定してみてください。

[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"color.png"] forBarMetrics:UIBarMetricsDefault];

viewDidLoadメソッド内。

そのようにすると、常に中央に配置されますが、左側のナビゲーションアイテムとして長いタイトルのbackボタンがある場合、ロゴの上に表示できます。そして、おそらく最初にナビゲーションバーと同じサイズの別の画像を作成し、その中央に画像を描画し、その後それを背景画像として設定する必要があります。

2)または、画像ビューをtitleViewとして設定する代わりに、サブビューとして追加するだけでよいので、左右のバーボタン項目に関連する制約はありません。

1
bzz

Swiftでは、これは私にとってうまくいったものですが、それは最良の解決策ではありません(基本的に、navigationBarに追加してください):

    let titleIV = UIImageView(image: UIImage(named:"some"))
        titleIV.contentMode = .scaleAspectFit
        titleIV.translatesAutoresizingMaskIntoConstraints = false

      if let navigationController = self.navigationController{
            navigationController.navigationBar.addSubview(titleIV)
            titleIV.centerXAnchor.constraint(equalTo:  
navigationController.navigationBar.centerXAnchor).isActive = true
            titleIV.centerYAnchor.constraint(equalTo: navigationController.navigationBar.centerYAnchor).isActive = true
      }
      else{
            view.addSubview(titleIV)
            titleIV.topAnchor.constraint(equalTo: view.topAnchor, constant: UIApplication.shared.statusBarFrame.height).isActive = true
            titleIV.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true

      }

Darrenの答えを拡張して、私の修正はsizeThatFitsサイズでUILabelを返すことでした。これは、layoutSubViewsの後に呼び出されるため、ラベルにはサイズがあります。

override func sizeThatFits(_ size: CGSize) -> CGSize {
    return CGSize(width: titleLabel.frame.width + titleInset*2, height: titleLabel.frame.height)
}

また、+ titleInset*2は、次のように水平方向の制約を設定しているためです。

titleLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: titleInset),
titleLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -titleInset)
0
richy