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 5, 2023
1 parent ef18f4e commit 6b43793
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,17 @@ struct AdaptiveModalInterpolationPoint: Equatable {
};

func apply(toModalView modalView: UIView){
modalView.frame = self.computedRect;

modalView.layer.cornerRadius = self.modalCornerRadius;
modalView.layer.maskedCorners = self.modalMaskedCorners;

modalView.setNeedsLayout();
};

func apply(toModalWrapperView modalWrapperView: UIView){
modalWrapperView.frame = self.computedRect;
//modalWrapperView.transform = self.modalTransform;

modalWrapperView.setNeedsLayout();
};

func apply(toDummyModalView dummyModalView: UIView){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class AdaptiveModalManager {
weak var eventDelegate: AdaptiveModalEventNotifiable?;

lazy var dummyModalView = UIView();
lazy var modalWrapperView = UIView();

weak var targetView: UIView?;
weak var modalView: UIView?;
Expand Down Expand Up @@ -70,14 +71,11 @@ class AdaptiveModalManager {

var modalFrame: CGRect! {
set {
guard let modalView = self.modalView,
let newValue = newValue
else { return };

self.prevModalFrame = modalView.frame;
modalView.frame = newValue;
guard let newValue = newValue else { return };
self.prevModalFrame = self.dummyModalView.frame;

self.dummyModalView.frame = newValue;
self.modalWrapperView.frame = newValue;
}
get {
self.dummyModalView.frame;
Expand Down Expand Up @@ -253,22 +251,26 @@ class AdaptiveModalManager {
bgDimmingView.alpha = 0;
};

targetView.addSubview(modalView);
let modalWrapperView = self.modalWrapperView;
modalWrapperView.backgroundColor = .clear;
targetView.addSubview(modalWrapperView);

modalWrapperView.addSubview(modalView);

modalView.clipsToBounds = true;
modalView.backgroundColor = .clear;

if let modalBackgroundView = self.modalBackgroundView {
modalView.addSubview(modalBackgroundView);
modalView.sendSubviewToBack(modalBackgroundView);
modalWrapperView.addSubview(modalBackgroundView);
modalWrapperView.sendSubviewToBack(modalBackgroundView);

modalBackgroundView.backgroundColor = .systemBackground;
modalBackgroundView.isUserInteractionEnabled = false;
};

if let modalBGVisualEffectView = self.modalBackgroundVisualEffectView {
modalView.addSubview(modalBGVisualEffectView);
modalView.sendSubviewToBack(modalBGVisualEffectView);
modalWrapperView.addSubview(modalBGVisualEffectView);
modalWrapperView.sendSubviewToBack(modalBGVisualEffectView);

modalBGVisualEffectView.clipsToBounds = true;
modalBGVisualEffectView.backgroundColor = .clear;
Expand All @@ -281,6 +283,8 @@ class AdaptiveModalManager {
let targetView = self.targetView
else { return };

let modalWrapperView = self.modalWrapperView;

if let bgVisualEffectView = self.backgroundVisualEffectView {
bgVisualEffectView.translatesAutoresizingMaskIntoConstraints = false;

Expand All @@ -303,25 +307,34 @@ class AdaptiveModalManager {
]);
};

modalView.translatesAutoresizingMaskIntoConstraints = false;

NSLayoutConstraint.activate([
modalView.topAnchor .constraint(equalTo: modalWrapperView.topAnchor ),
modalView.bottomAnchor .constraint(equalTo: modalWrapperView.bottomAnchor ),
modalView.leadingAnchor .constraint(equalTo: modalWrapperView.leadingAnchor ),
modalView.trailingAnchor.constraint(equalTo: modalWrapperView.trailingAnchor),
]);

if let modalBGView = self.modalBackgroundView {
modalBGView.translatesAutoresizingMaskIntoConstraints = false;

NSLayoutConstraint.activate([
modalBGView.topAnchor .constraint(equalTo: modalView.topAnchor ),
modalBGView.bottomAnchor .constraint(equalTo: modalView.bottomAnchor ),
modalBGView.leadingAnchor .constraint(equalTo: modalView.leadingAnchor ),
modalBGView.trailingAnchor.constraint(equalTo: modalView.trailingAnchor),
modalBGView.topAnchor .constraint(equalTo: modalWrapperView.topAnchor ),
modalBGView.bottomAnchor .constraint(equalTo: modalWrapperView.bottomAnchor ),
modalBGView.leadingAnchor .constraint(equalTo: modalWrapperView.leadingAnchor ),
modalBGView.trailingAnchor.constraint(equalTo: modalWrapperView.trailingAnchor),
]);
};

if let modalBGVisualEffectView = self.modalBackgroundVisualEffectView {
modalBGVisualEffectView.translatesAutoresizingMaskIntoConstraints = false;

NSLayoutConstraint.activate([
modalBGVisualEffectView.topAnchor .constraint(equalTo: modalView.topAnchor ),
modalBGVisualEffectView.bottomAnchor .constraint(equalTo: modalView.bottomAnchor ),
modalBGVisualEffectView.leadingAnchor .constraint(equalTo: modalView.leadingAnchor ),
modalBGVisualEffectView.trailingAnchor.constraint(equalTo: modalView.trailingAnchor),
modalBGVisualEffectView.topAnchor .constraint(equalTo: modalWrapperView.topAnchor ),
modalBGVisualEffectView.bottomAnchor .constraint(equalTo: modalWrapperView.bottomAnchor ),
modalBGVisualEffectView.leadingAnchor .constraint(equalTo: modalWrapperView.leadingAnchor ),
modalBGVisualEffectView.trailingAnchor.constraint(equalTo: modalWrapperView.trailingAnchor),
]);
};
};
Expand Down Expand Up @@ -447,6 +460,73 @@ class AdaptiveModalManager {
);
};

func interpolateModalTransform(
forInputPercentValue inputPercentValue: CGFloat,
rangeInput: [CGFloat]? = nil,
rangeOutput: [AdaptiveModalInterpolationPoint]? = nil
) -> CGAffineTransform? {

guard let interpolationSteps = rangeOutput ?? self.interpolationStepsSorted,
let interpolationRangeInput = rangeInput ?? self.interpolationRangeInput
else { return nil };

let clampConfig = modalConfig.interpolationClampingConfig;

let nextModalRotation = Self.interpolate(
inputValue: inputPercentValue,
rangeInput: interpolationRangeInput,
rangeOutput: interpolationSteps.map {
$0.modalRotation
},
shouldClampMin: clampConfig.shouldClampModalInitRotation,
shouldClampMax: clampConfig.shouldClampModalLastRotation
);

let nextScaleX = Self.interpolate(
inputValue: inputPercentValue,
rangeInput: interpolationRangeInput,
rangeOutput: interpolationSteps.map {
$0.modalScaleX;
},
shouldClampMin: clampConfig.shouldClampModalLastScaleX,
shouldClampMax: clampConfig.shouldClampModalLastScaleX
);

let nextScaleY = Self.interpolate(
inputValue: inputPercentValue,
rangeInput: interpolationRangeInput,
rangeOutput: interpolationSteps.map {
$0.modalScaleY
},
shouldClampMin: clampConfig.shouldClampModalLastScaleY,
shouldClampMax: clampConfig.shouldClampModalLastScaleY
);

let nextTransform: CGAffineTransform = {
var transforms: [CGAffineTransform] = [];

if let rotation = nextModalRotation {
transforms.append(
.init(rotationAngle: rotation)
);
};

if let nextScaleX = nextScaleX,
let nextScaleY = nextScaleY {

transforms.append(
.init(scaleX: nextScaleX, y: nextScaleY)
);
};

return transforms.reduce(.identity) {
$0.concatenating($1);
};
}();

return nextTransform;
};

func interpolateModalBackgroundOpacity(
forInputPercentValue inputPercentValue: CGFloat,
rangeInput: [CGFloat]? = nil,
Expand Down Expand Up @@ -745,11 +825,14 @@ class AdaptiveModalManager {
self.animator = animator;

animator.addAnimations {
interpolationPoint.apply(toDummyModalView: self.dummyModalView);
interpolationPoint.apply(toModalView: modalView);

interpolationPoint.apply(toDummyModalView: self.dummyModalView);
interpolationPoint.apply(toModalBackgroundView: self.modalBackgroundView);
interpolationPoint.apply(toBackgroundView: self.backgroundDimmingView);

self.modalWrapperView.layoutIfNeeded();
modalView.layoutIfNeeded();
};

if let completion = completion {
Expand Down

0 comments on commit 6b43793

Please sign in to comment.