2015-08-23 23 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()。我的猜測是,它設置了幀大小,這在使用自動佈局時基本沒用,但也會在某處清除「髒」標誌,告訴矩陣它需要使其內在大小無效。換句話說,矩陣認爲它已經做了重新佈局的東西,它需要做的。