Skip to content

Commit

Permalink
💫 Update: Exp - AdaptiveModal
Browse files Browse the repository at this point in the history
Summary: Update experiment/test - `swift-programmatic-modal/AdaptiveModal`.
  • Loading branch information
dominicstop committed Jun 20, 2023
1 parent 695dd1b commit 367880c
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -372,15 +372,43 @@ class AdaptiveModalManager: NSObject {

super.init();
self.computeSnapPoints();
self.setupObservers();
};

deinit {
self.clearAnimators();
self.removeObservers();
};

// MARK: - Functions - Setup
// -------------------------

private func setupObservers(){
NotificationCenter.default.addObserver(self,
selector: #selector(self.onKeyboardWillShow(notification:)),
name: UIResponder.keyboardWillShowNotification,
object: nil
);

NotificationCenter.default.addObserver(self,
selector: #selector(self.onKeyboardDidShow(notification:)),
name: UIResponder.keyboardDidShowNotification,
object: nil
);

NotificationCenter.default.addObserver(self,
selector: #selector(self.onKeyboardWillHide(notification:)),
name: UIResponder.keyboardWillHideNotification,
object: nil
);

NotificationCenter.default.addObserver(self,
selector: #selector(self.onKeyboardDidHide(notification:)),
name: UIResponder.keyboardDidHideNotification,
object: nil
);
};

func setupViewControllers() {
guard let modalVC = self.modalViewController else { return };

Expand Down Expand Up @@ -545,6 +573,90 @@ class AdaptiveModalManager: NSObject {
]);
};
};

// MARK: - Functions - Cleanup-Related
// -----------------------------------

private func clearGestureValues() {
self.gestureOffset = nil;
self.gestureInitialPoint = nil;
self.gestureVelocity = nil;
self.gesturePoint = nil;
};

private func clearAnimators() {
self.backgroundVisualEffectAnimator?.clear();
self.backgroundVisualEffectAnimator = nil;

self.modalBackgroundVisualEffectAnimator?.clear();
self.modalBackgroundVisualEffectAnimator = nil;

self.modalAnimator?.stopAnimation(true);
self.modalAnimator = nil;
};

private func removeObservers(){
let notificationNames = [
UIResponder.keyboardWillShowNotification,
UIResponder.keyboardDidShowNotification,
UIResponder.keyboardWillHideNotification,
UIResponder.keyboardDidHideNotification
];

notificationNames.forEach {
NotificationCenter.default.removeObserver(self, name: $0, object: nil);
};
};

private func cleanupViews() {
let viewsToCleanup: [UIView?] = [
self.dummyModalView,
self.modalWrapperView,
// self.modalWrapperTransformView,
// self.nodalView,
self.modalWrapperShadowView,
self.modalBackgroundView,
self.modalBackgroundVisualEffectView,
self.backgroundDimmingView,
self.backgroundVisualEffectView
];

viewsToCleanup.forEach {
guard let view = $0 else { return };

view.removeAllAncestorConstraints();
view.removeFromSuperview();
};

self.modalView = nil;
self.targetView = nil;

self.modalBackgroundView = nil;
self.modalBackgroundVisualEffectView = nil;
self.backgroundDimmingView = nil;
self.backgroundVisualEffectView = nil;

self.didTriggerSetup = false;
};

private func cleanupSnapPointOverride(){
self.isOverridingSnapPoints = false;
self.overrideSnapPoints = nil;
self.overrideInterpolationPoints = nil;

self.prevOverrideInterpolationIndex = 0;
self.nextOverrideInterpolationIndex = nil;
self.currentOverrideInterpolationIndex = 0;
};

private func cleanup() {
self.clearGestureValues();
self.clearAnimators();
self.cleanupViews();
self.cleanupSnapPointOverride();

self.currentInterpolationIndex = 0;
};

// MARK: - Functions - Interpolation-Related Helpers
// -------------------------------------------------
Expand Down Expand Up @@ -1104,77 +1216,6 @@ class AdaptiveModalManager: NSObject {
self.applyInterpolationToModal(forPoint: gesturePointWithOffset);
};

// MARK: - Functions - Cleanup-Related
// -----------------------------------

private func clearGestureValues() {
self.gestureOffset = nil;
self.gestureInitialPoint = nil;
self.gestureVelocity = nil;
self.gesturePoint = nil;
};

private func clearAnimators() {
self.backgroundVisualEffectAnimator?.clear();
self.backgroundVisualEffectAnimator = nil;

self.modalBackgroundVisualEffectAnimator?.clear();
self.modalBackgroundVisualEffectAnimator = nil;

self.modalAnimator?.stopAnimation(true);
self.modalAnimator = nil;
};

private func cleanupViews() {
let viewsToCleanup: [UIView?] = [
self.dummyModalView,
self.modalWrapperView,
// self.modalWrapperTransformView,
// self.nodalView,
self.modalWrapperShadowView,
self.modalBackgroundView,
self.modalBackgroundVisualEffectView,
self.backgroundDimmingView,
self.backgroundVisualEffectView
];

viewsToCleanup.forEach {
guard let view = $0 else { return };

view.removeAllAncestorConstraints();
view.removeFromSuperview();
};

self.modalView = nil;
self.targetView = nil;

self.modalBackgroundView = nil;
self.modalBackgroundVisualEffectView = nil;
self.backgroundDimmingView = nil;
self.backgroundVisualEffectView = nil;

self.didTriggerSetup = false;
};

private func cleanupSnapPointOverride(){
self.isOverridingSnapPoints = false;
self.overrideSnapPoints = nil;
self.overrideInterpolationPoints = nil;

self.prevOverrideInterpolationIndex = 0;
self.nextOverrideInterpolationIndex = nil;
self.currentOverrideInterpolationIndex = 0;
};

private func cleanup() {
self.clearGestureValues();
self.clearAnimators();
self.cleanupViews();
self.cleanupSnapPointOverride();

self.currentInterpolationIndex = 0;
};

// MARK: - Functions - Helpers/Utilities
// -------------------------------------

Expand Down Expand Up @@ -1216,6 +1257,18 @@ class AdaptiveModalManager: NSObject {
};
};

private func getKeyboardRect(
fromNotification notification: NSNotification
) -> CGRect? {

guard let userInfo = notification.userInfo,
let keyboardFrameRaw = userInfo[UIResponder.keyboardFrameEndUserInfoKey],
let keyboardFrame = keyboardFrameRaw as? NSValue
else { return nil };

return keyboardFrame.cgRectValue;
};

func debug(prefix: String? = ""){
print(
"\n - AdaptiveModalManager.debug - \(prefix ?? "N/A")"
Expand Down Expand Up @@ -1391,6 +1444,9 @@ class AdaptiveModalManager: NSObject {
self.startDisplayLink();
};

// MARK: - Functions - Handlers
// ----------------------------

@objc private func onDragPanGesture(_ sender: UIPanGestureRecognizer) {
let gesturePoint = sender.location(in: self.targetView);
self.gesturePoint = gesturePoint;
Expand Down Expand Up @@ -1429,6 +1485,47 @@ class AdaptiveModalManager: NSObject {
};
};

@objc func onKeyboardWillShow(notification: NSNotification) {
guard let keyboardRect = self.getKeyboardRect(fromNotification: notification)
else { return };

print(
"onKeyboardWillShow",
"\n - keyboardRect:", keyboardRect
);
};

@objc func onKeyboardDidShow(notification: NSNotification) {
guard let keyboardRect = self.getKeyboardRect(fromNotification: notification)
else { return };

print(
"onKeyboardDidShow",
"\n - keyboardRect:", keyboardRect
);
};


@objc func onKeyboardWillHide(notification: NSNotification) {
guard let keyboardRect = self.getKeyboardRect(fromNotification: notification)
else { return };

print(
"onKeyboardWillHide",
"\n - keyboardRect:", keyboardRect
);
};

@objc func onKeyboardDidHide(notification: NSNotification) {
guard let keyboardRect = self.getKeyboardRect(fromNotification: notification)
else { return };

print(
"onKeyboardDidHide",
"\n - keyboardRect:", keyboardRect
);
};

// MARK: - Functions - DisplayLink-Related
// ---------------------------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ enum AdaptiveModalConfigTestPresets: CaseIterable {
case demo06;
case demo07;
case demo08;
case demo09;

var config: AdaptiveModalConfig {
switch self {
Expand Down Expand Up @@ -993,6 +994,39 @@ enum AdaptiveModalConfigTestPresets: CaseIterable {
layoutPreset: .fitScreen
)
);

case .demo09: return AdaptiveModalConfig(
snapPoints: [
// Snap Point 1
AdaptiveModalSnapPointConfig(
snapPoint: RNILayout(
horizontalAlignment: .center,
verticalAlignment: .bottom,
width: .stretch,
height: .percent(percentValue: 0.3)
),
animationKeyframe: AdaptiveModalAnimationConfig(
modalShadowOffset: .init(width: 0, height: -2),
modalShadowOpacity: 0.2,
modalShadowRadius: 7,
modalCornerRadius: 0,
modalMaskedCorners: [
.layerMinXMinYCorner,
.layerMaxXMinYCorner
],
modalBackgroundOpacity: 0.9,
modalBackgroundVisualEffect: UIBlurEffect(style: .systemUltraThinMaterial),
modalBackgroundVisualEffectIntensity: 1,
backgroundVisualEffect: UIBlurEffect(style: .regular),
backgroundVisualEffectIntensity: 0
)
),
],
snapDirection: .bottomToTop,
overshootSnapPoint: AdaptiveModalSnapPointPreset(
layoutPreset: .fitScreen
)
);
};
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ fileprivate class TestModalViewController: UIViewController, AdaptiveModalEventN

var showDismissButton = true;
var showCustomSnapPointButton = false;
var showTextInputField = false;

lazy var floatingViewLabel: UILabel = {
let label = UILabel();
Expand Down Expand Up @@ -57,6 +58,21 @@ fileprivate class TestModalViewController: UIViewController, AdaptiveModalEventN
return button;
}();

let textInputField: UITextField = {
let textField = UITextField();

textField.placeholder = "Enter text here";
textField.font = UIFont.systemFont(ofSize: 15);
textField.borderStyle = UITextField.BorderStyle.roundedRect;
textField.autocorrectionType = UITextAutocorrectionType.no;
textField.keyboardType = UIKeyboardType.default;
textField.returnKeyType = UIReturnKeyType.done;
textField.clearButtonMode = UITextField.ViewMode.whileEditing;
textField.contentVerticalAlignment = UIControl.ContentVerticalAlignment.center;

return textField;
}();

let stackView: UIStackView = {
let stack = UIStackView();

Expand All @@ -67,6 +83,10 @@ fileprivate class TestModalViewController: UIViewController, AdaptiveModalEventN

stack.addArrangedSubview(self.floatingViewLabel);

if self.showTextInputField {
stack.addArrangedSubview(textInputField);
};

if self.showDismissButton {
stack.addArrangedSubview(dismissButton);
};
Expand Down Expand Up @@ -163,6 +183,7 @@ class AdaptiveModalPresentationTestViewController : UIViewController {
.demo06,
.demo07,
.demo08,
.demo09,
];

var currentModalConfigPresetCounter = 0;
Expand Down Expand Up @@ -296,8 +317,11 @@ class AdaptiveModalPresentationTestViewController : UIViewController {
let testVC = TestModalViewController();

switch self.currentModalConfigPreset {
case .demo08, .demo07:
case .demo07, .demo08:
testVC.showCustomSnapPointButton = true;

case .demo09:
testVC.showTextInputField = true;

default: break;
};
Expand Down

0 comments on commit 367880c

Please sign in to comment.