Я только что преодолел «горб» с NSScrollView внутри NSWindow. Чтобы прокрутка происходила, представление внутри NSScrollview должно быть больше, чем окно контента. Это трудно установить с помощью динамических ограничений. Статическая установка внутреннего вида на большую ширину / высоту, чем окно «работает», но статические размеры обычно не соответствуют вашим ожиданиям.
Вот моя иерархия и ограничения представления построителя интерфейса, не включая программно добавленные блоки
В моем приложении пользователь добавляет «ящики» (настраиваемые перетаскиваемые виды) в mainView, который находится внутри scrollview в NSwindow.
Вот функциональность, которую я хотел:
1) Если я развернул окно NSWindow, я хотел, чтобы основной вид внутри прокрутки развернулся, чтобы заполнить все окно. В этом случае прокрутка не требуется, если видны все поля.
2) Если я сократил NSWindow, я хотел, чтобы mainView внутри scrollview сжимался настолько, чтобы включить все мои подпредставления mainView («блоки»), но не дальше (я добавил minBorder из 20). Это приводит к прокрутке, если позиция блока дальше вправо / вверх, чем ширина / высота nswindow.
Я обнаружил, что хитрость заключается в том, чтобы рассчитать размер основного вида, который я хочу, на основе максимального угла каждого перетаскиваемого окна или высоты / ширины фрейма содержимого nswindow, в зависимости от того, что больше.
Ниже приведен мой код, включая некоторые отладочные отпечатки.
Будьте осторожны с тем, какие подпредставления вы используете для расчета максимального размера. Если вы включите подпредставление, которое динамически присоединяется к правой / верхней части окна, то ваше окно никогда не будет уменьшаться. Если к этому добавить границу +20, вы можете получить бесконечный цикл. Не проблема в моем случае.
extension MapWindowController: NSWindowDelegate {
func windowDidEndLiveResize(_ notification: Notification) {
if let frame = window?.frame, let content = window?.contentRect(forFrameRect: frame) {
print("window did resize \(frame)")
var maxX: CGFloat = content.width
var maxY: CGFloat = content.height
for view in mainView?.subviews ?? [] {
let frameMaxX = view.frame.maxX + minBorder
let frameMaxY = view.frame.maxY + minBorder
if frameMaxX > maxX {
maxX = frameMaxX
}
if frameMaxY > maxY {
maxY = frameMaxY
}
}
print("view maxX \(maxX) maxY \(maxY)")
print("window width \(content.width) height \(content.height)")
mainView?.setFrameSize(NSSize(width: maxX, height: maxY))
}
}
}