IOS中的动画
UIView动画:渐隐渐显、位置移动
UIKit自带动画:UITableViewCell添加删除、UIViewController切换
UIView内置动画封装(UIView AnimationWithBlocks)
处理日常开发80%以上的动画效果
处理基本的Frame、Alpha、Transform
不能自定义中间过程
实现步骤:
1.设置动画参数(时间、效果)
2.动画终止时属性的最终值
+(void)animateWithDuration:(NSTimeInterval)duration //动画时间
delay:(NSTimeInterval)delay //动画延迟
usingSpringWithDamping:(CGFloat)dampingRatio //阻尼系数
initialSpringVelocity:(CGFloat)velocity //回弹系数
option:(UIViewAnimationOptions)options //动画效果
animations:^{
//动画最终样式
} completion:^(BOOL finished){
//动画结束后的逻辑
}
简单实现弹窗动画
//
// GSCDeleteCellView.m
// GSCApp1
//
// Created by gsc on 2024/5/19.
//
#import "GSCDeleteCellView.h"
@interface GSCDeleteCellView()
@property(nonatomic, strong, readwrite)UIView *backgroundView;
@property(nonatomic, strong, readwrite)UIButton *deleteButton;
@property(nonatomic, copy, readwrite) dispatch_block_t deleteBlock;
@end
@implementation GSCDeleteCellView
-(instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if(self){
[self addSubview:({
_backgroundView = [[UIView alloc] initWithFrame:self.bounds];
_backgroundView.backgroundColor = [UIColor blackColor];
_backgroundView.alpha = 0.5;
[_backgroundView addGestureRecognizer:({
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissDeleteButton)];
tapGesture;
})];
_backgroundView;
})];
}
[self addSubview:({
_deleteButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[_deleteButton addTarget:self action:@selector(_clickButton) forControlEvents:UIControlEventTouchUpInside];
_deleteButton.backgroundColor = [UIColor whiteColor];
_deleteButton;
})];
return self;
}
-(void)showDeleteViewFromPoint:(CGPoint)point clickBlock:(dispatch_block_t) clickBlock{
//deleteButton初始位置
_deleteButton.frame = CGRectMake(point.x, point.y, 0, 0);
_deleteBlock = [clickBlock copy];
NSArray<UIScene *> *connectedScenesArray = UIApplication.sharedApplication.connectedScenes.allObjects;
for (UIScene *scene in connectedScenesArray) {
if ([scene isKindOfClass:[UIWindowScene class]]) {
UIWindowScene *windowScene = (UIWindowScene *)scene;
// 检查场景是否处于前台活跃状态
if (scene.activationState == UISceneActivationStateForegroundActive && windowScene.windows.count > 0) {
UIWindow *window = windowScene.windows.firstObject;
[window addSubview:self];
break;
}
}
}
// [UIView animateWithDuration:1.f animations:^{
// self.deleteButton.frame = CGRectMake((self.bounds.size.width - 200) / 2, (self.bounds.size.height - 200) / 2, 200, 200);
// }];
[UIView animateWithDuration:1.f delay:0.1f usingSpringWithDamping:0.8 initialSpringVelocity:0.1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.deleteButton.frame = CGRectMake((self.bounds.size.width - 200) / 2, (self.bounds.size.height - 200) / 2, 200, 200);
} completion:^(BOOL finished){
// NSLog(@"");
}];
}
-(void)dismissDeleteButton{
[self removeFromSuperview];
}
-(void)_clickButton{
if(_deleteBlock){
_deleteBlock();
}
[self removeFromSuperview];
}
@end
//
// ViewController.m
// GSCApp1
//
// Created by gsc on 2024/5/13.
//
#import "ViewController.h"
#import "GSCNormalTableViewCell.h"
#import "GSCDetailViewController.h"
#import "GSCDeleteCellView.h"
@interface ViewController ()<UITableViewDataSource,UITableViewDelegate,UIWebViewDelegate,GSCNormalTableViewCellDelegate>
@property(nonatomic, strong, readwrite)UITableView *tableView;
@property(nonatomic, strong, readwrite)NSMutableArray *dataArray;
@end
@implementation ViewController
-(instancetype)init{
self = [super init];
if(self){
_dataArray = @[].mutableCopy;
for (int i = 0; i<20; i++){
[_dataArray addObject:@(i)];
}
}
return self;
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
_tableView.dataSource = self;
_tableView.delegate = self;
[self.view addSubview:_tableView];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 100;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
GSCDetailViewController *controller = [[GSCDetailViewController alloc] init];
controller.title = [NSString stringWithFormat:@"%@",@(indexPath.row)];
controller.view.backgroundColor = [UIColor whiteColor];
[self.navigationController pushViewController:controller animated:YES];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return _dataArray.count;
}
//- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
// NSLog(@"scrollViewDidScroll");
//}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
GSCNormalTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"id"];
if (!cell){
cell = [[GSCNormalTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"id"];
cell.delegate = self;
}
// UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"id"];
[cell layoutTableViewCell];
return cell;
}
-(void)tableViewCell:(UITableViewCell *)tableViewCell clickDeletButton:(UIButton *)deleteButton{
GSCDeleteCellView *deleteView = [[GSCDeleteCellView alloc] initWithFrame:self.view.bounds];
CGRect rect = [tableViewCell convertRect:deleteButton.frame toView:nil];
//解决循环引用
__weak typeof (self) wself = self;
[deleteView showDeleteViewFromPoint:rect.origin clickBlock:^{
__strong typeof(self) strongSelf = wself;
[strongSelf.dataArray removeLastObject];
[self.tableView deleteRowsAtIndexPaths:@[[strongSelf.tableView indexPathForCell:tableViewCell]] withRowAnimation:UITableViewRowAnimationAutomatic];
}];
}
@end
CALayer基本应用
1.每个UIView都有一个CALayer负责内容的绘制与动画
2.UIKit其他组件对应的展示Layer(CAScrollLayer CATextLayer)
3.和UIView相同的结构(subLayer)
修改Button的展示形式
[self.contentView addSubview:({
self.deletButton = [[UIButton alloc] initWithFrame:CGRectMake(290, 80, 30, 20)];
[self.deletButton setTitle:@"X" forState:UIControlStateNormal];
[self.deletButton setTitle:@"V" forState:UIControlStateHighlighted];
self.deletButton.backgroundColor = [UIColor blueColor];
[self.deletButton addTarget:self action:@selector(deleteButtonClicked) forControlEvents:UIControlEventTouchUpInside];
//修改Button形式
self.deletButton.layer.cornerRadius = 10;
self.deletButton.layer.masksToBounds = YES;
self.deletButton.layer.borderColor = [UIColor lightGrayColor].CGColor;
self.deletButton.layer.borderWidth = 2;
self.deletButton;
})];
创建自定义CALayer
1.轻量、无需交互的单纯展示
2.不易Debug
3.UIView默认情况下禁止了CALayer的动画
CoreAnimation
CABaseAnimation——基本动画,时常、开始结束状态等
CAKeyframeAnimation——关键路径动画,设置不同的时间点
CAAnimationGroup——复杂动画都可以分解成多个简单的动画
CATransition——转场动画(渐入渐出) -UIViewController