我有一个垂直的NSSplitView,左边有一个NSScrollView(NSOutlineView,源列表,没有标题视图),右边有一个WebView。所有视图的初始帧均为NSZeroRect。 NSSplitView,NSScrollView和WebView的自动调整大小蒙版均已关闭,并且将NSSplitView制成为使用“自动布局”填充窗口。我似乎无法强迫NSSplitView分隔线位于给定位置;

[sv setPosition:250 ofDividerAtIndex:0];


只是拒绝生效。尽管我的用例只是一个初始职位,但最终我将需要一个随时可用的解决方案,因为我没有为此使用nib / xib文件。

不论是否使用上面的setPosition:调用,都会为WebView提供NSSplitView的整个宽度。如果我将NSScrollView的初始帧设置为NSMakeRect(0, 0, 250, 0),它将起作用。当然,这仅适用于初始框架,这还不够好(并且不能抵抗UI布局更改)...我发现的所有内容都早于“自动布局”,并说您应该直接操作框架;因为这是自动版式,所以我怀疑这是个好主意...

但这很奇怪:如果我将分隔符样式设置为NSSplitViewDividerStyleThin,则即使NSMakeRect()也将被忽略,并且无论如何,NSScrollView都将获得NSSplitView的完整宽度。

那为什么不能设置NSSplitView的位置?

是因为位置由自动版式确定?在那种情况下,如何设置约束以将左视图的宽度强制为给定宽度,让布局管理器运行以应用该约束,然后立即删除该约束?我尝试覆盖NSSplitView的layoutupdateConstraints来做到这一点,但是Auto Layout确实不像我那样,没有效果并且当我尝试再次移动分隔线时会崩溃!

还是我真的应该直接操纵NSSplitView子视图的帧矩形,而不管自动布局的最佳做法是什么?

是的,我已经多次在这里以及其他几页上阅读了每个类似的问题;它的所有建议要么无效,要么说setPosition:应该神奇地起作用。

这是OS X 10.11,但我需要一个可以回溯至10.7的解决方案。

下面的Swift 2程序快速演示了我的意思。您可以使用appLaunched()中的各种代码行来尝试各种效果。无论出于何种原因,我上面提到的奇怪的事情(如果分隔线样式为Thin,则左侧视图占据了所有空间)虽然没有发生。那是我感到困惑的另一件事...

谢谢。

// 3 january 2016
// scratch program 17 august 2015
import Cocoa
import WebKit

var keepAliveMainwin: NSWindow? = nil

func appLaunched() {
    let mainwin = NSWindow(
        contentRect: NSMakeRect(0, 0, 320, 240),
        styleMask: (NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask),
        backing: NSBackingStoreType.Buffered,
        `defer`: true)
    let contentView = mainwin.contentView!

    let splitView = NSSplitView(frame: NSZeroRect)
    splitView.dividerStyle = NSSplitViewDividerStyle.Thin
    splitView.vertical = true
    splitView.translatesAutoresizingMaskIntoConstraints = false
    contentView.addSubview(splitView)

    let box1 = NSScrollView(frame: NSZeroRect)
    let ov = NSOutlineView(frame: NSZeroRect)
    ov.headerView = nil
    ov.selectionHighlightStyle = NSTableViewSelectionHighlightStyle.SourceList
    box1.documentView = ov
    box1.translatesAutoresizingMaskIntoConstraints = false
    splitView.addSubview(box1)

    let box2 = WebView(frame: NSZeroRect)
    box2.translatesAutoresizingMaskIntoConstraints = false
    splitView.addSubview(box2)

    let views: [String: NSView] = [
        "splitView":    splitView,
    ]
    addConstraint(contentView, "H:|-[splitView]-|", views)
    addConstraint(contentView, "V:|-[splitView]-|", views)

    splitView.setPosition(50, ofDividerAtIndex: 0)

    mainwin.cascadeTopLeftFromPoint(NSMakePoint(20, 20))
    mainwin.makeKeyAndOrderFront(mainwin)
    keepAliveMainwin = mainwin
}

func addConstraint(view: NSView, _ constraint: String, _ views: [String: NSView]) {
    let constraints = NSLayoutConstraint.constraintsWithVisualFormat(
        constraint,
        options: [],
        metrics: nil,
        views: views)
    view.addConstraints(constraints)
}

class appDelegate : NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(note: NSNotification) {
        appLaunched()
    }

    func applicationShouldTerminateAfterLastWindowClosed(app: NSApplication) -> Bool {
        return true
    }
}

func main() {
    let app = NSApplication.sharedApplication()
    app.setActivationPolicy(NSApplicationActivationPolicy.Regular)
    // NSApplication.delegate is weak; if we don't use the temporary variable, the delegate will die before it's used
    let delegate = appDelegate()
    app.delegate = delegate
    app.run()
}

main()

最佳答案

我只是遇到了同样的问题,我设法通过使用相同的参数两次调用setPosition:ofDividerAtIndex:来解决了这个问题。也许它也对您有用。

08-18 14:56