Как мне выбрать NSWindow с автоматическим макетом? - PullRequest
0 голосов
/ 19 апреля 2020

Опробовал код проекта SwiftUI по умолчанию, который Xcode делает для проектов документов на основе macOS. Я переместил код создания окна из подкласса NSDocument в новый подкласс NSWindowController. Это началось так:

init() {
    let content = ContentView()
    let windowSize = NSRect(x: 0, y: 0, width: Constants.defaultWidth, height: Constants.defaultHeight)
    let window = NSWindow(contentRect: windowSize, styleMask: Constants.windowStyle, backing: .buffered, defer: false)
    window.contentView = NSHostingView(rootView: content)
    super.init(window: window)

    // Other setup.
    window.center()
    window.delegate = self
}

Теперь я хочу попробовать создать окно без указания его прямоугольника. Для этого есть инициализатор, который использует NSViewController для базы:

init() {
    let content = ContentView()
    let controller = NSHostingController(rootView: content)
    let window = NSWindow(contentViewController: controller)
    //window.contentMinSize = NSSize(width: Constants.defaultWidth, height: Constants.defaultHeight)
    window.styleMask.formUnion(.fullSizeContentView)
    super.init(window: window)

    // Other setup.
    //window.center()
    window.delegate = self
}

ContentView - это просто код Xcode по умолчанию, только с Hello World! текстовый блок. Кажется, он не имеет внутреннего размера c, поэтому окно уменьшается до нуля. Свойство contentMinSize, которое теперь закомментировано, не исправило его. Затем я прочитал документацию для инициализатора ближе и решил попробовать что-то с автоматическим макетом.

init() {
    // Create and size content.
    let content = ContentView()
    let controller = NSHostingController(rootView: content)
    let guide = NSLayoutGuide()
    controller.view.addLayoutGuide(guide)
    guide.widthAnchor.constraint(greaterThanOrEqualToConstant: CGFloat(Constants.defaultWidth)).isActive = true
    guide.heightAnchor.constraint(greaterThanOrEqualToConstant: CGFloat(Constants.defaultHeight)).isActive = true
    controller.view.translatesAutoresizingMaskIntoConstraints = false
    //controller.view.autoresizesSubviews = false

    let window = NSWindow(contentViewController: controller)
    window.styleMask.formUnion(.fullSizeContentView)
    super.init(window: window)

    // Other setup.
    //window.center()
    window.delegate = self
}

Но у меня все еще есть исчезающее окно. (Закомментированное изменение на autoresizesSubviews не помогло.) Затем я заметил, что там было окно, но с шириной в один пиксель и высотой около двух строк заголовка. Однако, когда я попытался изменить его размер, окно стало видимым, прыгнув до минимального размера, необходимого для текстового блока. После прикосновения я не смог сжать окно ниже того, что нужно для отображения текстового блока. Однако этот минимальный размер по-прежнему меньше, чем мои ширина и высота по умолчанию, поэтому эти настройки игнорируются.

Итак, как я могу контролировать размер окна, если NSWindow.init(contentViewController:) хочет использовать автоматическое расположение?

(Хм, когда я набираю этот запрос, я не уверен, что настройки, которые я установил для guide, связаны с controller.view. Возможно, мне нужно сначала убедиться в этом.)

1 Ответ

0 голосов
/ 19 апреля 2020

Последнее подозрение на использование controller.view вместо нового объекта NSLayoutGuide, похоже, работает.

init() {
    // Create and size content.
    let content = ContentView()
    let controller = NSHostingController(rootView: content)
    controller.view.autoresizesSubviews = false
    controller.view.widthAnchor.constraint(greaterThanOrEqualToConstant: CGFloat(Constants.defaultWidth)).isActive = true
    controller.view.heightAnchor.constraint(greaterThanOrEqualToConstant: CGFloat(Constants.defaultHeight)).isActive = true

    let window = NSWindow(contentViewController: controller)
    window.styleMask.formUnion(.fullSizeContentView)
    super.init(window: window)

    window.delegate = self
}

Но это только регулирует размер; Я не могу выбрать, куда на экране уходит окно.

...