【问题标题】:Setting minimum width of NSSplitViews设置 NSSplitViews 的最小宽度
【发布时间】:2020-07-16 05:56:10
【问题描述】:

我在设置一个简单的拆分视图时遇到了麻烦。第一个拆分视图已折叠。我需要为它设置一个最小宽度。我在网上看到的所有内容(NSSplitViewController/NSSplitView 很少见)都是针对 Objective-C 的,将所有内容都放在应用程序委托中,并使用 XIB。

这是场景: 窗口控制器与 SplitView 控制器有一个 segue,它有两个拆分视图(2 个视图控制器)。

哪个对象需要有 NSSplitViewDelegate?

编辑:添加代码 sn-p: 例如,我有这个:

import Cocoa

class ViewController: NSSplitViewController, NSSplitViewDelegate {


    @IBOutlet weak var pdlSplitView: NSSplitView!

    override func viewDidLoad() {
        super.viewDidLoad()

        }
    override func splitView(splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
        return proposedMinimumPosition + 200
    }

}

我还有什么遗漏的吗?

谢谢

更新

基于下面的 cmets,我进行了更改,但现在我在 AppDelegate 的类定义上获得了 sigAbort。 Full code

视图控制器:

import Cocoa

class ViewController: NSSplitViewController, NSSplitViewDelegate {


    @IBOutlet weak var pdlSplitView: NSSplitView!

    let publicDataListings : PDL = PDL()


    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.pdlSplitView.delegate = self

    }

    override func splitView(splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
    return proposedMinimumPosition + 200
    }

}

侧边栏视图控制器:

import Cocoa

class SidebarViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
    }


}

数据集视图控制器:

import Cocoa

class DatasetViewController: NSViewController, NSSplitViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
    }

}

更新 我拿走了我的自定义 NSSplitViewController 类并创建了两个 NSSplitView 类,一个使用约束方法。现在,我看到了两个子视图,但它们比应有的要小得多:

是否有任何人使用 Swift 和 Storyboards 做到了这一点?

【问题讨论】:

  • 你在使用自动布局吗?您希望应用运行的操作系统的早期版本是什么?如果您的目标是 10.8 或更高版本并使用自动布局,则拆分视图将遵守其子视图的约束。因此,最小宽度可能是隐含的,因为子视图中的某些内容具有固有宽度并抵抗压缩并且对子视图具有前导和尾随约束。或者您可以在子视图上创建显式宽度约束,使其大于或等于某个常数。
  • 我可以定位 10.10+。我正在尝试在 Swift 中执行此操作。我尝试过应用约束,但它们没有坚持。我知道现在这是一个移动世界,但见鬼,我现在只需为 Swift 中的 SplitView Hello World 付费。然后我就去参加比赛了。
  • 如果你实现了某些拆分视图委托方法,那么拆分视图将不会使用自动布局。有关详细信息,请参阅 10.8 的 AppKit 发行说明。另外,我不确定拆分视图委托方法是否与NSSplitViewController 兼容。如果删除该委托方法没有帮助,请显示您尝试设置的约束以及您是如何做到的。
  • 删除 NSSplitViewController 会在委托方法中产生错误。
  • 我不建议删除它。我建议您使用自动布局,而不是尝试限制视图大小的 NSSplitViewDelegate 方法。

标签: xcode macos swift nssplitview


【解决方案1】:

无需编码即可在具有自动布局的故事板中为 NSSplitViewController/NSSplitView 设置最小宽度。

选择您需要最小宽度的自定义视图(例如 200),并添加一个设置为所需值的宽度约束,这将添加一个“相等”约束(例如自定义 View.Width 等于 200)。

接下来找到新的约束并将约束关系更改为“大于或等于”(例如,您现在的宽度 ≥ 200)。

您现在在 NSSplitView 中有一个最小宽度。然后,您可以使用 Priority 字段解决与任何其他自动布局约束的任何冲突。

【讨论】:

  • 谢谢。这是一个完全的谜,直到你知道它在那里! :-) 包含屏幕截图可能会对您的答案有所帮助。
  • 谢谢,我正在为此苦苦挣扎。如果您不知道约束的 >= 和
  • 所以我选择了我的视图并尝试设置一个新的宽度约束。我禁用了约束选项。我错过了什么吗?
  • @AnaghSharma 您不能为 contentView(场景的根视图)设置约束,只能设置其内容,因此您必须创建自定义视图,将其固定到顶部/前沿,并给它一个“或更大”的宽度常数以使用此解决方案。 (通常,您可以限制内容)
【解决方案2】:

这些值没有暴露在情节提要中,这很遗憾,但是 NSSplitViewItem 具有可以使用的 minimumThickness 和 maximumThickness 属性。 (这会覆盖持有优先级,因此如果您为一个 splitViewItem 设置 minimumThickness,如果您使窗口足够小,其他的现在将缩小为空。)

还有 automaticMaximumThickness(我无法弄清楚它如何与其他值交互)和 preferredThicknessFraction,当我在 10.13 下使用它时没有效果。

【讨论】:

    【解决方案3】:
    1. 将 NSSplitViewController 设置为 NSSplitView(您要约束的拆分视图)的委托。在您的情况下,它应该是 - 在 xib 中将 NSSplitView 的委托出口挂钩到文件所有者(我猜文件所有者是 NSSplitViewController 子类)
    2. 实施

      - (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex { ... }
      

    在 NSSplitViewController 中

    https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSSplitViewDelegate_Protocol/index.html#//apple_ref/occ/intfm/NSSplitViewDelegate/splitView:constrainMinCoordinate:ofSubviewAt:

    【讨论】:

    • 在 XIB 中?我们不应该使用故事板吗?这就是现在的一切。请查看我上面的编辑以了解我目前拥有的代码。
    • 您发布的上述代码是正确的,只需将 ViewController 设置为您要约束的拆分视图的委托。在 ViewController 中:覆盖 func viewDidLoad() { super.viewDidLoad() splitView.delegate = self; }
    • 覆盖 func viewDidLoad() { super.viewDidLoad(); pdlSplitView.delegate = self; }
    • 这是一个工作示例(它在 ObjC 中),但它的代码与 swift 95% 相同,你会明白的:tagtaxa.com/download/SplitExample.zip
    • 我尝试了你的建议。我现在得到一个错误。我已经用附加代码和完整代码的链接更新了帖子。
    猜你喜欢
    • 2012-04-05
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多