无法在导航栏的中心设置titleView,因为后退按钮

时间:2015-01-24 01:39:45

标签: ios objective-c uinavigationbar

我使用图片视图在导航栏中显示图片。问题在于,由于后退按钮,我无法将其正确设置到中心。我检查了相关问题,并且在我解决之前遇到了几乎相同的问题,但这次我不知道。

之前我用假条形按钮解决了这个问题,所以我尝试在右侧(和左侧)添加假条形按钮,但它没有帮助。

- (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在同一侧有条形按钮。是否有任何解释为什么它可以使用以编程方式创建但不能与常用后退按钮一起使用的条形按钮?

9 个答案:

答案 0 :(得分:92)

只要有足够的空间,

UINavigationBar会自动将其titleView居中。如果标题没有居中,这意味着标题视图太宽而无法居中,如果你设置了backgroundColor,如果你UIImageView你会看到正是发生了什么

标题视图太宽,因为该导航栏会使用-sizeThatFits:自动调整标题大小以保存其内容。这意味着您的标题视图将始终调整为图像大小。

两种可能的修复方法:

  1. 您使用的图片太大了。使用尺寸合适的44x44 pt图像,2x和3x版本。

  2. 在常规UIView中包装UIImageView以避免调整大小。

  3. 示例:

    UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"test.jpeg"]];
    imageView.contentMode = UIViewContentModeScaleAspectFit;
    
    UIView* titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
    imageView.frame = titleView.bounds;
    [titleView addSubview:imageView];
    
    self.navigationItem.titleView = titleView;
    

答案 1 :(得分:14)

Darren的第二种方式 Swift 3 版本中的一个例子:

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

答案 2 :(得分:7)

我建议你覆盖函数 - (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始终是正确的位置

答案 3 :(得分:5)

不要使用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];

答案 4 :(得分:5)

群力对我很有帮助。这是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 :(得分:2)

我创建了一个自定义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()的最佳位置分别位于视图控制器的viewWillAppear()viewWillDisappear()方法中:

class YourViewController: UIViewController {

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

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

答案 6 :(得分:1)

1)您可以尝试通过调用

将图像设置为UINavigationBar的背景图像
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"color.png"] forBarMetrics:UIBarMetricsDefault];

viewDidLoad方法中。

这样它将始终居中,但如果你有一个带有长标题的back按钮作为左侧导航项,它可以显示在你的徽标顶部。您可能应该首先创建与导航栏大小相同的另一个图像,然后在其中心绘制图像,然后将其设置为背景图像。

2)或者不是将图片视图设置为titleView,您可以尝试简单地将其添加为子视图,因此它不会有与左右栏条项相关的约束。

答案 7 :(得分:1)

在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

      }

答案 8 :(得分:0)

扩展Darren的答案,对我来说修复是返回sizeThatFits UILabel的{​​{1}}。事实证明,这是在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)