Skip to content

Commit

Permalink
🛠 Refactor: Use RNIModalView
Browse files Browse the repository at this point in the history
Related:
* `TODO:2023-03-28-18-52-17` - Pre-migration to `react-native-ios-utilites`.
* `2023-03-29-05-04-40` - Refactor: Update `RNIModalView` + `ModalView` to use `RNIWrapperView`.

Summary: Refactor to use `RNIModalView`.
  • Loading branch information
dominicstop committed Mar 30, 2023
1 parent 544a2d6 commit a53fb36
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 180 deletions.
148 changes: 29 additions & 119 deletions ios/src_library/React Native/RNIModalView/RNIModalView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ class RNIModalView: UIView, RNIModalFocusNotifying, RNIModalIdentity,

typealias CompletionHandler = (_ isSuccess: Bool, _ error: RNIModalViewError?) -> Void;

enum NativeIDKey: String {
case modalViewContent;
};

// MARK: - Properties
// ------------------

weak var bridge: RCTBridge?;

private var modalVC: RNIModalViewController?;
var modalContentWrapper: RNIWrapperView?;
var modalVC: RNIModalViewController?;

private var touchHandler: RCTTouchHandler!;
private var reactSubview: UIView?;

// MARK: - Properties - RNIModalFocusNotifying
// -------------------------------------------
Expand Down Expand Up @@ -256,8 +259,6 @@ class RNIModalView: UIView, RNIModalFocusNotifying, RNIModalIdentity,
super.init(frame: CGRect());

self.bridge = bridge;
self.touchHandler = RCTTouchHandler(bridge: self.bridge);

RNIModalManagerShared.register(modal: self);
};

Expand All @@ -269,26 +270,6 @@ class RNIModalView: UIView, RNIModalFocusNotifying, RNIModalIdentity,
// MARK: - UIKit Lifecycle
// -----------------------

override func layoutSubviews() {
super.layoutSubviews();

guard let modalVC = self.modalVC,
let reactSubview = self.reactSubview else { return };

#if DEBUG
print(
"Log - RNIModalView.layoutSubviews"
+ " - self.modalNativeID: '\(self.modalNativeID!)'"
+ " - Unable to parse string value"
+ " - instance reactTag: '\(self.reactTag ?? -1)'"
);
#endif

if !reactSubview.isDescendant(of: modalVC.view) {
modalVC.reactView = reactSubview;
};
};

override func didMoveToWindow() {
super.didMoveToWindow();
if self.presentViaMount {
Expand All @@ -309,79 +290,35 @@ class RNIModalView: UIView, RNIModalFocusNotifying, RNIModalIdentity,
override func insertReactSubview(_ subview: UIView!, at atIndex: Int) {
super.insertReactSubview(subview, at: atIndex);

guard (self.reactSubview == nil) else {
#if DEBUG
print(
"Error - RNIModalView.insertReactSubview"
+ " - self.modalNativeID: '\(self.modalNativeID!)'"
+ " - arg subview.reactTag: \(subview.reactTag ?? -1)"
+ " - arg atIndex: \(atIndex)"
+ " - Guard check failed: Modal view can only have one subview "
);
#endif
return;
};

#if DEBUG
print(
"Log - RNIModalView.insertReactSubview"
+ " - self.modalNativeID: '\(self.modalNativeID!)'"
+ " - arg subview.reactTag: \(subview.reactTag ?? -1)"
+ " - arg atIndex: \(atIndex)"
);
#endif

subview.removeFromSuperview();
subview.frame = CGRect(
origin: CGPoint(x: 0, y: 0),
size : CGSize(width: 0, height: 0)
);

if let newBounds = modalVC?.view.bounds {
self.bridge?.uiManager.setSize(newBounds.size, for: subview);
guard let wrapperView = subview as? RNIWrapperView,
let nativeID = subview.nativeID,
let nativeIDKey = NativeIDKey(rawValue: nativeID)
else { return };

self.initControllers();
wrapperView.isMovingToParent = true;

switch nativeIDKey {
case .modalViewContent:
if let oldModalContentWrapper = self.modalContentWrapper,
wrapperView !== oldModalContentWrapper {

oldModalContentWrapper.cleanup();
self.modalContentWrapper = nil;

self.deinitControllers();
};

self.modalContentWrapper = wrapperView;
self.initControllers();
};

self.reactSubview = subview;
self.touchHandler.attach(to: subview);

// modal contents has been mounted, and is about to be presented so
// prepare for modal presentation and init the vc's
self.initControllers();
wrapperView.removeFromSuperview();
wrapperView.isMovingToParent = false;
};

override func removeReactSubview(_ subview: UIView!) {
super.removeReactSubview(subview);

guard self.reactSubview == subview else {
#if DEBUG
print(
"Error - RNIModalView.removeReactSubview"
+ " - self.modalNativeID: '\(self.modalNativeID!)'"
+ " - arg subview.reactTag: '\(subview.reactTag ?? -1)'"
+ " - Cannot remove view other than modal view"
+ " - reactSubview.reactTag: '\(reactSubview?.reactTag ?? -1)'"
);
#endif
return;
};

#if DEBUG
print(
"Log - RNIModalView.removeReactSubview"
+ " - self.modalNativeID: '\(self.modalNativeID!)'"
+ " - arg subview.reactTag: '\(subview.reactTag ?? -1)'"
+ " - Cannot remove view other than modal view"
+ " - reactSubview.reactTag: '\(reactSubview?.reactTag ?? -1)'"
);
#endif

// modal contents has been unmounted so reset react subview
self.reactSubview = nil;
self.modalVC?.reactView = nil;

// cleanup
self.touchHandler.detach(from: subview);
self.deinitControllers();
};

// MARK: - Functions - Private
Expand All @@ -404,18 +341,10 @@ class RNIModalView: UIView, RNIModalFocusNotifying, RNIModalIdentity,

vc.blurEffectStyle = self.synthesizedModalBGBlurEffectStyle;

vc.boundsDidChangeBlock = { [weak self] (newBounds: CGRect) in
self?.notifyForBoundsChange(newBounds);
};

vc.presentationController?.delegate = self;

return vc;
}();
};

/// TODO:2023-03-22-12-18-37 - Refactor: Remove `deinitControllers`
/// * Refactor so that we don't have to constantly cleanup...
private func deinitControllers(){
#if DEBUG
print(
Expand All @@ -424,29 +353,10 @@ class RNIModalView: UIView, RNIModalFocusNotifying, RNIModalIdentity,
);
#endif

self.modalVC?.reactView = nil;

self.modalVC = nil;
self.presentingViewController = nil;
};

private func notifyForBoundsChange(_ newBounds: CGRect){
guard let bridge = self.bridge,
let reactSubview = self.reactSubview
else { return };

#if DEBUG
print(
"LOG - RNIModalView.notifyForBoundsChange"
+ " - self.modalNativeID: \(self.modalNativeID!)"
+ " - args newBounds: \(newBounds)"
+ " - reactSubview.bounds: \(reactSubview.bounds)"
);
#endif

bridge.uiManager.setSize(newBounds.size, for: reactSubview);
};

private func enableSwipeGesture(_ flag: Bool? = nil){
self.modalVC?
.presentationController?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class RNIModalViewController: UIViewController {
// MARK: - Properties
// ------------------

var prevViewFrame: CGRect?;
var prevBounds: CGRect?;
var boundsDidChangeBlock: ((CGRect) -> Void)?;

weak var modalViewRef: RNIModalView?;
Expand All @@ -40,8 +40,12 @@ class RNIModalViewController: UIViewController {
self.modalViewRef?.modalID as? String
};

// MARK: - Properties - Views
// --------------------------
var modalContentWrapper: RNIWrapperView? {
self.modalViewRef?.modalContentWrapper;
};

// MARK: - Properties
// ------------------

var blurEffectView: UIVisualEffectView? = nil;

Expand All @@ -66,77 +70,53 @@ class RNIModalViewController: UIViewController {
}
};

var reactView: UIView? {
didSet {

let didChange =
oldValue?.reactTag != self.reactView?.reactTag;

let shouldRemoveOldView =
oldValue != nil && didChange;

if shouldRemoveOldView,
let oldView = oldValue {

oldView.removeFromSuperview();
};

if didChange,
let newView = self.reactView {

self.view.addSubview(newView);
};
}
};

// MARK: - View Controller Lifecycle
// ---------------------------------

override func viewDidLoad() {
super.viewDidLoad();

#if DEBUG
print(
"Log - RNIModalViewController.viewDidLoad"
+ " - modalNativeID: '\(self.modalViewRef?.modalNativeID ?? "N/A")'"
);
#endif

// setup vc's view
self.view = {
let view = UIView();
view.autoresizingMask = [.flexibleHeight, .flexibleWidth];

return view;
}();

if let modalContentWrapper = self.modalContentWrapper {
self.view.addSubview(modalContentWrapper);
modalContentWrapper.notifyForBoundsChange(size: self.view.bounds.size);
};

self.updateBackgroundTransparency();
self.updateBackgroundBlur();

self.boundsDidChangeBlock?(self.view.bounds)
};

override func viewDidLayoutSubviews(){
super.viewDidLayoutSubviews();

let didChangeViewFrame: Bool = {
guard let lastViewFrame = self.prevViewFrame else { return true };
return !lastViewFrame.equalTo(self.view.frame);
let didChangeBounds: Bool = {
guard let prevBounds = self.prevBounds else { return true };
return !prevBounds.equalTo(self.view.bounds);
}();

if didChangeViewFrame,
let boundsDidChangeBlock = self.boundsDidChangeBlock {

boundsDidChangeBlock(self.view.bounds);
self.prevViewFrame = self.view.frame;

#if DEBUG
print(
"Log - RNIModalViewController.viewDidLayoutSubviews"
+ " - modalNativeID: '\(self.modalViewRef?.modalNativeID ?? "N/A")'"
+ " - invoke boundsDidChangeBlock"
);
#endif
};
guard didChangeBounds,
let modalContentWrapper = self.modalContentWrapper
else { return };

let nextBounds = self.view.bounds;

#if DEBUG
print(
"Log - RNIModalViewController.viewDidLayoutSubviews"
+ " - modalNativeID: '\(self.modalViewRef?.modalNativeID ?? "N/A")'"
+ " - self.prevBounds: \(String(describing: self.prevBounds))"
+ " - nextBounds: \(nextBounds)"
);
#endif

modalContentWrapper.notifyForBoundsChange(size: nextBounds.size);
self.prevBounds = nextBounds;
};

// MARK: - Private Functions
Expand Down
Loading

0 comments on commit a53fb36

Please sign in to comment.