NSWindow запускается с неправильным размером после установки contentViewController в NSTabViewController

У меня есть проект Xcode с NSWindowController, contentViewController которого был установлен в подкласс NSViewController. Недавно я удалил подкласс NSViewController из раскадровки и заменил contentViewController подклассом NSTabViewController.

Теперь, когда я запускаю приложение, NSWindow открывается с размером 500x500 вместо размера первой вкладки. Более того, в раскадровке я не вижу ни одного представления размером 500 x 500, и этот размер также не задан программно. Само окно имеет другой размер, как и представление в первом NSViewController NSTabViewController.

Я предполагаю, что есть какое-то ограничение, которое я должен где-то установить, но если оно есть, я не знаю, где/как его найти. Использование Xcode 9.2 и High Sierra.

Программная установка размера окна на правильный размер в windowDidLoad() работает, но если я когда-нибудь изменю размер представления, мне придется изменить и это, что быстро устареет.

Извините, если это расплывчато; Я действительно понятия не имею, какой снимок экрана или фрагмент кода был бы полезен.


person tiltowait    schedule 30.01.2018    source источник
comment
Проблема все еще присутствует в Xcode 11.4   -  person    schedule 06.03.2020
comment
@RaffaeleCandeliere вы добавили в представление подпредставления и ограничения?   -  person Willeke    schedule 04.06.2020
comment
@Willeke Что именно вы имеете в виду под просмотром? У меня есть подпредставления (с ограничениями и т. д.) на каждой отдельной вкладке моего представления вкладок, но я не уверен, что вы говорите о них. Однако я обошел проблему с помощью этого решения (gist.github.com/mminer/caec00d2165362ff65e9f1f728cecae2). Это не исправление, но оно работает для моих нужд.   -  person    schedule 05.06.2020


Ответы (3)


Недавно тоже столкнулся с этой неприятной проблемой.

Есть несколько вариантов решения этой проблемы:

  1. Как вы упомянули, установите preferredContentSize в каждом из ваших настраиваемых контроллеров представления, которые содержат содержимое вкладки до желаемого размера. Это негибко, но это работает.

    // Swift
    class FooViewController: ViewController {
    
        override func viewWillAppear() {
            super.viewWillAppear()
    
            preferredContentSize = NSSize(width: 400, height: 280)
        }
    }
    
  2. Я нашел подсказку о лучшем решении в этом ТАК отвечайте. Вы можете добавить подпредставление (stackview, nsview и т. д.) к основному представлению контроллера представления, которое обрабатывает содержимое вкладки (уф!), а затем добавить ограничения, закрепляющие его на каждом краю, и добавить ограничения, устанавливающие размер.

Вот скриншот того, как это выглядит в Interface Builder. Я добавил представление стека, а затем добавил 6 ограничений.

Надеюсь это поможет.

person Joshua Lynch    schedule 05.04.2018

ответ Джошуа с настройкой preferredContentSize сделал свое дело, за что ему большое спасибо! Одно замечание, которое стоит сделать, заключается в том, что, поскольку это делается исключительно для родительского контроллера представления вкладок, хорошей идеей будет создать его подкласс и перенести эту обработку в метод делегата tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?), который вызывается при выборе вкладки:

override func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) {
    tabViewItem?.viewController?.preferredContentSize = tabViewItem?.view?.frame.size
    // Alternatively: tabViewItem?.viewController?.preferredContentSize = tabViewItem?.view?.fittingSize
    super.tabView(tabView, didSelect: tabViewItem)
}

Таким образом, предпочтительный размер содержимого всегда актуален, и вы можете не беспокоиться о его ручном обновлении, предполагая, что представление обеспечивает правильный размер кадра или подходящий размер, что легко достигается с помощью ограничений.

Этот метод также вызывается после завершения загрузки оконного контроллера и при первоначальной установке 500×500.

Установка предпочтительного размера контента в каждом контроллере представления с вкладками сама по себе не идеальна: один и тот же код дублируется на нескольких контроллерах и добавляет ненужный шум, если эти контроллеры повторно используются в другом месте.

person Ian Bytchek    schedule 26.01.2019

У меня была аналогичная проблема. Я добавил контроллер представления с представлением контейнера в качестве содержимого окна и указал содержимое представления контейнера на контроллер представления вкладки.

person Steven    schedule 03.05.2018