不能在导航栏的中心设置titleView因为后退按钮

[英]Can't set titleView in the center of navigation bar because back button


I'm using an image view to display an image in my nav bar. The problem is that I can't set it to the center correctly because of the back button. I checked the related questions and had almost the same problem earlier that I solved, but this time I have no idea.

我正在用一个图像视图在我的导航条中显示一个图像。问题是由于后退按钮,我不能正确地将它设置为中心。我检查了相关的问题,之前我已经解决了几乎相同的问题,但是这次我不知道。

Earlier I solved this problem with fake bar buttons, so I tried to add a fake bar button to the right (and left) side, but it doesn't helped.

之前我用假栏按钮解决了这个问题,所以我尝试在右边(和左边)添加一个假栏按钮,但是没有用。

- (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];

}

I think it should be workin fine because in this case the titleView has bar buttons on the same side. Is there any explanation why it worked with bar buttons that was created programmatically but doesn't works with the common back button?

我认为它应该可以很好地工作,因为在这个例子中,titleView在同一边有一个按钮。是否有任何解释可以解释为什么它使用以编程方式创建的bar按钮而不使用普通的back按钮?

10 个解决方案

#1


82  

UINavigationBar automatically centers its titleView as long as there is enough room. If the title isn't centered that means that the title view is too wide to be centered, and if you set the backgroundColor if your UIImageView you'll see that's exactly what is happening.

只要有足够的空间,UINavigationBar就会自动将它的titleView居中。如果标题没有居中那意味着标题视图太宽了,不能居中,如果你设置背景色如果你的UIImageView你会看到这就是正在发生的。

The title view is too wide because that navigation bar will automatically resize the title to hold its content, using -sizeThatFits:. This means that your title view will always be resized to the size of your image.

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

Two possible fixes:

两个可能的修复:

  1. The image you're using is way too big. Use a properly sized 44x44 pt image with 2x and 3x versions.

    你使用的图像太大了。使用一个大小合适的44x44 pt图像与2x和3x版本。

  2. Wrap UIImageView inside of a regular UIView to avoid resizing.

    将UIImageView包装在一个常规的UIView中,以避免调整大小。

Example:

例子:

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;

#2


10  

An example in Swift 3 version of Darren's second way:

一个例子,在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

#3


7  

I suggest you Override the function - (void)setFrame:(CGRect)fram like this:

我建议您重写这个函数(void)setFrame:(CGRect)

- (void)setFrame:(CGRect)frame  { 

    [super setFrame:frame]; //systom function

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

}

so that the titleView.center always the right location

titleView。在正确的位置居中

#4


6  

Don't use titleView.

不要使用titleView。

Just add your image to navigationController.navigationBar

只需将图像添加到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


5  

Qun Li's worked perfectly for me. Here's the swift 2.3 code:

李群很适合我。以下是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
    }
}

#6


3  

If you're using a custom view from a nib, be sure to disable auto-layout on the nib file.

如果您正在使用nib中的自定义视图,请确保禁用nib文件的自动布局。

#7


1  

1) You can try setting your image as UINavigationBar's background image by calling

1)您可以通过调用将您的图像设置为UINavigationBar的背景图像

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

inside the viewDidLoad method.

在viewDidLoad方法。

That way it will be always centered, but if you have back button with long title as left navigation item, it can appear on top of your logo. And you should probably at first create another image with the same size as the navigation bar, then draw your image at its center, and after that set it as the background image.

这样它就会始终居中,但是如果你有一个长标题为左导航项的后退按钮,它可以出现在你的徽标顶部。你应该首先创建一个与导航栏相同大小的图像,然后在它的中心画出你的图像,然后将它设置为背景图像。

2) Or instead of setting your image view as titleView, you can try simply adding at as a subview, so it won't have the constraints related to right and left bar button items.

2)或者不要将图像视图设置为titleView,您可以尝试将at添加为子视图,这样它就不会有与左右栏按钮项相关的约束。

#8


1  

I created a custom UINavigationController that after dropping in, the only thing you have to do is call showNavBarTitle(title:font:) when you want to show and removeNavBarTitle() when you want to hide:

我创建了一个自定义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()
    }
}

I find the best place to call showNavBarTitle(title:font:) and removeNavBarTitle() are in the view controller's viewWillAppear() and viewWillDisappear() methods, respectively:

我发现调用showNavBarTitle(标题:字体:)和removeNavBarTitle()的最佳位置分别位于视图控制器的viewWillAppear()和viewWillDisappear()方法中:

class YourViewController: UIViewController {

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

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

#9


1  

In Swift, this is what worked for me however it´s not the best solution (basically, add it up to navigationBar):

在迅速,这就是为我工作但是它´s不是最好的解决方案(基本上,将它添加到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

      }

#10


0  

Extending Darren's answer, a fix for me was to return a sizeThatFits with the UILabel size. It turns out that this is called after layoutSubViews so the label has a size.

扩大达伦的回答,对我来说,一个解决的办法是返回一个符合UILabel大小的sizethatfit。事实证明,这是在layoutSubViews之后调用的,因此标签有一个大小。

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

Also note that I have + titleInset*2 because Im setting the horizontal constraints like so:

还要注意,我有+ titleInset*2,因为我是这样设置水平约束的:

titleLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: titleInset),
titleLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -titleInset)
智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2015/01/24/6f99a9986acf775977df77f30c8601b2.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告