实现方式
- 使用
UIView
的动画方法:UIView
提供了一系列类方法来创建动画,能够方便地实现视图的淡入淡出、滑动切换等效果。
- 使用
UIViewController
的转场动画:可以通过自定义 UIViewControllerAnimatedTransitioning
协议来实现更复杂的视图控制器之间的过渡动画。
- 使用
CAAnimation
及其子类:Core Animation
框架提供了更底层的动画控制,例如 CABasicAnimation
、CAKeyframeAnimation
等,可以实现各种复杂的动画效果。
代码示例 - 使用 UIView
的动画方法
- 淡入淡出效果
// 淡入
UIView *viewToFadeIn = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
viewToFadeIn.backgroundColor = [UIColor redColor];
[self.view addSubview:viewToFadeIn];
viewToFadeIn.alpha = 0.0;
[UIView animateWithDuration:1.0 animations:^{
viewToFadeIn.alpha = 1.0;
}];
// 淡出
[UIView animateWithDuration:1.0 animations:^{
viewToFadeIn.alpha = 0.0;
} completion:^(BOOL finished) {
[viewToFadeIn removeFromSuperview];
}];
- 滑动切换效果(以从右向左滑动为例)
UIView *viewToSlide = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
viewToSlide.backgroundColor = [UIColor blueColor];
[self.view addSubview:viewToSlide];
[UIView animateWithDuration:1.0 animations:^{
viewToSlide.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
}];
代码示例 - 使用 UIViewController
的转场动画
- 定义一个实现
UIViewControllerAnimatedTransitioning
协议的类
#import <UIKit/UIKit.h>
@interface SlideTransitionAnimator : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic, assign) BOOL isPresenting;
@end
@implementation SlideTransitionAnimator
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
return 0.5;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView];
CGRect screenBounds = [UIScreen mainScreen].bounds;
if (self.isPresenting) {
toVC.view.frame = CGRectMake(screenBounds.size.width, 0, screenBounds.size.width, screenBounds.size.height);
[containerView addSubview:toVC.view];
} else {
fromVC.view.frame = CGRectMake(0, 0, screenBounds.size.width, screenBounds.size.height);
[containerView insertSubview:toVC.view belowSubview:fromVC.view];
}
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
if (self.isPresenting) {
toVC.view.frame = CGRectMake(0, 0, screenBounds.size.width, screenBounds.size.height);
} else {
fromVC.view.frame = CGRectMake(-screenBounds.size.width, 0, screenBounds.size.width, screenBounds.size.height);
}
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
- 在视图控制器中使用该转场动画
#import "ViewController.h"
#import "SlideTransitionAnimator.h"
@interface ViewController () <UIViewControllerTransitioningDelegate>
@property (nonatomic, strong) SlideTransitionAnimator *animator;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.animator = [[SlideTransitionAnimator alloc] init];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(100, 100, 200, 50);
[button setTitle:@"Present" forState:UIControlStateNormal];
[button addTarget:self action:@selector(presentViewController:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (void)presentViewController:(UIButton *)sender {
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor greenColor];
self.animator.isPresenting = YES;
vc.transitioningDelegate = self;
[self presentViewController:vc animated:YES completion:nil];
}
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
self.animator.isPresenting = YES;
return self.animator;
}
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
self.animator.isPresenting = NO;
return self.animator;
}
@end
代码示例 - 使用 CAAnimation
及其子类
- 淡入淡出效果使用
CABasicAnimation
UIView *viewForCAAnimation = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
viewForCAAnimation.backgroundColor = [UIColor yellowColor];
[self.view addSubview:viewForCAAnimation];
CABasicAnimation *fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeAnimation.fromValue = @(0.0);
fadeAnimation.toValue = @(1.0);
fadeAnimation.duration = 1.0;
[viewForCAAnimation.layer addAnimation:fadeAnimation forKey:@"fadeIn"];
- 滑动切换效果使用
CAKeyframeAnimation
(以从下向上滑动为例)
UIView *viewToSlideWithCA = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, self.view.bounds.size.height)];
viewToSlideWithCA.backgroundColor = [UIColor purpleColor];
[self.view addSubview:viewToSlideWithCA];
CAKeyframeAnimation *slideAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position.y"];
NSValue *startValue = [NSValue valueWithCGPoint:CGPointMake(viewToSlideWithCA.center.x, self.view.bounds.size.height + viewToSlideWithCA.bounds.size.height / 2)];
NSValue *endValue = [NSValue valueWithCGPoint:CGPointMake(viewToSlideWithCA.center.x, viewToSlideWithCA.center.y)];
slideAnimation.values = @[startValue, endValue];
slideAnimation.duration = 1.0;
[viewToSlideWithCA.layer addAnimation:slideAnimation forKey:@"slideUp"];