Как прикрепить NSViewController к вершине NSPopover во время NSViewController.transition? - PullRequest
3 голосов
/ 29 февраля 2020

Я пытался создать скользящий переход от одного дочернего контроллера представления к другому внутри NSPopover.

Моя проблема заключается в том, что дочерние контроллеры представления не придерживаются вершины NSPopover во время перехода , Они анимируются снизу или сверху:

Demo GIF

Ожидаемое поведение: оба контроллера дочернего представления должны придерживаться вершины во время перехода и должны просто скользить по по горизонтали.

Это функция, которую я написал для запуска перехода:

func loadViewController(_ childViewController: NSViewController, withTransition transitionOptions: NSViewController.TransitionOptions?) {
        addChild(childViewController)
        view.addSubview(childViewController.view)

        childViewController.view.layer?.borderColor = NSColor(calibratedRed: 0, green: 255, blue: 0, alpha: 1).cgColor
        childViewController.view.layer?.borderWidth = 2

        childViewController.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        view.layout()

        let oldViewController = currentViewController
        currentViewController = childViewController

        oldViewController?.view.layer?.borderColor = NSColor(calibratedRed: 255, green: 0, blue: 0, alpha: 1).cgColor
        oldViewController?.view.layer?.borderWidth = 2

        if let oldViewController = oldViewController  {
            transition(from: oldViewController, to: currentViewController!, options: transitionOptions ?? .slideLeft, completionHandler: { [weak oldViewController] in
                oldViewController?.removeFromParent()
                oldViewController?.view.removeFromSuperview()
            })
        }

        NSAnimationContext.runAnimationGroup({ (context) -> Void in
            context.duration = 0.5
            context.allowsImplicitAnimation = true

            self.parentPopover?.contentSize = NSSize(width: childViewController.preferredContentSize.width, height: childViewController.preferredContentSize.height)
        })
    }

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

Я загрузил полный воспроизводимый пример здесь: https://github.com/maximilianschmitt/DebugPopoverAnimation

Большое спасибо за вашу помощь!

1 Ответ

1 голос
/ 02 марта 2020

Если вы ожидаете, как показано на анимации ниже

demo

, просто удалите обновление размера контента из блока анимации, как показано ниже

self.parentPopover?.contentSize = NSSize(width: childViewController.preferredContentSize.width, height: childViewController.preferredContentSize.height)
NSAnimationContext.runAnimationGroup({ (context) -> Void in
    context.duration = 0.5
    context.allowsImplicitAnimation = true

}) {
    oldViewController?.removeFromParent()
    oldViewController?.view.removeFromSuperview()
}

Обновление: поддерживает анимируемость содержимого popover (вышеуказанные изменения не требуются)

demo2

В этом случае единственное, что вам нужно, - это перевернуть систему координат для просмотра содержимого popover (что представление MasterViewController)

class PopoverContentView: NSView {
    override var isFlipped: Bool { true }
}

class MasterViewController: NSViewController {
    ...
    override func loadView() {
        self.view = PopoverContentView()
    }
...