ios 由于后退按钮,无法在导航栏的中心设置 titleView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28121388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can't set titleView in the center of navigation bar because back button
提问by rihe
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
,同一侧有条形按钮。有什么解释为什么它可以与以编程方式创建但不适用于常见后退按钮的条形按钮一起使用?
回答by Darren
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
只要有足够的空间,它就会自动居中。如果标题未居中,则意味着标题视图太宽而无法居中,如果您设置了 backgroundColor,您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:
两个可能的修复:
The image you're using is way too big. Use a properly sized 44x44 pt image with 2x and 3x versions.
Wrap UIImageView inside of a regular UIView to avoid resizing.
您使用的图像太大了。使用具有 2x 和 3x 版本的适当大小的 44x44 pt 图像。
将 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;
回答by pedrouan
An example in Swift 3version of Darren's second way:
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
回答by Qun Li
I suggest you Override the function - (void)setFrame:(CGRect)fram like this:
我建议你像这样覆盖函数 - (void)setFrame:(CGRect)frame:
- (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.center 始终位于正确的位置
回答by PowHu
Don't use 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];
回答by MikeB
Qun Li's worked perfectly for me. Here's the swift 2.3 code:
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
}
}
回答by joslinm
If you're using a custom view from a nib, be sure to disable auto-layout on the nib file.
如果您使用来自 nib 的自定义视图,请务必禁用 nib 文件的自动布局。
回答by shoe
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(title:font:)
,removeNavBarTitle()
分别位于视图控制器viewWillAppear()
和viewWillDisappear()
方法中:
class YourViewController: UIViewController {
func viewWillAppear() {
(navigationController as! NavigationController).showNavBarLabel(title: "Your Title")
}
func viewWillDisappear() {
(navigationController as! NavigationController).removeNavBarLabel()
}
}
回答by Francisco José García Villarán
In Swift, this is what worked for me however it′s not the best solution (basically, add it up to navigationBar):
在 Swift 中,这对我有用,但它不是最佳解决方案(基本上,将其添加到导航栏):
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
}
回答by bzz
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.
这样它就会始终居中,但是如果您有back
长标题的按钮作为左侧导航项,它可以出现在您的徽标顶部。您应该首先创建另一个与导航栏大小相同的图像,然后在其中心绘制图像,然后将其设置为背景图像。
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 添加为子视图,而不是将图像视图设置为 ,这样它就不会受到与左右栏按钮项相关的约束。
回答by richy
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.
扩展达伦的回答,对我来说是修复是返回一个sizeThatFits
与UILabel
大小。事实证明这是在 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)