2015-08-23 24 views
0

我想使用Interface Builder使用的NSMatrix方法创建一组单选按钮,但使用代码。矩阵布局使用自动布局。我主要工作,除了在运行时添加新选项时。动态添加单元格到自动布局布局的NSMatrix有奇怪的效果;为什么?

在下面的例子中,点击Append Item几次就可以正常工作,然后矩阵开始离顶部附近的窗口(至少我认为它被剪切在顶部)。如果在添加一堆物品之后最大化该窗口,窗口将保持相同的高度,并且所有物品都会被剪裁到每个像素高度,这是非常不可取的事情:)

在我的真实程序而不是下面的测试),它的工作原理大多数都很好,但如果我动态地添加一个选项,在某些项目(最初为5)之后,选项会稍微剪切,出现轻微挤压或挤压。添加另一个选项将恢复此操作,直到下一个幻数被击中。

发生了什么事?我在OS X Yosemite上测试了这个。谢谢。

// 17 august 2015 
import Cocoa 

var keepAliveMainwin: NSWindow? = nil 
var matrix: NSMatrix? = nil 

class ButtonHandler : NSObject { 
    @IBAction func onClicked(sender: AnyObject) { 
     var lastRow = matrix!.numberOfRows 
     matrix!.renewRows(lastRow + 1, columns: 1) 
     var cell = matrix!.cellAtRow(lastRow, column: 0) as! NSButtonCell 
     cell.title = "New Item" 
     matrix!.sizeToCells() 
    } 
} 

var buttonHandler: ButtonHandler = ButtonHandler() 

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

    var prototype = NSButtonCell() 
    prototype.setButtonType(NSButtonType.RadioButton) 
    prototype.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSControlSize.RegularControlSize)) 

    matrix = NSMatrix(frame: NSZeroRect, 
     mode: NSMatrixMode.RadioModeMatrix, 
     prototype: prototype, 
     numberOfRows: 0, 
     numberOfColumns: 0) 
    matrix!.allowsEmptySelection = false 
    matrix!.selectionByRect = true 
    matrix!.intercellSpacing = NSMakeSize(4, 2) 
    matrix!.autorecalculatesCellSize = true 
    matrix!.drawsBackground = false 
    matrix!.drawsCellBackground = false 
    matrix!.autosizesCells = true 
    matrix!.translatesAutoresizingMaskIntoConstraints = false 
    contentView.addSubview(matrix!) 

    var button = NSButton(frame: NSZeroRect) 
    button.title = "Append Item" 
    button.setButtonType(NSButtonType.MomentaryPushInButton) 
    button.bordered = true 
    button.bezelStyle = NSBezelStyle.RoundedBezelStyle 
    button.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSControlSize.RegularControlSize)) 
    button.translatesAutoresizingMaskIntoConstraints = false 
    contentView.addSubview(button) 

    button.target = buttonHandler 
    button.action = "onClicked:" 

    var views: [String: NSView] 
    views = [ 
     "button": button, 
     "matrix": matrix!, 
    ] 
    addConstraints(contentView, "V:|-[matrix]-[button]-|", views) 
    addConstraints(contentView, "H:|-[matrix]-|", views) 
    addConstraints(contentView, "H:|-[button]-|", views) 

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

func addConstraints(view: NSView, constraint: String, views: [String: NSView]) { 
    var constraints = NSLayoutConstraint.constraintsWithVisualFormat(
     constraint, 
     options: NSLayoutFormatOptions(0), 
     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() { 
    var 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 
    var delegate = appDelegate() 
    app.delegate = delegate 
    app.run() 
} 

main() 
+0

如果矩阵太高而不适合放在窗口中(减去按钮的空间),您期望/想要发生什么?你有没有尝试将'autosizesCells'设置为false?你想要矩阵的内在大小来反映它的单元格的大小;您不希望矩阵根据其当前大小调整单元格的大小。另外,矩阵(水平和垂直)的抗压优先级是否按您的要求设置?特别是,如果您希望窗口在矩阵变得太高时增长,则希望压缩阻力大于500('NSLayoutPriorityWindowSizeStayPut')。 –

+0

好问题。我希望NSMatrix能够适应新的单元,但不压缩其他单元。我在真正的程序中尝试了'autosizesCells',但没有达到预期的效果,尽管我不记得是什么。我也会尝试压缩阻力的东西,并报告一切,然后编辑问题更清楚一点。谢谢。 – andlabs

+0

没错,但是当矩阵比窗口长得高时,你期望发生什么?窗户应该增长吗?什么时候窗户的高度能够适应屏幕?你想让矩阵滚动吗?在这种情况下,它必须处于滚动视图。 –

回答

1

显然,你需要在调用renewRows(_:columns:)后调用省略到sizeToCells()。我的猜测是,它设置了帧大小,这在使用自动布局时基本没用,但也会在某处清除“脏”标志,告诉矩阵它需要使其内在大小无效。换句话说,矩阵认为它已经做了重新布局的东西,它需要做的。