From 78a2bb486004cfe3b07bbfcfc3dbae27844c5391 Mon Sep 17 00:00:00 2001 From: Dominic Go Date: Sun, 6 Oct 2024 08:24:52 +0800 Subject: [PATCH] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20Impl:=20`RNIModalSheetBott?= =?UTF-8?q?omAttachedOverlayController`=20Scaffolding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...SheetBottomAttachedOverlayController.swift | 37 ++++ .../RNIModalSheetDecorationController.swift | 179 ------------------ .../RNIModalSheetViewController.swift | 68 +++++-- .../RNIModalSheetViewDelegate.swift | 31 ++- 4 files changed, 101 insertions(+), 214 deletions(-) create mode 100644 ios/RNIModalSheetView/RNIModalSheetBottomAttachedOverlayController.swift delete mode 100644 ios/RNIModalSheetView/RNIModalSheetDecorationController.swift diff --git a/ios/RNIModalSheetView/RNIModalSheetBottomAttachedOverlayController.swift b/ios/RNIModalSheetView/RNIModalSheetBottomAttachedOverlayController.swift new file mode 100644 index 00000000..f6023c88 --- /dev/null +++ b/ios/RNIModalSheetView/RNIModalSheetBottomAttachedOverlayController.swift @@ -0,0 +1,37 @@ +// +// RNIModalSheetBottomAttachedOverlayController.swift +// react-native-ios-modal +// +// Created by Dominic Go on 10/6/24. +// + +import UIKit +import DGSwiftUtilities +import react_native_ios_utilities + + +public class RNIModalSheetBottomAttachedOverlayController: + ModalSheetBottomAttachedOverlayController { + + public override func setupContent() { + defer { + super.setupContent(); + }; + + // MARK: TODO TEMP! + self.contentController = DummyContentController(); + self.view.backgroundColor = .red; + }; +}; + +// MARK: TODO - TEMP! +public class DummyContentController: UIViewController { + public override func viewDidLoad() { + self.view.backgroundColor = .blue; + + self.view.translatesAutoresizingMaskIntoConstraints = false; + NSLayoutConstraint.activate([ + self.view.heightAnchor.constraint(equalToConstant: 100), + ]); + }; +}; diff --git a/ios/RNIModalSheetView/RNIModalSheetDecorationController.swift b/ios/RNIModalSheetView/RNIModalSheetDecorationController.swift deleted file mode 100644 index be6cbdb3..00000000 --- a/ios/RNIModalSheetView/RNIModalSheetDecorationController.swift +++ /dev/null @@ -1,179 +0,0 @@ -// -// RNIModalSheetDecorationController.swift -// react-native-ios-modal -// -// Created by Dominic Go on 10/3/24. -// - -import UIKit -import DGSwiftUtilities -import react_native_ios_utilities - -#if !RCT_NEW_ARCH_ENABLED -import React -#endif - -/// Holds/wraps a `RNIBaseView` instance (i.e. `RNIContentViewParentDelegate`) -/// -open class RNIModalSheetDecorationController: UIViewController { - - public var shouldTriggerDefaultCleanup = true; - - public weak var rootReactView: RNIContentViewParentDelegate?; - - public var positionConfig: AlignmentPositionConfig = .default; - - // MARK: - Computed Properties - // --------------------------- - - public var contentView: RNIContentViewDelegate? { - self.rootReactView?.contentDelegate; - }; - - // MARK: - View Controller Lifecycle - // --------------------------------- - - public override func viewDidLoad() { - guard let rootReactView = self.rootReactView else { - return; - }; - - #if DEBUG && false - self.log(); - #endif - - // MARK: Setup Constraints - #if !RCT_NEW_ARCH_ENABLED - rootReactView.removeAllAncestorConstraints(); - #endif - - rootReactView.translatesAutoresizingMaskIntoConstraints = false; - self.view.addSubview(rootReactView); - - NSLayoutConstraint.activate([ - rootReactView.leadingAnchor.constraint( - equalTo: rootReactView.leadingAnchor - ), - rootReactView.trailingAnchor.constraint( - equalTo: rootReactView.leadingAnchor - ), - rootReactView.bottomAnchor.constraint( - equalTo: rootReactView.bottomAnchor - ), - rootReactView.topAnchor.constraint( - equalTo: rootReactView.topAnchor - ), - ]); - }; - - public override func viewDidLayoutSubviews() { - guard let rootReactView = self.rootReactView else { - return; - }; - - #if DEBUG && false - self.log(); - DispatchQueue.main.asyncAfter(deadline: .now() + 2){ - self.log(); - }; - #endif - }; - - open override func didMove(toParent parent: UIViewController?) { - guard let parent = parent else { - return; - }; - - let constraints = self.positionConfig.createConstraints( - forView: self.view, - attachingTo: parent.view, - enclosingView: parent.view - ); - - self.view.translatesAutoresizingMaskIntoConstraints = false; - NSLayoutConstraint.activate([ - self.view.leadingAnchor.constraint(equalTo: parent.view.leadingAnchor), - self.view.trailingAnchor.constraint(equalTo: parent.view.trailingAnchor), - self.view.bottomAnchor.constraint(equalTo: parent.view.bottomAnchor), - self.view.heightAnchor.constraint(equalToConstant: 100), - ]); - } - - // MARK: Methods - // -------------- - - #if DEBUG - func log(funcString: String = #function){ - print( - "RNIModalSheetDecorationController.\(funcString)", - "\n - positionConfig:", self.positionConfig, - - "\n - window.size:", - self.view.window?.bounds.size.debugDescription ?? "N/A", - - "\n - view.size:", self.view.bounds.size, - - "\n - view.globalFrame:", - self.view.globalFrame?.debugDescription ?? "N/A", - - "\n - view.layer.frame:", - self.view.layer.presentation()?.frame.debugDescription ?? "N/A", - - "\n - superview.size:", - self.view.superview?.bounds.size.debugDescription ?? "N/A", - - "\n - superview.globalFrame:", - self.view.superview?.globalFrame?.debugDescription ?? "N/A", - - "\n - rootReactView.size:", - self.rootReactView?.bounds.size.debugDescription ?? "N/A", - - "\n - rootReactView.cachedLayoutMetrics.contentFrame:", - self.rootReactView?.cachedLayoutMetrics?.contentFrame.debugDescription ?? "N/A", - - "\n - rootReactView.globalFrame:", - self.rootReactView?.globalFrame?.debugDescription ?? "N/A", - - "\n - rootReactView.layer.frame:", - self.rootReactView?.layer.presentation()?.frame.debugDescription ?? "N/A", - - "\n - rootReactView.intrinsicContentSize:", - self.rootReactView?.intrinsicContentSize.debugDescription ?? "N/A", - - "\n - contentDelegate.bounds.size:", - self.rootReactView?.contentDelegate.bounds.size.debugDescription ?? "N/A", - - "\n - contentDelegate.globalFrame:", - self.rootReactView?.contentDelegate.globalFrame?.debugDescription ?? "N/A", - - "\n - contentDelegate.layer.frame:", - self.rootReactView?.contentDelegate.layer.presentation()?.frame.debugDescription ?? "N/A", - - "\n" - ); - }; - #endif -}; - -extension RNIModalSheetDecorationController: RNIViewLifecycle { - - public func notifyOnRequestForCleanup(sender: RNIContentViewParentDelegate) { - guard self.shouldTriggerDefaultCleanup, - self.view.window != nil - else { - return; - }; - - if self.presentingViewController != nil { - self.dismiss(animated: true); - - } else if self.parent != nil { - self.willMove(toParent: nil); - self.view.removeFromSuperview(); - self.removeFromParent(); - - } else { - self.view.removeFromSuperview(); - }; - }; -}; diff --git a/ios/RNIModalSheetView/RNIModalSheetViewController.swift b/ios/RNIModalSheetView/RNIModalSheetViewController.swift index e3086976..93f28a28 100644 --- a/ios/RNIModalSheetView/RNIModalSheetViewController.swift +++ b/ios/RNIModalSheetView/RNIModalSheetViewController.swift @@ -22,6 +22,8 @@ open class RNIModalSheetViewController: ModalSheetViewControllerLifecycleNotifie private(set) public weak var mainSheetContent: RNIWrapperViewContent?; public var positionConfigForMainSheetContent: AlignmentPositionConfig = .default; + + public var bottomOverlayController: RNIModalSheetBottomAttachedOverlayController?; // MARK: - Computed Properties // --------------------------- @@ -46,6 +48,36 @@ open class RNIModalSheetViewController: ModalSheetViewControllerLifecycleNotifie public override func viewDidLoad() { super.viewDidLoad(); + self.setupMainContent(); + //self.setupBottomOverlayIfNeeded(); + }; + + public override func viewIsAppearing(_ animated: Bool) { + self.setupBottomOverlayIfNeeded(); + }; + + public override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews(); + + guard let mainSheetContentParent = self.mainSheetContentParent else { + return; + }; + + self.positionConfigForMainSheetContent.setIntrinsicContentSizeOverrideIfNeeded( + forRootReactView: mainSheetContentParent, + withSize: self.view.bounds.size + ); + + self.positionConfigForMainSheetContent.applySize( + toRootReactView: mainSheetContentParent, + attachingTo: self.view + ); + }; + + // MARK: Methods + // -------------- + + func setupMainContent(){ guard let mainSheetContentParent = self.mainSheetContentParent, let mainSheetContent = mainSheetContentParent.contentDelegate as? RNIWrapperViewContent else { @@ -91,27 +123,31 @@ open class RNIModalSheetViewController: ModalSheetViewControllerLifecycleNotifie ); }; }; - - public override func viewWillLayoutSubviews() { - super.viewWillLayoutSubviews(); - - guard let mainSheetContentParent = self.mainSheetContentParent else { + + func setupBottomOverlayIfNeeded(){ + guard let bottomOverlayController = self.bottomOverlayController, + let targetView = self.closestSheetDropShadowView?.superview + else { return; }; - - self.positionConfigForMainSheetContent.setIntrinsicContentSizeOverrideIfNeeded( - forRootReactView: mainSheetContentParent, - withSize: self.view.bounds.size + + // let the child setup constraints + add itself as it's subview... + // but, is this okay? + // + // wouldn't it be better if the logic for layout be handled in the child + // vc's `didMove` lifecycle method? + // + // + bottomOverlayController.attachView( + anchoredToBottomEdgesOf: targetView, + withSheetContainerView: self.view ); - self.positionConfigForMainSheetContent.applySize( - toRootReactView: mainSheetContentParent, - attachingTo: self.view - ); + targetView.bringSubviewToFront(bottomOverlayController.view); + + self.addChild(bottomOverlayController); + bottomOverlayController.didMove(toParent: parent); }; - - // MARK: Methods - // -------------- }; extension RNIModalSheetViewController: RNIViewLifecycle { diff --git a/ios/RNIModalSheetView/RNIModalSheetViewDelegate.swift b/ios/RNIModalSheetView/RNIModalSheetViewDelegate.swift index 837b36fe..0c7fc5d0 100644 --- a/ios/RNIModalSheetView/RNIModalSheetViewDelegate.swift +++ b/ios/RNIModalSheetView/RNIModalSheetViewDelegate.swift @@ -56,7 +56,7 @@ public final class RNIModalSheetViewDelegate: UIView, RNIContentView { public var modalSheetController: RNIModalSheetViewController?; public var sheetMainContentParentView: RNIContentViewParentDelegate?; - public var sheetBottomAttachedOverlayController: RNIModalSheetDecorationController?; + public var sheetBottomAttachedOverlayController: RNIModalSheetBottomAttachedOverlayController?; public var sheetBottomAttachedOverlayParentView: RNIContentViewParentDelegate?; // MARK: - Properties - RNIContentViewDelegate @@ -121,24 +121,17 @@ public final class RNIModalSheetViewDelegate: UIView, RNIContentView { modalVC.sheetPresentationStateMachine.eventDelegates.add(self); modalVC.modalFocusEventDelegates.add(self); - if let sheetBottomAttachedOverlayParentView = self.sheetBottomAttachedOverlayParentView { - let childVC = RNIModalSheetDecorationController(); - self.sheetBottomAttachedOverlayController = childVC; - - childVC.rootReactView = sheetBottomAttachedOverlayParentView; - - childVC.positionConfig = .init( - horizontalAlignment: .stretchTarget, - verticalAlignment: .targetBottom - ); - - childVC.view.backgroundColor = .red; - childVC.view.alpha = 0.5; - - modalVC.view.addSubview(childVC.view); - modalVC.addChild(childVC); - childVC.didMove(toParent: modalVC); - }; + // TODO: TEMP!! + let childVC = RNIModalSheetBottomAttachedOverlayController(); + modalVC.bottomOverlayController = childVC; + + // if let sheetBottomAttachedOverlayParentView = self.sheetBottomAttachedOverlayParentView { + // let childVC = RNIModalSheetBottomAttachedOverlayController(); + // self.sheetBottomAttachedOverlayController = childVC; + // modalVC.bottomAttachedOverlayController = childVC; + // + // childVC.mainContentView = sheetBottomAttachedOverlayParentView; + // }; return modalVC; };