UINavigationBar titleView 比栏本身高

Posted

技术标签:

【中文标题】UINavigationBar titleView 比栏本身高【英文标题】:UINavigationBar titleView taller than the bar itself 【发布时间】:2015-04-21 23:09:58 【问题描述】:

所以我试图在 UINavigationBar 上做一个中心按钮,类似于流行的 UITabBar 自定义。但它有一个小问题。

基本上一切正常,我已经调整了条形图的大小,正确显示 titleView,使用 AutoLayout (topLayoutGuide)。甚至推送动画也运行良好。但是流行动画失败了。它正在截图或剪辑到边界,我找不到一个好的解决方法,这不会让我只想制作一个自定义控件并跳过 UINavigationBar。

这里有一段视频,准确地展示了正在发生的事情。 http://tinypic.com/r/2vl8yl1/8

这里有一些自定义导航栏的代码:

private let NavigationBarOffset: CGFloat = 10.0

class ActionNavigationBar: UINavigationBar 

    override init(frame: CGRect) 
        super.init(frame: frame)

        self.clipsToBounds = false
        self.contentMode = .Redraw

        // Slide the original navigationBar up to make room for the actionbutton
        transform = CGAffineTransformMakeTranslation(0.0, -NavigationBarOffset)
    

    required init(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
    

    override func sizeThatFits(size: CGSize) -> CGSize 
        var expectedSize = super.sizeThatFits(size)

        // Adjust the height of the navigation bar
        expectedSize.height += NavigationBarOffset

        return expectedSize
    

这是获取按钮的代码:

navigationItem.title = "Browse"
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Bookmarks, target: nil, action: nil)
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Search, target: self, action: "next")

let button = UIButton()
button.setTranslatesAutoresizingMaskIntoConstraints(false)
button.setTitle("+", forState: .Normal)
button.setTitle("", forState: .Highlighted)
button.titleLabel?.font = UIFont.boldSystemFontOfSize(40.0)
button.backgroundColor = self.view.tintColor
button.layer.cornerRadius = 27.0

let buttonWrapper = UIView(frame: CGRect(x: 0, y: 0, width: 60.0, height: 60.0));
buttonWrapper.addSubview(button)

NSLayoutConstraint(item: button, attribute: .CenterX, relatedBy: .Equal, toItem: buttonWrapper, attribute: .CenterX, multiplier: 1.0, constant: 0.0).active = true
NSLayoutConstraint(item: button, attribute: .Bottom, relatedBy: .Equal, toItem: buttonWrapper, attribute: .Bottom, multiplier: 1.0, constant: 0.0).active = true
NSLayoutConstraint(item: button, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 54.0).active = true
NSLayoutConstraint(item: button, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 54.0).active = true

navigationItem.titleView = buttonWrapper;

【问题讨论】:

我使用了一种不同的方法来使用TabBar 来实现这一点,而不是尝试将按钮放在控制器内,而是使用viewWillLayoutSubviews 方法将它放在它上面。从他们那里,您可以将按钮添加为视图 [self.view addSubview:centerTabButton]; 的子视图 那么在这种情况下,你会让我继承 UINavigationController 吗?我回避的原因是我必须以某种方式在视图中模拟推送/弹出动画。 是的,您需要子类化。诚然,您还需要制作动画。在我们的例子中,这是让它为 TabBar 工作的唯一可靠方法,但我们不必为此处理动画。 【参考方案1】:

我已尝试关注override func viewDidLoad()。不使用自定义导航栏对我来说效果很好。

override func viewDidLoad()

    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    //self.edgesForExtendedLayout = UIRectEdge.None
    //navigationItem.title = "Browse"

    navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Bookmarks, target: nil, action: nil)
    navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Search, target: self, action: "next")



    let button = UIButton()
    //button.setTranslatesAutoresizingMaskIntoConstraints(false)
    button.frame = CGRectMake(0, 0, 40, 40)
    button.setTitle("+", forState: .Normal)
    button.setTitle("", forState: .Highlighted)
    button.titleLabel?.font = UIFont.boldSystemFontOfSize(40.0)
    button.backgroundColor = self.view.tintColor
    button.layer.cornerRadius = 20

    let buttonWrapper = UIView(frame: CGRect( 0, y: 0, width: 40, height: 40));
    //buttonWrapper.backgroundColor = UIColor.redColor()
    buttonWrapper.addSubview(button)

    /*NSLayoutConstraint(item: button, attribute: .CenterX, relatedBy: .Equal, toItem: buttonWrapper, attribute: .CenterX, multiplier: 1.0, constant: 0.0).active = true
    NSLayoutConstraint(item: button, attribute: .Bottom, relatedBy: .Equal, toItem: buttonWrapper, attribute: .Bottom, multiplier: 1.0, constant: 0.0).active = true
    NSLayoutConstraint(item: button, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 54.0).active = true
    NSLayoutConstraint(item: button, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 54.0).active = true*/

    navigationItem.titleView = buttonWrapper;

【讨论】:

您的视图与视频中显示的不符。您根本没有在 UINavigationBar 之外绘制按钮。【参考方案2】:

一般 UINavigationBar 高度为 65。StatusBar 在 Title 之前大约需要 10 yOffset。所以你可以将你的标题设置在 NavigationBar 的 10 到 65 yOffset 之间。 Button 的最大高度为 (65-10)=55。

所以你有两个解决方案:

    您可以更改按钮的高度和宽度,例如,

    let buttonWrapper = UIView(frame: CGRect(x: 0, y: 0, width: 45.0, height: 45.0));

    或者你可以改变 Button 的 yOffset 值,比如,

    let buttonWrapper = UIView(frame: CGRect(x: 0, y: -8, width: 60.0, height: 60.0));

【讨论】:

以上是关于UINavigationBar titleView 比栏本身高的主要内容,如果未能解决你的问题,请参考以下文章

UINavigationBar TitleView 带字幕

UINavigationBar titleView 比栏本身高

UINavigationBar titleView 用于不同的方向

防止 UINavigationItem 的 TitleView 闪烁

如何设置navigationItem.titleView 图片水平居中?

有啥方法可以覆盖 iOS 7 中的 titleView 褪色?