From 01f97d2dd99c7e2a01e585729711d3379a9166b4 Mon Sep 17 00:00:00 2001 From: Muukii Date: Fri, 21 May 2021 02:44:31 +0900 Subject: [PATCH] Patch --- Demo/App/AppOtherViewController.swift | 1 + Demo/App/AppSearchViewController.swift | 149 +++++++++++++++++- Demo/ContentView.swift | 5 + Demo/NavigationSampleViewController.swift | 5 + Demo/SampleViewController.swift | 5 + FluidPresentation/FluidViewController.swift | 8 + .../NavigatedFluidViewController.swift | 1 + FluidPresentation/TransitionControllers.swift | 43 ++++- 8 files changed, 207 insertions(+), 10 deletions(-) diff --git a/Demo/App/AppOtherViewController.swift b/Demo/App/AppOtherViewController.swift index fd75fe7..11ba7ee 100644 --- a/Demo/App/AppOtherViewController.swift +++ b/Demo/App/AppOtherViewController.swift @@ -29,6 +29,7 @@ final class AppOtherController: StackScrollNodeViewController { controller.modalPresentationStyle = .currentContext self.present(controller, animated: true, completion: nil) + }) ]) } diff --git a/Demo/App/AppSearchViewController.swift b/Demo/App/AppSearchViewController.swift index 1d7932f..00408cf 100644 --- a/Demo/App/AppSearchViewController.swift +++ b/Demo/App/AppSearchViewController.swift @@ -5,8 +5,9 @@ // Created by Muukii on 2021/04/14. // -import UIKit +import FluidPresentation import TextureSwiftSupport +import UIKit final class AppSearchViewController: StackScrollNodeViewController { @@ -17,12 +18,152 @@ final class AppSearchViewController: StackScrollNodeViewController { stackScrollNode.append(nodes: [ - Components.makeTitleCell(title: "Search"), + Components.makeSelectionCell( + title: "Open VC stacked", + onTap: { [unowned self] in + + let other = MenuViewController() + NavigatedFluidViewController(idiom: .presentation, bodyViewController: other) + .fluidContext + .present(from: self, animated: true, completion: nil) + + } + ) + ]) + } +} + +private final class MenuViewController: DisplayNodeViewController { + + private let stackScrollNode = StackScrollNode() + + private let child = ChildMenuViewController() + + override func viewDidLoad() { + super.viewDidLoad() + + if #available(iOS 13.0, *) { + view.backgroundColor = .systemBackground + } else { + view.backgroundColor = .white + } + + title = "Menu" + + definesPresentationContext = true + + stackScrollNode.append(nodes: [ + + Components.makeTitleCell(title: "Parent"), + + Components.makeSelectionCell( + title: "Open in FullScreen", + onTap: { [unowned self] in + + let other = MenuViewController() + NavigatedFluidViewController(idiom: .presentation, bodyViewController: other) + .fluidContext + .present(from: self, animated: true, completion: nil) + + } + ), + + Components.makeSelectionCell( + title: "Open in Context", + onTap: { [unowned self] in + + let other = MenuViewController() + NavigatedFluidViewController(idiom: .presentation, bodyViewController: other) + .fluidContext + .present(in: self, animated: true, completion: nil) + + } + ), + ]) + + child: do { + addChild(child) + child.didMove(toParent: self) + } + + } + + override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec { + LayoutSpec { + VStackLayout { + stackScrollNode + .flexBasis(fraction: 0.5) + child.node + .flexGrow(1) + } + } + } + +} + +private final class ChildMenuViewController: DisplayNodeViewController { + + private let stackScrollNode = StackScrollNode() + + override func viewDidLoad() { + super.viewDidLoad() + + if #available(iOS 13.0, *) { + view.backgroundColor = .systemBackground + } else { + view.backgroundColor = .white + } + + title = "Menu" + + definesPresentationContext = true + + stackScrollNode.append(nodes: [ + + Components.makeTitleCell(title: "Child"), + + Components.makeSelectionCell( + title: "Open in FullScreen", + onTap: { [unowned self] in + + let other = MenuViewController() + NavigatedFluidViewController(idiom: .presentation, bodyViewController: other) + .fluidContext + .present(from: self, animated: true, completion: nil) + + } + ), + + Components.makeSelectionCell( + title: "Open in Context", + onTap: { [unowned self] in - Components.makeSelectionCell(title: "Open", onTap: { + let other = MenuViewController() + NavigatedFluidViewController(idiom: .presentation, bodyViewController: other) + .fluidContext + .present(in: self, animated: true, completion: nil) + } + ), - }) + Components.makeSelectionCell( + title: "Open in Context Default", + onTap: { [unowned self] in + + let other = MenuViewController() + other.modalPresentationStyle = .currentContext + self.present(other, animated: true, completion: nil) + + } + ), ]) + } + + override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec { + LayoutSpec { + stackScrollNode + } + } + } diff --git a/Demo/ContentView.swift b/Demo/ContentView.swift index 53dd067..1c2665b 100644 --- a/Demo/ContentView.swift +++ b/Demo/ContentView.swift @@ -31,6 +31,7 @@ struct ContentView: View { case pushNavigationBar case pushInCurrentContext case present + case presentOverFullScreen case presentInCurrentContext case presentInOverCurrentContext case makePresentationContext(Bool) @@ -90,6 +91,10 @@ struct ContentView: View { onAction(.present) } + Button("Present - OverFullScreen") { + onAction(.presentOverFullScreen) + } + Button("Present - CurrentContext") { onAction(.presentInCurrentContext) } diff --git a/Demo/NavigationSampleViewController.swift b/Demo/NavigationSampleViewController.swift index 2789910..a083087 100644 --- a/Demo/NavigationSampleViewController.swift +++ b/Demo/NavigationSampleViewController.swift @@ -64,6 +64,11 @@ final class NavigationSampleViewController: NavigatedFluidViewController { let controller = SampleViewController() controller.setIdiom(.presentation) present(controller, animated: true, completion: nil) + case .presentOverFullScreen: + let controller = SampleViewController() + controller.setIdiom(.presentation) + controller.modalPresentationStyle = .overFullScreen + present(controller, animated: true, completion: nil) case .presentInCurrentContext: let controller = SampleViewController() controller.setIdiom(.presentation) diff --git a/Demo/SampleViewController.swift b/Demo/SampleViewController.swift index c7b57c6..59dfa84 100644 --- a/Demo/SampleViewController.swift +++ b/Demo/SampleViewController.swift @@ -61,6 +61,11 @@ final class SampleViewController: FluidViewController { let controller = SampleViewController() controller.setIdiom(.presentation) present(controller, animated: true, completion: nil) + case .presentOverFullScreen: + let controller = SampleViewController() + controller.setIdiom(.presentation) + controller.modalPresentationStyle = .overFullScreen + present(controller, animated: true, completion: nil) case .presentInCurrentContext: let controller = SampleViewController() controller.modalPresentationStyle = .currentContext diff --git a/FluidPresentation/FluidViewController.swift b/FluidPresentation/FluidViewController.swift index 149a857..f3f9551 100644 --- a/FluidPresentation/FluidViewController.swift +++ b/FluidPresentation/FluidViewController.swift @@ -175,6 +175,8 @@ open class FluidViewController: UIViewController, UIViewControllerTransitioningD open override func viewDidLoad() { super.viewDidLoad() + view.accessibilityIdentifier = "\(type(of: self))" + setupGestures() if let bodyViewController = bodyViewController { @@ -190,6 +192,12 @@ open class FluidViewController: UIViewController, UIViewControllerTransitioningD } } + open override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + Log.debug(.transition, "ViewDidAppear \(self), presenting: \(self.presentingViewController as Any)") + } + /// Set presenting and dismissing transition according to the idiom /// - Parameter idiom: public func setIdiom(_ idiom: Idiom) { diff --git a/FluidPresentation/NavigatedFluidViewController.swift b/FluidPresentation/NavigatedFluidViewController.swift index e88d27e..0b6acdd 100644 --- a/FluidPresentation/NavigatedFluidViewController.swift +++ b/FluidPresentation/NavigatedFluidViewController.swift @@ -64,6 +64,7 @@ open class NavigatedFluidViewController: FluidViewController, UINavigationBarDel open override func viewDidLoad() { super.viewDidLoad() + view.clipsToBounds = true view.addSubview(navigationBar) navigationBar.translatesAutoresizingMaskIntoConstraints = false diff --git a/FluidPresentation/TransitionControllers.swift b/FluidPresentation/TransitionControllers.swift index 12d1432..1ba2b1b 100644 --- a/FluidPresentation/TransitionControllers.swift +++ b/FluidPresentation/TransitionControllers.swift @@ -125,10 +125,23 @@ enum PresentingTransitionControllers { transitionContext.logDebug() - let toView = transitionContext.view(forKey: .to)! + let fromViewController = transitionContext.viewController(forKey: .from)! + let toViewController = transitionContext.viewController(forKey: .to)! + + let fromView = fromViewController.view! + let toView = toViewController.view! + + switch transitionContext.presentationStyle { + case .overFullScreen, .overCurrentContext: + assert(fromView.superview != nil) + default: + transitionContext.containerView.addSubview(fromView) + } transitionContext.containerView.addSubview(toView) + toView.frame = transitionContext.finalFrame(for: toViewController) + toView.transform = .init(translationX: 0, y: toView.bounds.height) let animator = UIViewPropertyAnimator(duration: 0.55, dampingRatio: 1) { @@ -176,6 +189,17 @@ enum PresentingTransitionControllers { let toView = toViewController.view! transitionContext.containerView.backgroundColor = .white + + var restoreForFromView: ((Bool) -> Void)? = nil + + switch transitionContext.presentationStyle { + case .overFullScreen, .overCurrentContext: + assert(fromView.superview != nil) + restoreForFromView = resorationHierarchyForDismissing(toView: fromView) + default: + break + } + transitionContext.containerView.addSubview(fromView) transitionContext.containerView.addSubview(toView) @@ -212,6 +236,7 @@ enum PresentingTransitionControllers { animator.addCompletion { _ in restoration() transitionContext.completeTransition(true) + restoreForFromView?(true) } animator.startAnimation() @@ -234,12 +259,19 @@ enum DismissingTransitionControllers { transitionContext.logDebug() - let fromView = transitionContext.viewController(forKey: .from)!.view! - let toView = transitionContext.viewController(forKey: .to)!.view! + let fromViewController = transitionContext.viewController(forKey: .from)! + let toViewController = transitionContext.viewController(forKey: .to)! - let restore = resorationHierarchyForDismissing(toView: toView) + let fromView = fromViewController.view! + let toView = toViewController.view! + + switch transitionContext.presentationStyle { + case .overFullScreen, .overCurrentContext: + assert(toView.superview != nil) + default: + transitionContext.containerView.addSubview(toView) + } - transitionContext.containerView.addSubview(toView) transitionContext.containerView.addSubview(fromView) let animator = UIViewPropertyAnimator(duration: 0.55, dampingRatio: 1) { @@ -247,7 +279,6 @@ enum DismissingTransitionControllers { } animator.addCompletion { _ in - restore(true) transitionContext.completeTransition(true) }