NSScrollView con diseño automático que no cambia de tamaño hasta el primer cambio manual de ventana

Tengo una aplicación OSX Cocoa que se ha creado mediante programación (es decir, no con un NIB / XIB), que estoy tratando de diseñar usando el diseño automático, pero obtengo un comportamiento extraño cuando aparece la ventana por primera vez.

Mi contenido principal es un NSView que tiene una colección de 100 NSButtons como subvistas, dispuestas verticalmente. Todos los botones están restringidos en relación con el NSView y entre sí; tanto el NSView como todos los NSButtons tienentranslatesAutoresizingMaskIntoConstraints=NO conjunto. Creo que el código para la vista de contenido es bueno (es decir, sin diseños ambiguos, etc.), porque si configuro contentView de la ventana principal en NSView, los botones se muestran como se esperaba.

Sin embargo, si configuro el contentView de la ventana principal como NSScrollView, y configuro el documentView de NSScrollView como NSView, me aparecen problemas de visualización.

En la primera pantalla, aparece una ventana en blanco, sin barras de desplazamiento, nada:

El NSScrollView tienetranslatesAutoresizingMaskIntoConstraints=NO. Para fines de depuración, también configuré el color de fondo de NSScrollView en azul para poder confirmar lo que se presenta en cada lugar, pero no se muestra azul en ningún lado.

Pero, tan pronto como cambio el tamaño de la ventana, el diseño se activa y obtengo un NSScrollView del tamaño completo de la ventana principal, con fondo azul y barras de desplazamiento como se esperaba:

He leído algunas referencias que sugieren que el problema es la falta de restricciones en el clipView que forma parte del NSScrollView. Sobre esa base, he intentado configurar restricciones vinculantes[NSScrollView contentView] a[NSScrollView documentView] en las direcciones vertical y horizontal (con constante 0, multiplicador 1, a la izquierda, derecha, arriba y abajo). Cuando hago esto, el NSScrollView ahora es visible en la primera pantalla, pero tiene el tamaño incorrecto. El desplazamiento no desplaza la altura total del contenido interno; el contenido desplazable se desplaza como si tuviera el mismo tamaño que la ventana visible. Por último, el contenido se superpone a la barra de título de la ventana:

Nuevamente, tan pronto como cambio el tamaño de la ventana, las restricciones entran en acción y la ventana se muestra como esperaba (ver la captura de pantalla anterior). Entonces, supongo que las restricciones adicionales no duelen, pero tampoco parecen agregar nada.

Otros asuntos confusos: si dejo los botones desactivados por completo y solo uso un NSView vacío sin subvistas como vista de contenido, obtendré una ventana azul completa al inicio, como era de esperar.

Entonces, ¿qué está pasando aquí? Parece que me estoy perdiendo una llamada para forzar la evaluación de restricciones en los botones; ¿Es ese el caso, o está sucediendo algo más aquí?

Para aquellos interesados, aquí está mi código de muestra. No es el Objetivo C, es Python, pero el enlace del lenguaje puede convertir los nombres de los métodos de Python en mensajes del Objetivo C; la asignación a la API nativa de ObjectiveC debería ser obvia:

app = NSApplication.sharedApplication()
app.setActivationPolicy_(NSApplicationActivationPolicyRegular)

main_window = NSWindow.alloc().initWithContentRect_styleMask_backing_defer_(
    NSMakeRect(100, 100, 640, 480),
    NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask,
    NSBackingStoreBuffered,
    False)

scrollview = NSScrollView.alloc().init()
scrollview.setHasVerticalScroller_(True)
scrollview.setHasHorizontalScroller_(True)
scrollview.setAutohidesScrollers_(True)
scrollview.setBorderType_(NSNoBorder)
scrollview.setTranslatesAutoresizingMaskIntoConstraints_(False)

scrollview.backgroundColor = NSColor.blueColor()

container = NSView.alloc().init()
container.setTranslatesAutoresizingMaskIntoConstraints_(False)

buttons = [
    NSButton.alloc().init()
    for b in range(0, 100)
]

for i, button in enumerate(buttons):
    button.setBezelStyle_(NSRoundedBezelStyle)
    button.setButtonType_(NSMomentaryPushInButton)
    button.setTitle_(get_NSString('Button %s' % i))
    button.setTranslatesAutoresizingMaskIntoConstraints_(False)

    container.addSubview_(button)

    if i == 0:
        container.addConstraint_(NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(
            button, NSLayoutAttributeTop,
            NSLayoutRelationEqual,
            container, NSLayoutAttributeTop,
            1, 50,
        ))
    else:
        container.addConstraint_(NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(
            button, NSLayoutAttributeBottom,
            NSLayoutRelationEqual,
            buttons[i-1], NSLayoutAttributeBottom,
            1, 50,
        ))

    container.addConstraint_(NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(
        button, NSLayoutAttributeLeft,
        NSLayoutRelationEqual,
        container, NSLayoutAttributeLeft,
        1, 50,
    ))

    container.addConstraint_(NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(
        button, NSLayoutAttributeRight,
        NSLayoutRelationEqual,
        container, NSLayoutAttributeRight,
        1, -50,
    ))

container.addConstraint_(NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_(
    buttons[-1], NSLayoutAttributeBottom,
    NSLayoutRelationEqual,
    container, NSLayoutAttributeBottom,
    1, -50,
))

scrollview.setDocumentView_(container)

main_window.setContentView_(scrollview)

main_window.makeKeyAndOrderFront_(None)

app.activateIgnoringOtherApps_(True)
app.run()

Respuestas a la pregunta(3)

Su respuesta a la pregunta