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 3, 2023
1 parent 8d006c3 commit 2dec67d
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ struct AdaptiveModalAnimationConfig {
let modalCornerRadius: CGFloat?;
let modalMaskedCorners: CACornerMask?;

let modalVisualEffect: UIVisualEffect?;
let modalVisualEffectIntensity: CGFloat?;
let modalBackgroundVisualEffect: UIVisualEffect?;
let modalBackgroundVisualEffectIntensity: CGFloat?;

let backgroundColor: UIColor?;
let backgroundOpacity: CGFloat?;
Expand All @@ -42,8 +42,8 @@ struct AdaptiveModalAnimationConfig {
modalBackgroundOpacity: CGFloat? = nil,
modalCornerRadius: CGFloat? = nil,
modalMaskedCorners: CACornerMask? = nil,
modalVisualEffect: UIVisualEffect? = nil,
modalVisualEffectIntensity: CGFloat? = nil,
modalBackgroundVisualEffect: UIVisualEffect? = nil,
modalBackgroundVisualEffectIntensity: CGFloat? = nil,
backgroundColor: UIColor? = nil,
backgroundOpacity: CGFloat? = nil,
backgroundVisualEffect: UIVisualEffect? = nil,
Expand All @@ -63,8 +63,8 @@ struct AdaptiveModalAnimationConfig {
self.modalCornerRadius = modalCornerRadius;
self.modalMaskedCorners = modalMaskedCorners;

self.modalVisualEffect = modalVisualEffect;
self.modalVisualEffectIntensity = modalVisualEffectIntensity;
self.modalBackgroundVisualEffect = modalBackgroundVisualEffect;
self.modalBackgroundVisualEffectIntensity = modalBackgroundVisualEffectIntensity;

self.backgroundColor = backgroundColor;
self.backgroundOpacity = backgroundOpacity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ struct AdaptiveModalInterpolationPoint: Equatable {
let modalCornerRadius: CGFloat;
let modalMaskedCorners: CACornerMask;

//let modalVisualEffect: UIVisualEffect?;
//let modalVisualEffectIntensity: CGFloat;
let modalBackgroundVisualEffect: UIVisualEffect?;
let modalBackgroundVisualEffectIntensity: CGFloat;

//let backgroundColor: UIColor?;
//let backgroundOpacity: CGFloat?;
Expand Down Expand Up @@ -93,6 +93,13 @@ struct AdaptiveModalInterpolationPoint: Equatable {
?? keyframePrev?.modalMaskedCorners
?? Self.DefaultMaskedCorners;

self.modalBackgroundVisualEffect = keyframeCurrent?.modalBackgroundVisualEffect
?? keyframePrev?.modalBackgroundVisualEffect;

self.modalBackgroundVisualEffectIntensity = keyframeCurrent?.modalBackgroundVisualEffectIntensity
?? keyframePrev?.modalBackgroundVisualEffectIntensity
?? 1;

self.backgroundVisualEffect = keyframeCurrent?.backgroundVisualEffect
?? keyframePrev?.backgroundVisualEffect;

Expand All @@ -103,12 +110,14 @@ struct AdaptiveModalInterpolationPoint: Equatable {

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

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

func apply(toModalBackgroundView modalBackgroundView: UIView?){
modalBackgroundView?.alpha = self.modalBackgroundOpacity;
};

func apply(toBackgroundEffectView effectView: UIVisualEffectView?){
effectView?.effect = self.backgroundVisualEffect;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class AdaptiveModalManager {

weak var targetView: UIView?;
weak var modalView: UIView?;

weak var modalBackgroundView: UIView?;
weak var modalBackgroundVisualEffectView: UIVisualEffectView?;
weak var backgroundVisualEffectView: UIVisualEffectView?;

var displayLinkStartTimestamp: CFTimeInterval?;
Expand All @@ -37,6 +40,7 @@ class AdaptiveModalManager {
var prevModalFrame: CGRect = .zero;

var backgroundVisualEffectAnimator: AdaptiveModalPropertyAnimator?;
var modalBackgroundVisualEffectAnimator: AdaptiveModalPropertyAnimator?;

// MARK: - Properties
// -------------------
Expand Down Expand Up @@ -173,16 +177,24 @@ class AdaptiveModalManager {
modalConfig: AdaptiveModalConfig,
modalView: UIView,
targetView: UIView,
modalBackgroundView: UIView? = nil,
modalBackgroundVisualEffectView: UIVisualEffectView? = nil,
backgroundVisualEffectView: UIVisualEffectView? = nil,
currentSizeProvider: @escaping () -> CGSize
) {
self.modalConfig = modalConfig;

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

self.modalBackgroundView = modalBackgroundView;
self.backgroundVisualEffectView = backgroundVisualEffectView;
self.modalBackgroundVisualEffectView = modalBackgroundVisualEffectView;

self.currentSizeProvider = currentSizeProvider;

modalBackgroundView?.backgroundColor = .systemBackground;
modalView.backgroundColor = .clear;
};

deinit {
Expand Down Expand Up @@ -356,35 +368,35 @@ class AdaptiveModalManager {
func applyInterpolationToBackgroundVisualEffect(
forInputPercentValue inputPercentValue: CGFloat
) {
guard let inputRange = self.getInterpolationStepRange(
forInputPercentValue: inputPercentValue
) else { return };

let animator: AdaptiveModalPropertyAnimator? = {

if let animator = self.backgroundVisualEffectAnimator,
!animator.didRangeChange(
interpolationRangeStart: inputRange.rangeStart,
interpolationRangeEnd: inputRange.rangeEnd
) {
let interpolationRange = self.getInterpolationStepRange(
forInputPercentValue: inputPercentValue
);

guard let interpolationRange = interpolationRange else { return nil };
let animator = self.backgroundVisualEffectAnimator;

let animatorDidRangeChange = animator?.didRangeChange(
interpolationRangeStart: interpolationRange.rangeStart,
interpolationRangeEnd: interpolationRange.rangeEnd
);

if let animator = animator, !animatorDidRangeChange! {
return animator;
};

self.backgroundVisualEffectAnimator?.clear();
animator?.clear();

guard let backgroundVisualEffectView = self.backgroundVisualEffectView,
let inputRange = self.getInterpolationStepRange(
forInputPercentValue: inputPercentValue
)
guard let visualEffectView = self.backgroundVisualEffectView
else { return nil };

backgroundVisualEffectView.effect = nil;
visualEffectView.effect = nil;

return AdaptiveModalPropertyAnimator(
interpolationRangeStart: inputRange.rangeStart,
interpolationRangeEnd: inputRange.rangeEnd,
forComponent: backgroundVisualEffectView,
interpolationRangeStart: interpolationRange.rangeStart,
interpolationRangeEnd: interpolationRange.rangeEnd,
forComponent: visualEffectView,
interpolationOutputKey: \.backgroundVisualEffectIntensity
) {
$0.effect = $1.backgroundVisualEffect;
Expand All @@ -397,6 +409,50 @@ class AdaptiveModalManager {
animator.setFractionComplete(forInputPercentValue: inputPercentValue);
};

func applyInterpolationToModalBackgroundVisualEffect(
forInputPercentValue inputPercentValue: CGFloat
) {

let animator: AdaptiveModalPropertyAnimator? = {
let interpolationRange = self.getInterpolationStepRange(
forInputPercentValue: inputPercentValue
);

guard let interpolationRange = interpolationRange else { return nil };
let animator = self.modalBackgroundVisualEffectAnimator;

let animatorRangeDidChange = animator?.didRangeChange(
interpolationRangeStart: interpolationRange.rangeStart,
interpolationRangeEnd: interpolationRange.rangeEnd
);

if let animator = animator, !animatorRangeDidChange! {
return animator;
};

animator?.clear();

guard let visualEffectView = self.modalBackgroundVisualEffectView
else { return nil };

visualEffectView.effect = nil;

return AdaptiveModalPropertyAnimator(
interpolationRangeStart: interpolationRange.rangeStart,
interpolationRangeEnd: interpolationRange.rangeEnd,
forComponent: visualEffectView,
interpolationOutputKey: \.modalBackgroundVisualEffectIntensity
) {
$0.effect = $1.modalBackgroundVisualEffect;
};
}();

guard let animator = animator else { return };
self.modalBackgroundVisualEffectAnimator = animator;

animator.setFractionComplete(forInputPercentValue: inputPercentValue);
};

func applyInterpolationToModal(
forInputPercentValue inputPercentValue: CGFloat
) {
Expand All @@ -416,14 +472,20 @@ class AdaptiveModalManager {
};

if let nextModalBackgroundOpacity = self.interpolateModalBackgroundOpacity(
forInputPercentValue: inputPercentValue
) {
modalView.alpha = nextModalBackgroundOpacity;
forInputPercentValue: inputPercentValue
),
let modalBackgroundView = self.modalBackgroundView {

modalBackgroundView.alpha = nextModalBackgroundOpacity;
};

self.applyInterpolationToBackgroundVisualEffect(
forInputPercentValue: inputPercentValue
);

self.applyInterpolationToModalBackgroundVisualEffect(
forInputPercentValue: inputPercentValue
);
};

func applyInterpolationToModal(forPoint point: CGPoint){
Expand Down Expand Up @@ -487,6 +549,9 @@ class AdaptiveModalManager {
func clearAnimators(){
self.backgroundVisualEffectAnimator?.clear();
self.backgroundVisualEffectAnimator = nil;

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

func animateModal(
Expand Down Expand Up @@ -531,7 +596,7 @@ class AdaptiveModalManager {

animator.addAnimations {
interpolationPoint.apply(toModalView: modalView);
modalView.layer.maskedCorners = interpolationPoint.modalMaskedCorners;
interpolationPoint.apply(toModalBackgroundView: self.modalBackgroundView);
};

if let completion = completion {
Expand Down Expand Up @@ -672,6 +737,10 @@ class AdaptiveModalManager {
forInputPercentValue: percentAdj
);

self.applyInterpolationToModalBackgroundVisualEffect(
forInputPercentValue: percentAdj
);

self.prevModalFrame = nextModalFrame;
};

Expand Down
Loading

0 comments on commit 2dec67d

Please sign in to comment.