首页 > 解决方案 > 在 y 方向重新定位自定义导航栏 titleView

问题描述

使用 Swift5.1.3、XCode11.3、iOS13.3、

我尝试重新定位自定义导航栏 titleView。

创建自定义视图并将其添加到我的导航栏工作正常。(见下面的代码)

这里有一个例子:请只考虑顶部带有名称标签和黄色圆形图像的 DarkGray NavigationBar。标签和图像应在 y 方向移动!

在此处输入图像描述

左边的例子,我已经成功运行了。我尝试实现的右侧示例。但到目前为止还没有运气。

自 4 小时以来,我一直在努力解决一件缺失的事情。

如何调整自定义 navigationBar titleView 的 y 位置(或 .topAnchor 常量偏移)???

崩溃消息说:

'Unable to activate constraint with anchors
<NSLayoutYAxisAnchor:0x6000033ac900 "UIStackView:0x7fdcced39ea0.top"> and
<NSLayoutYAxisAnchor:0x6000033644c0 "UIView:0x7fdcd412ba20.top"> because they
have no common ancestor.  Does the constraint or its anchors reference items
in different view hierarchies?  That's illegal.'

这是我的代码(请注意带有许多感叹号的注释 - 这是我的代码的 y 偏移试验和崩溃位置):

override func viewWillAppear(_ animated: Bool) {

    super.viewWillAppear(animated)

    // ...

    // set up navigationItem and navigationController look and feeel
    navigationController?.set_iOS12_lookAndFeel()
    navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    navigationItem.largeTitleDisplayMode = .always

    // create NavigationBar.titleView StackView (consisting of a label and a button)
    let titleStackView = UIStackView(frame: CGRect(origin: .zero, size: CGSize(width: self.view.bounds.width, height: 88.0)))
    titleStackView.isUserInteractionEnabled = true
    titleStackView.axis = .horizontal
    titleStackView.alignment = .center
    titleStackView.spacing = 10.0
    // stackView label
    let labelWidth: CGFloat = UIScreen.main.bounds.width - 16.0 - 10.0 - 36.0 - 16.0   // FullScreenWidth minus (Leading + Spacing + ButtonWidth + Trailing)
    let label = UILabel()
    label.font = AppConstants.Font.NavBar_TitleFont
    label.text = self.profileName
    label.textColor = .white
    label.tintColor = .white
    // position label
    label.translatesAutoresizingMaskIntoConstraints = false
    label.widthAnchor.constraint(equalToConstant: labelWidth).isActive = true
    // stackView button
    let buttonWidth: CGFloat = 36.0
    let button = UIButton(frame: CGRect(origin: .zero, size: CGSize(width: buttonWidth, height: buttonWidth)))
    button.setImage(self.profileImageView.image, for: .normal)
    button.isUserInteractionEnabled = true
    button.addTarget(self, action: #selector(self.callProfileBtnMethod), for: .touchUpInside)
    button.frame = CGRect(x: 0, y: 0, width: 36, height: 36)
    button.layer.cornerRadius = button.frame.size.width / 2
    button.layer.masksToBounds = false
    button.clipsToBounds = true
    // position button
    button.translatesAutoresizingMaskIntoConstraints = false
    button.widthAnchor.constraint(equalToConstant: buttonWidth).isActive = true
    button.heightAnchor.constraint(equalToConstant: buttonWidth).isActive = true
    // add label and button to stackView
    titleStackView.addArrangedSubview(label)
    titleStackView.addArrangedSubview(button)
    // position titleStackView
    titleStackView.translatesAutoresizingMaskIntoConstraints = false

    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // Here the code crashes !!!!!!!
    titleStackView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100.0).isActive = true
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    // position cockpitHeaderView (equal in size and position to titleStackView)
    let cockpitHeaderView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: self.view.bounds.width, height: 88.0)))
    cockpitHeaderView.backgroundColor = .green
    cockpitHeaderView.isUserInteractionEnabled = true
    cockpitHeaderView.addSubview(titleStackView)
    cockpitHeaderView.leadingAnchor.constraint(equalTo: titleStackView.leadingAnchor, constant: 0.0).isActive = true
    cockpitHeaderView.topAnchor.constraint(equalTo: titleStackView.topAnchor, constant: 0.0).isActive = true
    cockpitHeaderView.trailingAnchor.constraint(equalTo: titleStackView.trailingAnchor, constant: 0.0).isActive = true
    cockpitHeaderView.bottomAnchor.constraint(equalTo: titleStackView.bottomAnchor, constant: 0.0).isActive = true
    // finally replace NavBar title by custom cockpitHeaderView
    self.title = ""
    self.navigationItem.titleView = cockpitHeaderView
}

如何正确移动 titleView ???

标签: swiftconstraintspositioningnslayoutconstraintnavigationbar

解决方案


推荐阅读