我有一个垂直的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的
layout
和updateConstraints
来做到这一点,但是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:
来解决了这个问题。也许它也对您有用。