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 May 31, 2023
1 parent 2dd20d0 commit 03d853c
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ struct AdaptiveModalAnimationConfig {
let modalCornerRadius: CGFloat?;
let modalMaskedCorners: CACornerMask?;

let modalBlurEffectStyle: UIBlurEffect.Style?;
let modalBlurEffectIntensity: CGFloat?;
let modalVisualEffect: UIVisualEffect?;
let modalVisualEffectIntensity: CGFloat?;

let backgroundColor: UIColor?;
let backgroundOpacity: CGFloat?;

let backgroundBlurEffectStyle: UIBlurEffect.Style?;
let backgroundBlurEffectIntensity: CGFloat?;
let backgroundVisualEffect: UIVisualEffect?;
let backgroundVisualEffectIntensity: CGFloat?;

init(
modalRotation: CGFloat? = nil,
Expand All @@ -42,12 +42,12 @@ struct AdaptiveModalAnimationConfig {
modalBackgroundOpacity: CGFloat? = nil,
modalCornerRadius: CGFloat? = nil,
modalMaskedCorners: CACornerMask? = nil,
modalBlurEffectStyle: UIBlurEffect.Style? = nil,
modalBlurEffectIntensity: CGFloat? = nil,
modalVisualEffect: UIVisualEffect? = nil,
modalVisualEffectIntensity: CGFloat? = nil,
backgroundColor: UIColor? = nil,
backgroundOpacity: CGFloat? = nil,
backgroundBlurEffectStyle: UIBlurEffect.Style? = nil,
backgroundBlurEffectIntensity: CGFloat? = nil
backgroundVisualEffect: UIVisualEffect? = nil,
backgroundVisualEffectIntensity: CGFloat? = nil
) {
self.modalRotation = modalRotation;

Expand All @@ -63,13 +63,13 @@ struct AdaptiveModalAnimationConfig {
self.modalCornerRadius = modalCornerRadius;
self.modalMaskedCorners = modalMaskedCorners;

self.modalBlurEffectStyle = modalBlurEffectStyle;
self.modalBlurEffectIntensity = modalBlurEffectIntensity;
self.modalVisualEffect = modalVisualEffect;
self.modalVisualEffectIntensity = modalVisualEffectIntensity;

self.backgroundColor = backgroundColor;
self.backgroundOpacity = backgroundOpacity;

self.backgroundBlurEffectStyle = backgroundBlurEffectStyle;
self.backgroundBlurEffectIntensity = backgroundBlurEffectIntensity;
self.backgroundVisualEffect = backgroundVisualEffect;
self.backgroundVisualEffectIntensity = backgroundVisualEffectIntensity;
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ struct AdaptiveModalInterpolationPoint: Equatable {

let modalCornerRadius: CGFloat;
let modalMaskedCorners: CACornerMask;

let backgroundVisualEffect: UIVisualEffect?;

init(
modalConfigIndex: Int,
Expand All @@ -41,13 +43,20 @@ struct AdaptiveModalInterpolationPoint: Equatable {
self.modalMaskedCorners = keyframePrev?.modalMaskedCorners
?? keyframePrev?.modalMaskedCorners
?? Self.DefaultMaskedCorners;

self.backgroundVisualEffect = keyframePrev?.backgroundVisualEffect
?? keyframePrev?.backgroundVisualEffect;
};

func apply(toModalView modalView: UIView){
modalView.frame = self.computedRect;
modalView.layer.cornerRadius = self.modalCornerRadius;
modalView.layer.maskedCorners = self.modalMaskedCorners;
};

func apply(toBackgroundEffectView effectView: UIVisualEffectView){
effectView.effect = self.backgroundVisualEffect;
};
};

extension AdaptiveModalInterpolationPoint {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import UIKit




class AdaptiveModalManager {

// MARK: - Properties - Config-Related
Expand All @@ -27,6 +25,7 @@ class AdaptiveModalManager {

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

var gestureOffset: CGPoint?;
var gestureVelocity: CGPoint?;
Expand Down Expand Up @@ -160,19 +159,70 @@ class AdaptiveModalManager {
modalConfig: AdaptiveModalConfig,
modalView: UIView,
targetView: UIView,
backgroundVisualEffectView: UIVisualEffectView? = nil,
currentSizeProvider: @escaping () -> CGSize
) {
self.modalConfig = modalConfig;

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

self.currentSizeProvider = currentSizeProvider;
};


// MARK: - Functions - Interpolation-Related
// -----------------------------------------

func getInterpolationStepRange(
forInputValue inputValue: CGFloat
) -> (
rangeStart: AdaptiveModalInterpolationPoint,
rangeEnd: AdaptiveModalInterpolationPoint
)? {
guard let interpolationSteps = self.interpolationSteps,
let minStep = interpolationSteps.first,
let maxStep = interpolationSteps.last
else { return nil };

let lastIndex = interpolationSteps.count - 1;

if inputValue <= minStep.computedRect.origin[keyPath: self.inputAxisKey]{
return (
rangeStart: minStep,
rangeEnd: interpolationSteps[1]
);
};

if inputValue >= maxStep.computedRect.origin[keyPath: self.inputAxisKey]{
return (
rangeStart: interpolationSteps[lastIndex - 1],
rangeEnd: maxStep
);
};

let firstMatch = interpolationSteps.enumerated().first {
guard let nextItem = interpolationSteps[safeIndex: $0.offset + 1]
else { return false };

let coordCurrent =
$0.element.computedRect.origin[keyPath: self.inputAxisKey];

let coordNext =
nextItem.computedRect.origin[keyPath: self.inputAxisKey];

return coordCurrent >= inputValue && inputValue <= coordNext;
};

guard let rangeStart = firstMatch?.element,
let rangeStartIndex = firstMatch?.offset,
let rangeEnd = interpolationSteps[safeIndex: rangeStartIndex + 1]
else { return nil };

return (rangeStart, rangeEnd);
};

func interpolateModalRect(
forInputValue inputValue: CGFloat,
rangeInput: [CGFloat]? = nil,
Expand Down Expand Up @@ -400,6 +450,10 @@ class AdaptiveModalManager {

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

if let bgEffectView = self.backgroundVisualEffectView {
interpolationPoint.apply(toBackgroundEffectView: bgEffectView);
};
};

if let completion = completion {
Expand Down Expand Up @@ -486,54 +540,6 @@ class AdaptiveModalManager {
);
};

func getInterpolationStepRange(
forInputValue inputValue: CGFloat
) -> (
rangeStart: AdaptiveModalInterpolationPoint,
rangeEnd: AdaptiveModalInterpolationPoint
)? {
guard let interpolationSteps = self.interpolationSteps,
let minStep = interpolationSteps.first,
let maxStep = interpolationSteps.last
else { return nil };

let lastIndex = interpolationSteps.count - 1;

if inputValue <= minStep.computedRect.origin[keyPath: self.inputAxisKey]{
return (
rangeStart: minStep,
rangeEnd: interpolationSteps[1]
);
};

if inputValue >= maxStep.computedRect.origin[keyPath: self.inputAxisKey]{
return (
rangeStart: interpolationSteps[lastIndex - 1],
rangeEnd: maxStep
);
};

let firstMatch = interpolationSteps.enumerated().first {
guard let nextItem = interpolationSteps[safeIndex: $0.offset + 1]
else { return false };

let coordCurrent =
$0.element.computedRect.origin[keyPath: self.inputAxisKey];

let coordNext =
nextItem.computedRect.origin[keyPath: self.inputAxisKey];

return coordCurrent >= inputValue && inputValue <= coordNext;
};

guard let rangeStart = firstMatch?.element,
let rangeStartIndex = firstMatch?.offset,
let rangeEnd = interpolationSteps[safeIndex: rangeStartIndex + 1]
else { return nil };

return (rangeStart, rangeEnd);
};

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ enum AdaptiveModalConfigTestPresets: CaseIterable {
.layerMinXMaxYCorner,
.layerMaxXMinYCorner,
.layerMaxXMaxYCorner
]
],
backgroundVisualEffect: UIBlurEffect(style: .prominent)
)
),
],
Expand All @@ -121,6 +122,7 @@ class RNIDraggableTestViewController : UIViewController {
modalConfig: AdaptiveModalConfigTestPresets.default.config,
modalView: self.floatingView,
targetView: self.view,
backgroundVisualEffectView: self.backgroundVisualEffectView,
currentSizeProvider: {
.zero
}
Expand Down Expand Up @@ -175,15 +177,63 @@ class RNIDraggableTestViewController : UIViewController {

return view;
}();

lazy var backgroundVisualEffectView = UIVisualEffectView();

lazy var dummyBackgroundView: UIView = {
let view = UIView();

let imageView = UIImageView(
image: UIImage(named: "DummyBackgroundImage")
);

imageView.contentMode = .scaleAspectFill;

view.addSubview(imageView);

imageView.translatesAutoresizingMaskIntoConstraints = false;

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

return view;
}();

override func viewDidLoad() {
self.view.backgroundColor = .white;

let dummyBackgroundView = self.dummyBackgroundView;
self.view.addSubview(dummyBackgroundView);

let backgroundVisualEffectView = self.backgroundVisualEffectView;
self.view.addSubview(backgroundVisualEffectView);

backgroundVisualEffectView.effect = nil;

let floatingView = self.floatingView;
self.view.addSubview(floatingView);

self.floatingViewLabel.text = "\(self.modalManager.currentSnapPointIndex)";

dummyBackgroundView.translatesAutoresizingMaskIntoConstraints = false;
backgroundVisualEffectView.translatesAutoresizingMaskIntoConstraints = false;

NSLayoutConstraint.activate([
dummyBackgroundView.topAnchor.constraint(equalTo: self.view.topAnchor),
dummyBackgroundView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
dummyBackgroundView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
dummyBackgroundView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),

backgroundVisualEffectView.topAnchor.constraint(equalTo: self.view.topAnchor),
backgroundVisualEffectView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
backgroundVisualEffectView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
backgroundVisualEffectView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
]);

self.modalManager.computeSnapPoints();
self.modalManager.updateModal();
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "DummyBackgroundImage.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 03d853c

Please sign in to comment.