Light's Blog

The best or nothing.

iOS知识小集-171204

| Comments

UIViewController Transition

自定义Present和Dismiss动画。

设置待Present的UIViewController的transitioningDelegate

modalPresentationStyleFullScreen时,dismiss时会自动移除fromView
modalPresentationStyleCustom时,dismiss时会需手动移除fromView

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@interface ViewController : UIViewController <UIViewControllerTransitioningDelegate>

@end

@implementation ViewController

- (instancetype)init{
  if (self = [super init]) {
    self.modalPresentationStyle = UIModalPresentationOverFullScreen;
    self.transitioningDelegate = self;
  }
  return self;
}

#pragma mark - UIViewControllerTransitioningDelegate
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
                                                                  presentingController:(UIViewController *)presenting
                                                                      sourceController:(UIViewController *)source {
  return [PresentAnimator new];
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
  return [DismissAnimator new];
}

@end

创建PresentAnimator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@interface PresentAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

@implementation PresentAnimator

#pragma mark - UIViewControllerContextTransitioning
- (void)animateTransition:(nonnull id<UIViewControllerContextTransitioning>)transitionContext {
  //  from -> to
  UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
  UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
  //  contrainer
  UIView *containerView = transitionContext.containerView;
  //  from -> to
  UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
  UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
  //  add
  [containerView addSubview:toView];
  //  animation
  toView.alpha = 0;
  toView.frame = CGRectMake(fromView.frame.origin.x, CGRectGetMaxY(fromView.frame) / 2, fromView.frame.size.width, fromView.frame.size.height);
  [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
    toView.alpha = 1;
    toView.frame = [transitionContext finalFrameForViewController:toViewController];
  } completion:^(BOOL finished) {
    [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
  }];
}

- (NSTimeInterval)transitionDuration:(nullable id<UIViewControllerContextTransitioning>)transitionContext {
  return 0.25;
}

@end

创建DismissAnimator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@interface DismissAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

@implementation DismissAnimator

#pragma mark - UIViewControllerContextTransitioning
- (void)animateTransition:(nonnull id<UIViewControllerContextTransitioning>)transitionContext {
  //  from -> to
  UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
  //  animation
  fromView.alpha = 1;
  [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
    fromView.alpha = 0;
  } completion:^(BOOL finished) {
    [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
  }];
}

- (NSTimeInterval)transitionDuration:(nullable id<UIViewControllerContextTransitioning>)transitionContext {
  return 0.25;
}

@end

Comments