【问题标题】:NavigationItem's titleView not animating correctlyNavigationItem 的 titleView 动画不正确
【发布时间】:2017-10-25 06:37:15
【问题描述】:

我已经查看了所有我能找到的类似问题,但我还没有找到解决这个问题的方法。

我在viewDidLoad 中设置了这样的titleView 属性:

self.navigationItem.titleView = label

视图控制器是导航堆栈的一部分。当您点击前一个视图控制器中的一行时,它会将这个控制器推入堆栈。完全正常的 UINavigationController 的东西。

当这个视图控制器开始动画时,标签出现在原点(左上角),然后一直停留在那里,直到视图控制器完成动画,然后它跳转(没有动画)到导航中间的正确位置酒吧。

点击后退按钮后,标题视图会正确显示动画,就像普通标题一样。

这是viewDidLoad中的代码:

let label = UILabel(frame: CGRect.zero)
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = .red
label.text = "test"
label.sizeToFit()
self.navigationItem.titleView = label

我尝试过的事情:

  • 指定一个框架:没有变化。另外我不想指定一个框架。我不想对导航栏的高度做出假设。

  • 将其移至viewWillAppear:没有变化。

  • 将其移至viewDidAppear:更好但仍然不正确。在动画完成之前标签根本不会出现,然后它会出现在它应该出现的地方,没有动画它只是出现。正确的行为是像正常标题一样从右到左进行动画处理。

这很容易通过 Xcode 中的 Master-Detail 项目模板重现。如果你想试试,只需将上面的代码添加到configureView() 的顶部DetailViewController.swift。在该模板中,导航项的标题被硬编码到情节提要中。您可以通过搜索“详细信息”轻松删除它。单击显示Navigation Item: Title = "Detail" 的结果,然后从“检查器”窗格中删除该字符串。


更新

@synndicate 的建议确实适用于上面的 UILabel 示例。但我真正的问题是UIStackView。当我按照@synndicate 建议的方法使用堆栈视图时,我遇到了另一个动画问题。这次标题视图开始滑入,但动画一直到原点。动画完成后,它会捕捉到它应该在的位置。

这是@synndicate 建议的prepare(for:sender:) 中的代码...

let label = UILabel(frame: CGRect.zero)
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = .red
label.text = "test"
let stackView = UIStackView(frame: CGRect.zero)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.addArrangedSubview(label)
stackView.sizeToFit()
controller.navigationItem.titleView = stackView

还有什么建议吗?

另外,这是 Xcode 8 和 iOS 10。

更新 2

我发现对于导航层次结构的根为UINavigationController 的视图控制器,上面的堆栈视图代码在viewDidLoad 中完美地动画化(就像普通标题一样)。当导航层次结构的根是UISplitViewController 时会出现问题。

所以我想我可以将我的问题更新为这个......

如何配置UIStackView,它将在导航层次结构的根为UISplitViewControllernavigationItemtitleView 属性上设置?

【问题讨论】:

    标签: ios swift animation uinavigationcontroller uinavigationitem


    【解决方案1】:

    如果您希望stackView出现在导航堆栈的特定视图控制器上,只需将其添加到视图控制器中

    self.view.addSubview(stackView)
    

    【讨论】:

    • 正确。但它不会随处可见。我正在尝试在导航项的titleView 中使用堆栈视图。所有细节都在上面。
    • 为什么要添加为titleViewtitleView 旨在用于在整个导航过程中持续存在的视图。
    • 我想在导航栏的标题中有多个标签。我的理解是每个视图控制器都可以像title一样设置其navigationItem的titleView
    【解决方案2】:

    在将视图控制器压入堆栈之前,您能否将代码移动到?

    例如在Master-Detail项目的MasterViewController.swift

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "showDetail" {
                if let indexPath = tableView.indexPathForSelectedRow {                    
    
                    let object = objects[indexPath.row] as! NSDate
                    let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
                    controller.detailItem = object
                    controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
                    controller.navigationItem.leftItemsSupplementBackButton = true
    
                    let label = UILabel()
                    label.textAlignment = .center
                    label.backgroundColor = .red
                    label.text = "test"
                    label.sizeToFit()
    
                    controller.navigationItem.titleView = label
    
                }
            }
        }
    

    【讨论】:

    • 为了响应您的更新,在这一点上,我建议您必须重构 UINavigationController 并在其中设置您的 titleView 子类。然后在将来的prepare(for:sender) 调用中,您可以设置特定于被推送控制器的文本
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多