我有一个垂直的 NSSplitView,左侧有一个 NSScrollView(NSOutlineView,源列表,无标题 View ),右侧有一个 WebView。所有 View 都有 NSZeroRect
的初始帧。 NSSplitView、NSScrollView 和 WebView 的自动调整大小 mask 已关闭,并且 NSSplitView 被设置为使用自动布局填充窗口。我似乎无法强制 NSSplitView 分隔线位于给定位置;
[sv setPosition:250 ofDividerAtIndex:0];
只是拒绝生效。虽然我的用例是针对初始位置,但我最终需要一个随时可用的解决方案,因为我没有为此使用 nib/xib 文件。
无论是否有上面的 setPosition:
调用,WebView 都会被赋予 NSSplitView 的整个宽度。如果我将 NSScrollView 的初始框架设置为 NSMakeRect(0, 0, 250, 0) ,它就可以工作。当然,这仅适用于初始框架,这还不够好(并且无法抵抗 UI 布局更改)...我发现的所有内容都早于自动布局,并表示您应该直接操作框架;因为这是自动布局,我怀疑这是一个好主意......
但事情变得更奇怪:如果我将分隔符样式设置为 NSSplitViewDividerStyleThin,甚至 NSMakeRect() 也会被忽略,并且 NSScrollView 会被赋予 NSSplitView 的完整宽度,无论如何。
为什么我不能设置 NSSplitView 的位置?
是不是因为位置是由自动布局决定的?在这种情况下,如何设置一个约束来强制左 View 的宽度为给定宽度,让布局管理器运行以应用该约束,然后立即删除该约束?我尝试重写 NSSplitView 的 layout
和 updateConstraints
来做到这一点,但自动布局并不像我那样,没有任何效果,并且当我再次尝试移动分隔线时崩溃!
或者我真的应该直接操作 NSSplitView subview 的框架矩形,尽管自动布局最佳实践是什么?
是的,我已经在这里多次以及其他一些页面上阅读了所有类似的问题;它的所有建议要么不起作用,要么说 setPosition:
应该神奇地起作用。
这是 OS X 10.11,但我需要一个可以追溯到 10.7 的解决方案。
下面的 Swift 2 程序快速演示了我的意思。您可以使用 appLaunched()
中的各行代码来尝试各种效果。不管出于什么原因,我上面提到的奇怪的事情(如果分隔线样式是薄的,左边的 View 占据了所有空间)在这里并没有发生。这是我感到困惑的另一件事......
谢谢。
// 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:
两次来解决它。也许它也适合你。
关于macos - 现在如何设置 NSSplitView 的位置?设置位置 :ofDividerAtIndex: doesn't work and I'm not sure how to make a temporary constraint,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34574478/