Я хочу создать группу переключателей, используя метод 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()
autosizesCells
в false? Вы хотите, чтобы внутренний размер матрицы отражал размер ее ячеек; вы не хотите, чтобы матрица изменяла размер ячеек в зависимости от ее текущего размера. Также приоритеты сопротивления сжатию матрицы (горизонтальные и вертикальные) выставлены как хотите? В частности, если вы хотите, чтобы окно увеличивалось, когда матрица становится слишком высокой, сопротивление сжатию должно быть больше 500 (NSLayoutPriorityWindowSizeStayPut
). - person Ken Thomases   schedule 23.08.2015autosizesCells
из false в реальной программе, и это не дало желаемого эффекта, хотя я не помню, какой. Я также попробую материал сопротивления сжатию и сообщу обо всем, а затем отредактирую вопрос, чтобы он был немного более ясным. Спасибо. - person andlabs   schedule 23.08.2015sizeToCells()
. Если это ничего не меняет, попробуйте добавить вызовinvalidateIntrinsicContentSize()
. - person Ken Thomases   schedule 24.08.2015sizeToCells()
сделало это не только в программе выше, но и в моей реальной программе. Я предполагаю, что он несовместим с Auto Layout, даже если я воссоздаю свои ограничения после его вызова. Спасибо! - person andlabs   schedule 24.08.2015