【问题标题】:NSWindow launching with wrong size after setting contentViewController to NSTabViewController将 contentViewController 设置为 NSTabViewController 后,NSWindow 以错误的大小启动
【发布时间】:2018-01-30 07:37:04
【问题描述】:

我有一个带有NSWindowController 的Xcode 项目,其contentViewController 设置为NSViewController 的子类。我最近从情节提要中删除了NSViewController 子类,并将contentViewController 替换为NSTabViewController 子类。

现在,当我运行应用程序时,NSWindow 以 500x500 的大小打开,而不是第一个选项卡的大小。更重要的是,我可以在故事板中看到 no 视图,其大小为 500x500,并且该大小也不是以编程方式进行的。窗口本身设置为不同的大小,NSTabViewController 的第一个NSViewController 中的视图也是如此。

我假设我必须在某处设置某种约束,但如果有,我不知道在哪里/如何找到它。使用 Xcode 9.2 和 High Sierra。

windowDidLoad() 中以编程方式将窗口的大小设置为正确的大小是可行的,但如果我改变了视图的大小,我也必须改变它,它会变老,很快。

抱歉,如果这含糊不清;我真的不知道什么样的屏幕截图或代码 sn-p 会有帮助。

【问题讨论】:

  • Xcode 11.4 中仍然存在问题
  • @RaffaeleCandeliere 你给视图添加了子视图和约束吗?
  • @Willeke “视图”到底是什么意思?我的选项卡视图的每个选项卡中确实有子视图(带有约束等),但我不确定您是否在谈论它们。但是,我已经绕过了这个解决方案 (gist.github.com/mminer/caec00d2165362ff65e9f1f728cecae2) 的问题。这不是一个修复程序,但它可以满足我的需求。

标签: macos nsview nswindow nswindowcontroller nstabviewcontroller


【解决方案1】:

我最近也遇到了这个令人沮丧的问题。

有几个选项可以解决这个问题:

  1. 正如您所提到的,在您的每个自定义视图控制器中设置preferredContentSize,以将选项卡的内容保持为您想要的大小。这是不灵活的,但它确实有效。

    // Swift
    class FooViewController: ViewController {
    
        override func viewWillAppear() {
            super.viewWillAppear()
    
            preferredContentSize = NSSize(width: 400, height: 280)
        }
    }
    
  2. 我在this SO 答案中找到了更好解决方案的提示。您可以将子视图(stackview、nsview 等)添加到处理选项卡内容的视图控制器的主视图(唷!),然后添加将其固定到每个边缘的约束并添加设置大小的约束。

这是一个screenshot 在 Interface Builder 中的样子。我添加了一个 Stack View,然后添加了 6 个约束。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    Joshua 的 answer 设置了 preferredContentSize 成功了,这一切都归功于他!值得一提的是,由于这是专门为父选项卡视图控制器完成的,因此最好将其子类化并将此处理移动到 tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) 委托方法中,该方法在选择选项卡时被调用:

    override func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) {
        tabViewItem?.viewController?.preferredContentSize = tabViewItem?.view?.frame.size
        // Alternatively: tabViewItem?.viewController?.preferredContentSize = tabViewItem?.view?.fittingSize
        super.tabView(tabView, didSelect: tabViewItem)
    }
    

    这样首选的内容大小始终是最新的,您不必担心手动刷新它,假设视图提供了正确的框架大小或适合大小,这很容易通过约束实现。

    在窗口控制器完成加载并且500×500 初始设置位置后,也会调用此方法。

    在每个选项卡式视图控制器本身中设置首选内容大小并不理想:相同的代码在多个控制器之间重复,如果这些控制器在其他地方重用,则会增加不必要的噪音。

    【讨论】:

      【解决方案3】:

      我遇到了类似的问题。我添加了一个带有容器视图作为窗口内容的视图控制器,并将容器视图内容指向选项卡视图控制器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-08
        • 1970-01-01
        • 2023-03-17
        • 1970-01-01
        • 1970-01-01
        • 2021-04-08
        • 1970-01-01
        • 2015-10-15
        相关资源
        最近更新 更多