2015-08-23 4 views
0

Я хочу создать группу переключателей, используя метод NSMatrix, который использует Interface Builder, но в коде. Матрица выложена с помощью автоматической компоновки. В основном я работаю, кроме тех случаев, когда добавляю новые параметры во время выполнения.Динамически добавляя ячейки в NSMatrix, выложенные с помощью Auto Layout, имеют странные эффекты; Зачем?

В следующем примере, нажав кнопку «Добавить элемент», несколько раз будет работать нормально, тогда матрица начнет выходить из окна вверху (по крайней мере, я думаю, что она обрезана вверху). Если вы увеличиваете это окно после добавления кучки элементов, то окно будет оставаться одинаковой высоты, и все элементы будут обрезаны примерно до одного пикселя, что очень нежелательно :)

В моей реальной программе (а не этот тест ниже), он работает в основном отлично, но если я добавлю опцию динамически, после определенного количества элементов (изначально 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' false в реальной программе и не имел желаемого эффекта, хотя я не помню, что. Я также попробую материал сопротивления сжатию и сообщит все обратно, а затем отредактируйте вопрос, чтобы быть более понятным. Благодарю. – andlabs

+0

Правильно, но когда матрица растет выше окна, что вы ожидаете? Должно ли окно расти? Как насчет того, когда окно так же высоко, как может поместиться на экране? Вы хотите, чтобы матрица прокручивалась? В этом случае он должен быть в виде прокрутки. –

ответ

1

Видимо, вам нужно пропустить вызов sizeToCells() после вызова renewRows(_:columns:). Я предполагаю, что он устанавливает размер кадра, который в большинстве случаев бесполезен при использовании автоматического макета, но также очищает «грязный» флаг где-то, который сообщает матрице, что ему необходимо аннулировать свой собственный размер. Другими словами, матрица думает, что она уже сделала материал для повторной компоновки, который ему нужно было сделать.