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 03d853c commit 1ad6487
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ struct AdaptiveModalInterpolationPoint: Equatable {
modalView.layer.maskedCorners = self.modalMaskedCorners;
};

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class AdaptiveModalManager {
var prevModalFrame: CGRect = .zero;

var modalViewMaskedCornersAnimator: AdaptiveModalPropertyAnimator?;
var backgroundVisualEffectAnimator: AdaptiveModalPropertyAnimator?;

// MARK: - Properties
// -------------------
Expand Down Expand Up @@ -171,6 +172,10 @@ class AdaptiveModalManager {
self.currentSizeProvider = currentSizeProvider;
};

deinit {
self.clearAnimators();
};


// MARK: - Functions - Interpolation-Related
// -----------------------------------------
Expand Down Expand Up @@ -322,12 +327,7 @@ class AdaptiveModalManager {
else { return };

let animator: AdaptiveModalPropertyAnimator = {
if var animator = self.modalViewMaskedCornersAnimator {
animator.update(
interpolationRangeStart: inputRange.rangeStart,
interpolationRangeEnd: inputRange.rangeEnd
);

if let animator = self.backgroundVisualEffectAnimator {
return animator;
};

Expand All @@ -341,9 +341,39 @@ class AdaptiveModalManager {
};
}();

self.modalViewMaskedCornersAnimator = animator;
animator.setFractionComplete(forInputValue: inputValue);
};

func applyInterpolationToBackgroundVisualEffect(
forInputValue inputValue: CGFloat
) {
guard let backgroundVisualEffectView = self.backgroundVisualEffectView,
let inputRange = self.getInterpolationStepRange(
forInputValue: inputValue
)
else { return };

let animator: AdaptiveModalPropertyAnimator = {
if let animator = self.backgroundVisualEffectAnimator {
return animator;
};

return AdaptiveModalPropertyAnimator(
interpolationRangeStart: inputRange.rangeStart,
interpolationRangeEnd: inputRange.rangeEnd,
forComponent: backgroundVisualEffectView,
withInputAxisKey: self.inputAxisKey
) {
$0.effect = $1.backgroundVisualEffect;
};
}();

self.backgroundVisualEffectAnimator = animator;
animator.setFractionComplete(forInputValue: inputValue);
};


func applyInterpolationToModal(forPoint point: CGPoint){
guard let modalView = self.modalView else { return };
let inputValue = point[keyPath: self.inputAxisKey];
Expand All @@ -366,6 +396,7 @@ class AdaptiveModalManager {
};

self.applyInterpolationToModalMaskedCorners(forInputValue: inputValue);
self.applyInterpolationToBackgroundVisualEffect(forInputValue: inputValue);
};

func applyInterpolationToModal(forGesturePoint gesturePoint: CGPoint){
Expand Down Expand Up @@ -405,6 +436,7 @@ class AdaptiveModalManager {
};

func clearAnimators(){
self.modalViewMaskedCornersAnimator?.clear();
self.modalViewMaskedCornersAnimator = nil;
};

Expand Down Expand Up @@ -450,10 +482,6 @@ 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 @@ -576,7 +604,9 @@ class AdaptiveModalManager {
let inputValueNext = nextModalFrame.origin[keyPath: self.inputAxisKey];
let inputValuePrev = prevModalFrame.origin[keyPath: self.inputAxisKey];

guard inputValueNext != inputValuePrev else { return };
guard inputValueNext != inputValuePrev else { return };

self.applyInterpolationToBackgroundVisualEffect(forInputValue: inputValueNext);

self.prevModalFrame = nextModalFrame;
};
Expand Down Expand Up @@ -611,7 +641,7 @@ class AdaptiveModalManager {
self.applyInterpolationToModal(forGesturePoint: gesturePoint);

case .cancelled, .ended:
self.clearAnimators();
// self.clearAnimators();

guard self.enableSnapping else {
self.clearGestureValues();
Expand Down Expand Up @@ -654,9 +684,13 @@ class AdaptiveModalManager {

currentInterpolationStep.apply(toModalView: modalView);

} else {
self.applyInterpolationToModal(
forPoint: modalView.frame.origin
} else if let currentInterpolationStep = self.currentInterpolationStep {
currentInterpolationStep.apply(toModalView: modalView);

return;

currentInterpolationStep.apply(
toBackgroundEffectView: self.backgroundVisualEffectView
);
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@
import UIKit

struct AdaptiveModalPropertyAnimator {

var inputAxisKey: KeyPath<CGPoint, CGFloat>;

var interpolationRangeStart: AdaptiveModalInterpolationPoint;
var interpolationRangeEnd: AdaptiveModalInterpolationPoint;

var animator: UIViewPropertyAnimator;

private weak var component: AnyObject?;

private var inputRangeStart: CGFloat {
self.interpolationRangeStart
.computedRect.origin[keyPath: self.inputAxisKey];
Expand All @@ -25,7 +28,7 @@ struct AdaptiveModalPropertyAnimator {
.computedRect.origin[keyPath: self.inputAxisKey];
};

init<T>(
init<T: AnyObject>(
interpolationRangeStart: AdaptiveModalInterpolationPoint,
interpolationRangeEnd: AdaptiveModalInterpolationPoint,
forComponent component: T,
Expand All @@ -39,6 +42,7 @@ struct AdaptiveModalPropertyAnimator {
self.interpolationRangeEnd = interpolationRangeEnd;

self.inputAxisKey = inputAxisKey;
self.component = component;

let animator = UIViewPropertyAnimator(
duration: 0,
Expand All @@ -49,25 +53,22 @@ struct AdaptiveModalPropertyAnimator {
animation(component, interpolationRangeEnd);
};

animator.stopAnimation(true);

self.animator = animator;
};

mutating func update(
mutating func didRangeChange(
interpolationRangeStart: AdaptiveModalInterpolationPoint,
interpolationRangeEnd: AdaptiveModalInterpolationPoint
){
) -> Bool {
let didChange =
interpolationRangeStart != self.interpolationRangeStart ||
interpolationRangeEnd != self.interpolationRangeEnd;

guard didChange else { return };

self.interpolationRangeStart = interpolationRangeStart;
self.interpolationRangeEnd = interpolationRangeEnd;
return didChange;
};

func setFractionComplete(forPercent percent: CGFloat){
func setFractionComplete(forPercent percent: CGFloat) {
self.animator.fractionComplete = percent;
};

Expand All @@ -76,6 +77,15 @@ struct AdaptiveModalPropertyAnimator {
let inputValueAdj = inputValue - self.inputRangeStart;

let percent = inputValueAdj / inputRangeEndAdj;

print(
"component: \(self.component)"
+ "\n - percent: \(percent)"
);
self.setFractionComplete(forPercent: percent);
};

func clear(){
self.animator.stopAnimation(true);
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,57 @@
import UIKit


class BlurEffectView: UIVisualEffectView {

var animator = UIViewPropertyAnimator(duration: 1, curve: .linear);

func setBlur(intensity: CGFloat){
self.animator.fractionComplete = intensity;
};

override func didMoveToSuperview() {
guard let superview = superview else { return }
backgroundColor = .clear
frame = superview.bounds //Or setup constraints instead
setupBlur()
}

private func setupBlur() {
animator.stopAnimation(true)
effect = nil

animator.addAnimations { [weak self] in
self?.effect = UIBlurEffect(style: .dark)
}
animator.fractionComplete = 0.1; //This is your blur intensity in range 0 - 1
}

deinit {
animator.stopAnimation(true)
}
}


class BlurEffectIntensityManager {

var animator: UIViewPropertyAnimator?;
var onDisplayLinkUpdateBlock: (() -> Void)? = nil;


func setBlur(
forBlurEffectView blurEffectView: UIVisualEffectView,
intensity: CGFloat = 1,
blurEffectStyle: UIBlurEffect.Style = .systemMaterial,
duration: CGFloat = 0,
curve: UIView.AnimationCurve = .easeIn
) {
guard self.animator == nil else { return };

let animator = UIViewPropertyAnimator(duration: duration, curve: curve);
self.animator = animator;

blurEffectView.effect = nil;


animator.addAnimations {
blurEffectView.effect = UIBlurEffect(style: blurEffectStyle);
blurEffectView.alpha = intensity;
// blurEffectView.alpha = intensity;
};

if duration == 0 {
Expand All @@ -43,6 +68,7 @@ class BlurEffectIntensityManager {

} else {
animator.startAnimation();
return;

let displayLink = CADisplayLink(
target: self,
Expand All @@ -62,14 +88,15 @@ class BlurEffectIntensityManager {
};

@objc func onDisplayLinkUpdate() {
return;
self.onDisplayLinkUpdateBlock?();
};
};


class BlurEffectTestViewController: UIViewController {

lazy var blurEffectView = UIVisualEffectView();
lazy var blurEffectView = BlurEffectView();

let blurManager = BlurEffectIntensityManager();
var isBlurred = false;
Expand Down Expand Up @@ -102,6 +129,7 @@ class BlurEffectTestViewController: UIViewController {
self.view = view;

let blurEffectView = self.blurEffectView;
blurEffectView.effect = UIBlurEffect(style: .prominent);

blurEffectView.addGestureRecognizer(
UITapGestureRecognizer(
Expand Down Expand Up @@ -139,28 +167,20 @@ class BlurEffectTestViewController: UIViewController {
};

override func viewDidLoad() {
return;
self.blurManager.setBlur(
forBlurEffectView: self.blurEffectView,
intensity: 1
);
};

@objc func onPressBlurView(_ sender: UITapGestureRecognizer){

if isBlurred {
self.blurManager.setBlur(
forBlurEffectView: self.blurEffectView,
intensity: 0,
duration: 1,
curve: .easeIn
);
self.blurEffectView.setBlur(intensity: 0);

} else {
self.blurManager.setBlur(
forBlurEffectView: self.blurEffectView,
intensity: 0.5,
duration: 1,
curve: .easeIn
);
self.blurEffectView.setBlur(intensity: 1);
};

self.isBlurred.toggle();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ class RNIDraggableTestViewController : UIViewController {
let backgroundVisualEffectView = self.backgroundVisualEffectView;
self.view.addSubview(backgroundVisualEffectView);

backgroundVisualEffectView.effect = nil;
// backgroundVisualEffectView.effect = nil;

let floatingView = self.floatingView;
self.view.addSubview(floatingView);
Expand All @@ -233,9 +233,6 @@ class RNIDraggableTestViewController : UIViewController {
backgroundVisualEffectView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
backgroundVisualEffectView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
]);

self.modalManager.computeSnapPoints();
self.modalManager.updateModal();
};

override func viewDidLayoutSubviews() {
Expand Down

0 comments on commit 1ad6487

Please sign in to comment.