Files
mier_ios/Pods/HWPopController/HWPopController/Classes/Animator/HWPopControllerAnimatedTransitioning.m
2025-08-11 10:43:19 +08:00

167 lines
5.7 KiB
Objective-C
Executable File

//
// HWPopControllerAnimationContext.m
// HWPopController
//
// Created by heath wang on 2019/5/21.
//
#import "HWPopControllerAnimatedTransitioning.h"
#import "HWDefaultPopAnimator.h"
@implementation HWPopAnimationContext
- (instancetype)initWithState:(HWPopState)state containerView:(UIView *)containerView {
self = [super init];
if (self) {
_state = state;
_containerView = containerView;
}
return self;
}
@end
@interface HWPopControllerAnimatedTransitioning ()
@property (nonatomic, strong) id<HWPopControllerAnimationProtocol> animator;
@end
@interface HWPopControllerAnimatedTransitioning ()
@property (nonatomic, strong, readonly) UIView *containerView;
@property (nonatomic, strong, readonly) UIView *backgroundView;
@property (nonatomic, strong) HWPopAnimationContext *animationContext;
@end
@implementation HWPopControllerAnimatedTransitioning
- (instancetype)initWithState:(HWPopState)state popController:(HWPopController *)popController {
self = [super init];
if (self) {
_state = state;
_popController = popController;
_containerView = _popController.containerView;
_backgroundView = _popController.backgroundView;
_animationContext = [[HWPopAnimationContext alloc] initWithState:state containerView:_containerView];
_animationContext.duration = _popController.animationDuration;
[self getAnimator];
}
return self;
}
- (void)getAnimator {
if (self.popController.animationProtocol) {
self.animator = self.popController.animationProtocol;
} else {
HWDefaultPopAnimator *defaultPopAnimator = [HWDefaultPopAnimator new];
defaultPopAnimator.popType = self.popController.popType;
defaultPopAnimator.dismissType = self.popController.dismissType;
self.animator = defaultPopAnimator;
}
}
#pragma mark - Animation
- (void)popAnimateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
toViewController.view.frame = fromViewController.view.frame;
UIViewController *topViewController = self.popController.topViewController;
[fromViewController beginAppearanceTransition:NO animated:YES];
[[transitionContext containerView] addSubview:toViewController.view];
[topViewController beginAppearanceTransition:YES animated:YES];
[toViewController addChildViewController:topViewController];
[self.popController.contentView addSubview:topViewController.view];
[self.popController layoutContainerView];
CGFloat lastBackgroundViewAlpha = self.backgroundView.alpha;
self.backgroundView.alpha = 0;
[self setContainerUserInteractionEnabled:NO];
self.containerView.transform = CGAffineTransformIdentity;
[UIView animateWithDuration:[self.animator popControllerAnimationDuration:self.animationContext] delay:0 usingSpringWithDamping:1 initialSpringVelocity:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.backgroundView.alpha = lastBackgroundViewAlpha;
} completion:nil];
[self.animator popAnimate:self.animationContext completion:^(BOOL finished){
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
[self setContainerUserInteractionEnabled:YES];
[topViewController endAppearanceTransition];
[topViewController didMoveToParentViewController:toViewController];
[fromViewController endAppearanceTransition];
[toViewController setNeedsStatusBarAppearanceUpdate];
}];
}
- (void)dismissTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
toViewController.view.frame = fromViewController.view.frame;
UIViewController *topViewController = self.popController.topViewController;
[toViewController beginAppearanceTransition:YES animated:YES];
[topViewController beginAppearanceTransition:NO animated:YES];
[topViewController willMoveToParentViewController:nil];
CGFloat lastBackgroundViewAlpha = self.backgroundView.alpha;
[self setContainerUserInteractionEnabled:NO];
[UIView animateWithDuration:[self.animator popControllerAnimationDuration:self.animationContext] delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.backgroundView.alpha = 0;
} completion:nil];
[self.animator dismissAnimate:self.animationContext completion:^(BOOL finished){
[self setContainerUserInteractionEnabled:YES];
self.backgroundView.alpha = lastBackgroundViewAlpha;
[fromViewController.view removeFromSuperview];
[topViewController.view removeFromSuperview];
[topViewController removeFromParentViewController];
[toViewController endAppearanceTransition];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
- (void)setContainerUserInteractionEnabled:(BOOL)enabled {
self.containerView.userInteractionEnabled = enabled;
self.backgroundView.userInteractionEnabled = enabled;
}
#pragma mark - UIViewControllerAnimatedTransitioning
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {
return [self.animator popControllerAnimationDuration:self.animationContext];
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
switch (self.state) {
case HWPopStatePop: {
[self popAnimateTransition:transitionContext];
}
break;
case HWPopStateDismiss:{
[self dismissTransition:transitionContext];
}
break;
}
}
@end