怎样做一个iOS App的启动分层引导动画
1个回答
展开全部
1. 首先我们要把我们承载整个动画场面的scrollView造出来
如
下,需要设置scrollView的几个关键属性:frame, contentSize, alwaysBounceHorizontal,
paginEnabled(这个如果是NO,那么页面间的弹性效果就没了),
delegate(需要设置从而获取scrollview的滚动状态)等等。
//初始化 scrollview
- (void)initScrollView
{
CGSize screenSize = [UIScreen mainScreen].bounds.size;
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, screenSize.height)];
//我们的scrollView的frame应该是屏幕大小
_scrollView.contentSize = CGSizeMake(screenSize.width * 4, screenSize.height);
//但是我们希望我们scrollView的可被展现区域是4个屏幕横排那么大
_scrollView.alwaysBounceHorizontal = YES;//横向一直可拖动
_scrollView.pagingEnabled = YES;//关键属性,打开page模式。
_scrollView.delegate = self;
_scrollView.showsHorizontalScrollIndicator = NO;//不要显示滚动条~
[self.view addSubview:_scrollView];
}
现在我们已经准备好了动画的画布,下面开始将每一页的元素加上去。
2. 加入页面元素
还是不要全篇幅贴代码了,以第一页为例把。
前面掉渣天的蛇鸡屎(我)的demo图已经表明,第一页,我们要有3个UILabel,一个UIImageView。
那么好,这些元素我们就给他声明出来。
@interface ViewController ()
@property (strong, nonatomic) UIScrollView *scrollView;//这是基本!
@property (strong, nonatomic) UIImageView *girlImageView;
@property (strong, nonatomic) UILabel *label_page1_1;
@property (strong, nonatomic) UILabel *label_page1_2;
@property (strong, nonatomic) UILabel *label_page1_3;
@end
然后把第一页的元素,加进来~
//为了更方便的初始化UILabel,我为UILabel增加了一个简易的类方法。是为了让代码更简洁可读。
+ (instancetype)labelWithText:(NSString *)text font:(UIFont *)font color:(UIColor *)color origin:(CGPoint)origin
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(origin.x, origin.y, 1000, 20)];
label.text = text;
label.font = font;
label.textColor = color;
[label sizeToFit];
return label;
}
//然后我们将第一页的元素加进来。
self.label_page1_1 = [UILabel labelWithText:@"我要买iPhone6!" font:[UIFont systemFontOfSize:18.0f] color:[UIColor redColor] origin:CGPointMake(140, 200)];
[self.scrollView addSubview:self.label_page1_1];
self.label_page1_2 = [UILabel labelWithText:@"我要看医生演唱会~~~~" font:[UIFont systemFontOfSize:18.0f] color:[UIColor blackColor] origin:CGPointMake(140, 240)];
[self.scrollView addSubview:self.label_page1_2];
self.label_page1_3 = [UILabel labelWithText:@"我要去大理!" font:[UIFont systemFontOfSize:18.0f] color:[UIColor orangeColor] origin:CGPointMake(140, 280)];
[self.scrollView addSubview:self.label_page1_3];
self.girlImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image_girl"]];
self.girlImageView.frame = CGRectMake(100, kScreenHeight - 200 - 50, 100, 200);
[self.scrollView addSubview:self.girlImageView];
3. 让第一页动起来~~
在第一页刚刚显示的时候,我们就希望第一页的元素能够有一个动起来的效果。那我们在上面刚刚加入第一页元素之后,可以紧接着做下面的事情:
self.girlImageView.transform = CGAffineTransformMakeTranslation(-200, 0);
self.label_page1_1.transform = CGAffineTransformMakeTranslation(- 100, 0);
self.label_page1_2.transform = CGAffineTransformMakeTranslation(100, 0);
self.label_page1_3.transform = CGAffineTransformMakeTranslation(- 120, 0);
[UIView animateWithDuration:0.7
animations:^{
self.girlImageView.transform = CGAffineTransformMakeTranslation(0, 0);
self.label_page1_1.transform = CGAffineTransformMakeTranslation(0, 0);
self.label_page1_2.transform = CGAffineTransformMakeTranslation(0, 0);
self.label_page1_3.transform = CGAffineTransformMakeTranslation(0, 0);
}];
可以看到,我们分别给第一页的四个元素不同的水平位移,然后希望它用0.7秒的时间,移动到之前init他们时候的位置。这样就完成了第一个4层的错位动画。
然后,我们希望在手指滑动scrollview 的时候,第一页的四个元素可以有相应的分层错位动画,那么我们第一需要拿到当前scrollView的位移量,也就是前面提到的很重要的contentOffset。这个值,在:
1
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
中,可以实时的获取。
具体来看,怎么做。
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat currentX = scrollView.contentOffset.x;
if (currentX <= kScreenWidth)
{
self.girlImageView.transform = CGAffineTransformMakeTranslation((kScreenWidth + 100.0f) * currentX / kScreenWidth, 0);
self.label_page1_2.transform = CGAffineTransformMakeTranslation(- 200 * currentX / kScreenWidth, 0);
}
}
呵呵,是不是看不懂,那就对了。。。
下面解释下,首先抛出两个定理:
定理一:在scrollview的滑动过程中,视觉上看,scrollview上的元素的移动方向与手指滑动方向相反,并且移动的距离与手指滑动的距离相等。但所有元素在scrollview上的物理位置并未改变。
定理二:在scrollview的滑动过程中,当且仅当scrollview上的元素的物理移动距离与手指滑动距离相等并且移动方向相反时,scrollview的元素视觉位置保持不变。
然后我们有两个需求:
第一,希望那个小女孩跟随手指滑动的时候,视觉上不是向左移动一直到消失,而是向右移动,待滑动到第二页的时候,小女孩出现在屏幕右侧。
我们应该明确,小女孩的移动,只能是在scrollview上位置的移动。根据定理二,我们知道,如果保持视觉上小女孩位置不变,小女孩在scrollView上的实际物理位移应该是:
公式 4.3.1 baseDistance = kScreenWidth 屏幕宽度
那么如果我们希望在移动到第二页之后,小女孩的视觉位置右移了100像素,那么小女孩在scrollView上的实际物理位移应该是:
公式 4.3.2 distance = baseDistance + 100
第一页到第二页,scrollView一共位移是 kScreenWidth ,当前scrollView位移是 contentOffset.x ,可以得出,当前位移的比例:
公式 4.3.3 status = scrollView.contentOffest.x / distance
由 4.3.1 4.3.2 4.3.3可得,我们设置小女孩位移的方式:
1
self.girlImageView.transform = CGAffineTransformMakeTranslation((kScreenWidth + 100.0f) * currentX / kScreenWidth, 0);
第二个需求,希望第一页中,第二个label的向左移动速度快于其他两个label。
根据定理二,和类似于上面的推倒(推导)方式,也易得第二个label的位移方式:
1
self.label_page1_2.transform = CGAffineTransformMakeTranslation(- 200 * currentX / kScreenWidth, 0);
如
下,需要设置scrollView的几个关键属性:frame, contentSize, alwaysBounceHorizontal,
paginEnabled(这个如果是NO,那么页面间的弹性效果就没了),
delegate(需要设置从而获取scrollview的滚动状态)等等。
//初始化 scrollview
- (void)initScrollView
{
CGSize screenSize = [UIScreen mainScreen].bounds.size;
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, screenSize.height)];
//我们的scrollView的frame应该是屏幕大小
_scrollView.contentSize = CGSizeMake(screenSize.width * 4, screenSize.height);
//但是我们希望我们scrollView的可被展现区域是4个屏幕横排那么大
_scrollView.alwaysBounceHorizontal = YES;//横向一直可拖动
_scrollView.pagingEnabled = YES;//关键属性,打开page模式。
_scrollView.delegate = self;
_scrollView.showsHorizontalScrollIndicator = NO;//不要显示滚动条~
[self.view addSubview:_scrollView];
}
现在我们已经准备好了动画的画布,下面开始将每一页的元素加上去。
2. 加入页面元素
还是不要全篇幅贴代码了,以第一页为例把。
前面掉渣天的蛇鸡屎(我)的demo图已经表明,第一页,我们要有3个UILabel,一个UIImageView。
那么好,这些元素我们就给他声明出来。
@interface ViewController ()
@property (strong, nonatomic) UIScrollView *scrollView;//这是基本!
@property (strong, nonatomic) UIImageView *girlImageView;
@property (strong, nonatomic) UILabel *label_page1_1;
@property (strong, nonatomic) UILabel *label_page1_2;
@property (strong, nonatomic) UILabel *label_page1_3;
@end
然后把第一页的元素,加进来~
//为了更方便的初始化UILabel,我为UILabel增加了一个简易的类方法。是为了让代码更简洁可读。
+ (instancetype)labelWithText:(NSString *)text font:(UIFont *)font color:(UIColor *)color origin:(CGPoint)origin
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(origin.x, origin.y, 1000, 20)];
label.text = text;
label.font = font;
label.textColor = color;
[label sizeToFit];
return label;
}
//然后我们将第一页的元素加进来。
self.label_page1_1 = [UILabel labelWithText:@"我要买iPhone6!" font:[UIFont systemFontOfSize:18.0f] color:[UIColor redColor] origin:CGPointMake(140, 200)];
[self.scrollView addSubview:self.label_page1_1];
self.label_page1_2 = [UILabel labelWithText:@"我要看医生演唱会~~~~" font:[UIFont systemFontOfSize:18.0f] color:[UIColor blackColor] origin:CGPointMake(140, 240)];
[self.scrollView addSubview:self.label_page1_2];
self.label_page1_3 = [UILabel labelWithText:@"我要去大理!" font:[UIFont systemFontOfSize:18.0f] color:[UIColor orangeColor] origin:CGPointMake(140, 280)];
[self.scrollView addSubview:self.label_page1_3];
self.girlImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image_girl"]];
self.girlImageView.frame = CGRectMake(100, kScreenHeight - 200 - 50, 100, 200);
[self.scrollView addSubview:self.girlImageView];
3. 让第一页动起来~~
在第一页刚刚显示的时候,我们就希望第一页的元素能够有一个动起来的效果。那我们在上面刚刚加入第一页元素之后,可以紧接着做下面的事情:
self.girlImageView.transform = CGAffineTransformMakeTranslation(-200, 0);
self.label_page1_1.transform = CGAffineTransformMakeTranslation(- 100, 0);
self.label_page1_2.transform = CGAffineTransformMakeTranslation(100, 0);
self.label_page1_3.transform = CGAffineTransformMakeTranslation(- 120, 0);
[UIView animateWithDuration:0.7
animations:^{
self.girlImageView.transform = CGAffineTransformMakeTranslation(0, 0);
self.label_page1_1.transform = CGAffineTransformMakeTranslation(0, 0);
self.label_page1_2.transform = CGAffineTransformMakeTranslation(0, 0);
self.label_page1_3.transform = CGAffineTransformMakeTranslation(0, 0);
}];
可以看到,我们分别给第一页的四个元素不同的水平位移,然后希望它用0.7秒的时间,移动到之前init他们时候的位置。这样就完成了第一个4层的错位动画。
然后,我们希望在手指滑动scrollview 的时候,第一页的四个元素可以有相应的分层错位动画,那么我们第一需要拿到当前scrollView的位移量,也就是前面提到的很重要的contentOffset。这个值,在:
1
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
中,可以实时的获取。
具体来看,怎么做。
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat currentX = scrollView.contentOffset.x;
if (currentX <= kScreenWidth)
{
self.girlImageView.transform = CGAffineTransformMakeTranslation((kScreenWidth + 100.0f) * currentX / kScreenWidth, 0);
self.label_page1_2.transform = CGAffineTransformMakeTranslation(- 200 * currentX / kScreenWidth, 0);
}
}
呵呵,是不是看不懂,那就对了。。。
下面解释下,首先抛出两个定理:
定理一:在scrollview的滑动过程中,视觉上看,scrollview上的元素的移动方向与手指滑动方向相反,并且移动的距离与手指滑动的距离相等。但所有元素在scrollview上的物理位置并未改变。
定理二:在scrollview的滑动过程中,当且仅当scrollview上的元素的物理移动距离与手指滑动距离相等并且移动方向相反时,scrollview的元素视觉位置保持不变。
然后我们有两个需求:
第一,希望那个小女孩跟随手指滑动的时候,视觉上不是向左移动一直到消失,而是向右移动,待滑动到第二页的时候,小女孩出现在屏幕右侧。
我们应该明确,小女孩的移动,只能是在scrollview上位置的移动。根据定理二,我们知道,如果保持视觉上小女孩位置不变,小女孩在scrollView上的实际物理位移应该是:
公式 4.3.1 baseDistance = kScreenWidth 屏幕宽度
那么如果我们希望在移动到第二页之后,小女孩的视觉位置右移了100像素,那么小女孩在scrollView上的实际物理位移应该是:
公式 4.3.2 distance = baseDistance + 100
第一页到第二页,scrollView一共位移是 kScreenWidth ,当前scrollView位移是 contentOffset.x ,可以得出,当前位移的比例:
公式 4.3.3 status = scrollView.contentOffest.x / distance
由 4.3.1 4.3.2 4.3.3可得,我们设置小女孩位移的方式:
1
self.girlImageView.transform = CGAffineTransformMakeTranslation((kScreenWidth + 100.0f) * currentX / kScreenWidth, 0);
第二个需求,希望第一页中,第二个label的向左移动速度快于其他两个label。
根据定理二,和类似于上面的推倒(推导)方式,也易得第二个label的位移方式:
1
self.label_page1_2.transform = CGAffineTransformMakeTranslation(- 200 * currentX / kScreenWidth, 0);
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询