导航栏标题视图的对齐方式

7
我希望我的导航栏能够在中间显示两个内容,其中之一是列表名称,另一个是用户名。用户名将放置在列表名称下方。目前我所做的是,通过编程创建了两个标签和一个父视图,并设置了navigationItemtitleView属性。
override func viewDidLoad() {
        super.viewDidLoad()
        var rectForView = CGRect(x: 0, y: 0, width: 190, height: 176)
        var viewForTitle = UIView(frame: rectForView)

        var rectForNameLabel = CGRect(x: 0, y: 63, width: 190, height: 30)
        var listNameLabel = UILabel(frame: rectForNameLabel)
        listNameLabel.text = "Name of the List...."
        listNameLabel.textAlignment = NSTextAlignment.Center
        listNameLabel.font = UIFont(name: "HelveticaNeue-Bold", size: 15)

        var rectForListLabel = CGRect(x: 0, y: 93, width: 190, height: 20)
        var usersOfListLabel = UILabel(frame: rectForListLabel)
        usersOfListLabel.text = "some Users...."
        usersOfListLabel.textAlignment = NSTextAlignment.Center
        usersOfListLabel.font = UIFont(name: "HelveticaNeue", size: 10)

        viewForTitle.addSubview(listNameLabel)
        viewForTitle.addSubview(usersOfListLabel)


        self.navigationItem.titleView = viewForTitle

事情是这样的,我随机选择宽度,这会导致在不同设备上出现对齐问题。如何实现我的情况下的中间对齐呢? iphone 6

iphone 5


你尝试设置一个 CenterX 的 NSLayoutConstraint 了吗? - gutenmorgenuhu
我没有这样做。但是我尝试将“textForViews”的中心X变量设置为控制器提供的视图的中心X变量。 - Salihcyilmaz
顺便问一下,如何通过编程方式添加约束? - Salihcyilmaz
在viewDidLoad中尝试了这个:var constX = NSLayoutConstraint(item: viewForTitle, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)。然后将constX添加到viewForTitle中,但是没有起作用。程序崩溃了,并显示“视图层次结构未准备好使用约束条件”。 - Salihcyilmaz
在将约束添加为子视图之后激活它们? - gutenmorgenuhu
我认为是这样的。它们被添加为viewDidLoad中的最后几行代码。顺便说一下,如果你能提出问题,我会很高兴。我真的想解决这个问题... - Salihcyilmaz
2个回答

6

方法:

  • titleView 始终居中
  • 因此将您的自定义视图的宽度设置为与 navigationBar 相匹配(宽度-40)

代码

private func setupNavigationItems() {
    
    let label = UILabel()
    
    label.translatesAutoresizingMaskIntoConstraints = false
    
    label.text = "aaaaa"
    label.backgroundColor = .green
    
    label.textAlignment = .left
    
    navigationItem.titleView = label
    
    if let navigationBar = navigationController?.navigationBar {
        
        label.widthAnchor.constraint(equalTo: navigationBar.widthAnchor, constant: -40).isActive = true
    }
}

Custom Title View for the entire width of the navigation bar


你救了我的一天!非常感谢你。 - Kawe

4
事实上,导航栏的titleView会尽力将你的视图居中显示。如果你看到的标题在较小的屏幕上不居中,那么原因就是自定义titleView的宽度超出了titleView的最大宽度。
如果您将值设置为160,则在第二种情况下将看到其居中显示。
一般解决方案
如果您想要自适应不同设备的标题宽度,则有几种方法可以帮助您解决问题。
1. 根据不同的屏幕宽度设置不同的宽度。例如,当屏幕宽度为320时,将其设置为不超过160。如果大于320,请根据不同的屏幕大小分配值。这不是一种优雅的解决方案,但是非常直接,无需设置和尝试复杂的约束条件。
2. 计算titleView的实际宽度。titleView的宽度由导航栏宽度减去左侧和右侧barbuttonitem决定。类似这样:
TitleViewWidth = Navigation width - leftbarbuttonitem.width +/- rightbarbuttonitem.width - someConstant
您需要进行一些实验以找到适合此公式的适当常数。
3. 为此titleView创建xib文件,设置比声明固定宽度更灵活的约束条件。从xib加载视图,然后将其分配给titleView。这可能需要更长的时间来调整以使其正常工作。
编辑
如果您是新手,我想到了另一种可能更容易的方法。
在Storyboard中,找到并将视图拖放到此视图控制器的导航栏titleView区域。
展开您希望视图的长度。
向该视图添加两个标签,并设置前导、尾随、高度和垂直约束条件。
在Storyboard上的外观
在4S上运行的外观

我认为与1中提到的解决方案类似,但我无法弄清楚如何做到这一点...我该如何为不同的设备或屏幕设置不同的数量?对于第3个问题,我不知道如何创建xib文件。我是iOS的新手,而且苹果似乎反对通过参考文档来创建nib文件。你能给我一些关于xibs的链接或者像“深入研究这些文档,学习这些”之类的东西吗?无论如何,感谢你的关注。 - Salihcyilmaz
@Salihcyilmaz,请查看我的编辑,这是一种更简单的方法。对于第1个问题,您可以尝试使用UIScreen或仅尝试获取导航栏的宽度,查看数字,并根据不同的导航宽度分配不同的宽度。 - Shali Liu
@Salihcyilmaz 对于第三个问题,我现在没有找到什么方便的东西。有很多关于如何创建xib文件或如何重用xib文件的文章,但我不确定它们是否适用于现在 :) 如果将来需要可重用的xib文件,请搜索相关信息。 - Shali Liu
不错。实际上,你在编辑中所做的是我的故事板版本,我猜。无论如何,在这两种情况下,如果将视图的宽度设置为160,一切都看起来很好。否则,它们会开始离中心移动。你能解释一下为什么会发生这种情况吗? - Salihcyilmaz
@Salihcyilmaz 如果你已经在Storyboard中设置了适当的约束条件来设置视图,那么你就不需要在viewdidload中编写任何代码。 - Shali Liu
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接