首页 文章

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

提问于
浏览
47

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

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

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

10 回答

  • 6

    只要有足够的空间, UINavigationBar 会自动将其 titleView 居中 . 如果 Headers 不居中意味着 Headers 视图太宽而无法居中,并且如果您设置了backgroundColor,那么 UIImageView 你正好发生了什么 .

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

    两个可能的修复:

    • 你正在使用的图像太大了 . 使用尺寸合适的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;
    
  • 91

    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
    
  • 5

    我建议你覆盖函数 - (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

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

    群力对我很有帮助 . 这是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
        }
    }
    
  • 13

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

  • 7

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

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

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

    viewDidLoad 方法内 .

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

    2)或者不是将图像视图设置为 titleView ,您可以尝试简单地将其添加为子视图,因此它不会具有与右侧和左侧条形按钮项相关的约束 .

  • 2

    在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
    
          }
    
  • 1

    扩展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)
    

相关问题