NSScrollView не прокручивается - PullRequest
0 голосов
/ 29 октября 2018

У меня есть форма в MacApp, которую нужно прокрутить. У меня есть scrollView, встроенный в ViewController. У меня есть scrollView с идентификатором, который связывает его с собственным файлом NSScrollView. Ограничения устанавливаются сверху, справа и слева от контроллера представления, для него также установлено ограничение высоты на полную высоту ViewController.

Вот мой код.

  import Cocoa

    class ScrollView: NSScrollView {

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
        NSRect documentView.NSMakeSize(0, 0, 1058.width, 1232.height)
    }

    override func scrollWheel(with event: NSEvent) {
        switch event.phase {
        case NSEvent.Phase.began:
            Swift.print("Began")
    //        case NSEvent.Phase.changed:
    //            Swift.print("Changed")
        case NSEvent.Phase.ended:
            Swift.print("Ended")
        default:
            break
        }

        switch event.momentumPhase {
        case NSEvent.Phase.began:
            Swift.print("Momentum Began")
    //        case NSEvent.Phase.changed:
    //            Swift.print("Momentum Changed")
        case NSEvent.Phase.ended:
            Swift.print("Momentum Ended")
        default:
            break
        }
        super.scrollWheel(with: event)
    }

Кажется, я не могу прокрутить приложение. Я думаю, что я не устанавливаю кадр правильно. Каков наилучший способ правильно установить кадр? Я правильно кодирую NSScrollView?

Спасибо

Капуста

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Я только что преодолел «горб» с 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))
        }
    }
}
0 голосов
/ 30 октября 2018

Я думаю, что вы делаете свою жизнь очень тяжелой, потому что вы делаете вещи, которые не совсем рекомендуются Apple. Прежде всего, вы не должны подкласс NSScrollView. Скорее вам следует сначала прочитать Введение в руководство по программированию Scroll View для какао от Apple, чтобы понять, как создать правильную иерархию представлений для NSScrollView для правильной работы.

Вторая рекомендация для вас - проверить эту хорошую статью о том, как установить NSScrollView на игровой площадке, чтобы вы могли поиграть с кодом, который хотите реализовать.

В-третьих, использование Autolayout и NSScrollView вызвало много горя у многих людей. Вам нужно правильно настроить AutoLayout, чтобы все работало как положено. Я рекомендую вам проверить этот ответ Кена Томаса, который ясно объясняет, как вам нужно настроить ограничения автоматического размещения для NSScrollView для правильной работы.

...