我使用图片视图在导航栏中显示图片。问题在于,由于后退按钮,我无法将其正确设置到中心。我检查了相关问题,并且在我解决之前遇到了几乎相同的问题,但这次我不知道。
之前我用假条形按钮解决了这个问题,所以我尝试在右侧(和左侧)添加假条形按钮,但它没有帮助。
- (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
在同一侧有条形按钮。是否有任何解释为什么它可以使用以编程方式创建但不能与常用后退按钮一起使用的条形按钮?
答案 0 :(得分:92)
UINavigationBar
会自动将其titleView
居中。如果标题没有居中,这意味着标题视图太宽而无法居中,如果你设置了backgroundColor,如果你UIImageView
你会看到正是发生了什么
标题视图太宽,因为该导航栏会使用-sizeThatFits:
自动调整标题大小以保存其内容。这意味着您的标题视图将始终调整为图像大小。
两种可能的修复方法:
您使用的图片太大了。使用尺寸合适的44x44 pt图像,2x和3x版本。
在常规UIView中包装UIImageView以避免调整大小。
示例:
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)
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)