目录:
1、三个结构体 CGPoint、CGSize、CGRect
2、视图的最基本属性
3、UIView的方法简介
4、UIView的动画方法
下面来认识一下UIView类,这个类继承自UIResponder,看这个名字我们就知道它是负责显示的画布,如果说把window比作画框的话。我们就是不断地在画框上移除、更换或者叠加画布,或者在画布上叠加其他画布,大小当然 由绘画者来决定了。有了画布,我们就可以在上面任意施为了。
UIView表示屏幕上的一块矩形区域,它在App中占有绝对重要的地位,因为iOS中几乎所有可视化控件都是UIView的子类。负责渲染区域的内容,并且响应该区域内发生的触摸事件
UIView的功能 :
1.管理矩形区域里的内容
2.处理矩形区域中的事件
3.子视图的管理
4.还能实现动画
UIView的子类也具有这些功能
1、三个结构体 CGPoint、CGSize、CGRect
1) CGPoint
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
2)CGSize
struct CGSize {
CGFloat width;
CGFloat height;
};
typedef struct CGSize CGSize;
3)CGRect
struct CGRect {
CGPoint origin; //偏移是相对父视图的
CGSize size;
};
typedef struct CGRect CGRect;
//这三个结构体均在一个头文件里:CGGeometry.h
2、视图的最基本属性
frame和center都是相对于父视图的,bounds是相对于自身的
frame 是CGRect,frame的origin是相对于父视图的左上角原点(0,0)的位置,改变视图的frame会改变center;
center 是CGPoint,指的就是整个视图的中心点,改变视图的center也会改变frame;
bounds 是CGRect,是告诉子视图本视图的原点位置(通俗的说就是,子视图的frame的origin与父视图的bounds的origin的差,就是子视图相对于父视图左上角的位置,如果结果为负,则子视图在父视图外)
通过addSubview:这个方法添加子类,不管谁添加它,只要越晚添加,视图就在越上层。
移除父视图也会把它得子视图移除。
//frame和bounds是UIView中的两个属性(property)。
//frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)
//bounds指的是:该view在本身坐标系统中 的位置和大小。(参照点是本身坐标系统)
-(CGRect)frame
{
returnCGRectMake(self.frame.origin.x,self.frame.origin.y,self.frame.size.width,self.frame.size.height);
}
-(CGRect)bounds
{
returnCGRectMake(0,0,self.frame.size.width,self.frame.size.height);
}
3、UIView的方法
一个 UIView 里面可以包含许多的 Subview(其他的 UIView),而这些 Subview 彼此之间是有所谓的阶层关系,这有点类似绘图软体中图层的概念,下面程式码示演示了几个在管理图层(Subview)上常用的方法,其程式码如下。
1)新增和移除Subview。
//将Subview从当前的UIView中移除
[Subview removeFromSuperview];
//替UIView增加一个Subview
[UIView addSubview:Subview];
2)在UIView中将Subview往前或是往后移动一个图层,往前移动会覆盖住较后层的 Subview,而往后移动则会被较上层的Subview所覆盖。
//将Subview往前移动一个图层(与它的前一个图层对调位置)
//将Subview往前移动一个图层(与它的前一个图层对调位置)
[UIView bringSubviewToFront:Subview];
//将Subview往后移动一个图层(与它的后一个图层对调位置)
[UIView sendSubviewToBack:Subview];
3)在UIView中使用索引Index交换两的Subview彼此的图层层级。
//交换两个图层
[UIView exchangeSubviewAtIndex:indexA withSubviewAtIndex:indexB];
4)使用Subview的变数名称取得它在UIView中的索引值(Index )。
//取得Index
NSInteger index = [[UIView subviews] indexOfObject:Subview名称];
5)替Subview加上NSInteger 的註记(Tag)好让之后它们分辨彼此。
//加上标记
[Subview setTag:NSInteger];
//通过标记得到view 返回值为UIView
[self.view viewWithTag:NSInteger];
6)最后是取得UIView中所有的Subview,呼叫此方法会传回一个 NSArray,并以由后往前的顺序列出这些 Subview,下图中是列出范例图片里Root中所有的Subview。
//取的UIView下的所有Subview
[UIView subviews] ;
4、UIView的动画方法
UIKit直接将动画集成到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画支持
执行动画所需要的工作由UIView类自动完成,但仍要在希望执行动画时通知视图,为此需要将改变属性的代码放在[UIView beginAnimations:nil context:nil]和[UIView commitAnimations]之间
1)常见方法解析:
//设置动画代理对象,当动画开始或者结束时会发消息给代理对象
+ (void)setAnimationDelegate:(id)delegate
//当动画即将开始时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector
+ (void)setAnimationWillStartSelector:(SEL)selector
//当动画结束时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector
+ (void)setAnimationDidStopSelector:(SEL)selector
//动画的持续时间,秒为单位
+ (void)setAnimationDuration:(NSTimeInterval)duration
//动画延迟delay秒后再开始
+ (void)setAnimationDelay:(NSTimeInterval)delay
//动画的开始时间,默认为now
+ (void)setAnimationStartDate:(NSDate *)startDate
// 动画的节奏控制
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve
// 动画的重复次数
+ (void)setAnimationRepeatCount:(float)repeatCount
//如果设置为YES,代表动画每次重复执行的效果会跟上一次相反
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses
//设置视图view的过渡效果, transition指定过渡类型, cache设置YES代表使用视图缓存,性能较好
+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache
2)UIView封装的动画与CALayer动画的对比
使用UIView和CALayer都能实现动画效果,但是在真实的开发中,一般还是主要使用UIView封装的动画,而很少使用CALayer的动画。
CALayer核心动画与UIView动画的区别:
UIView封装的动画执行完毕之后不会反弹。即如果是通过CALayer核心动画改变layer的位置状态,表面上看虽然已经改变了,但是实际上它的位置是没有改变的。
3)block动画
//简单常用
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
参数解析:
duration:动画的持续时间
delay:动画延迟delay秒后开始
options:动画的节奏控制
animations:将改变视图属性的代码放在这个block中
completion:动画结束后,会自动调用这个block
//转场动画
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
参数解析:
duration:动画的持续时间
view:需要进行转场动画的视图
options:转场动画的类型
animations:将改变视图属性的代码放在这个block中
completion:动画结束后,会自动调用这个block
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion
//方法调用完毕后,相当于执行了下面两句代码:
// 添加toView到父视图
[fromView.superview addSubview:toView];
// 把fromView从父视图中移除
[fromView.superview removeFromSuperview];
参数解析:
duration:动画的持续时间
options:转场动画的类型
animations:将改变视图属性的代码放在这个block中
completion:动画结束后,会自动调用这个block
4)动画示例
#pragma mark 原始动画
-(void)viewAnimationOne
{
//开始动画
[UIView beginAnimations:@"" context:nil];
//设置动画曲线
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:2];//执行时间
[UIView setAnimationRepeatAutoreverses:YES];//是否原路返回
[UIView setAnimationRepeatCount:2];//重复次数
[UIView setAnimationsEnabled:YES];//是否执行动画
//配置动画如何执行
//下移imageview
CGRect frame = self.imageview.frame;
frame.origin.y += 50;
self.imageview.frame = frame;
//提交动画
[UIView commitAnimations];
}
#pragma mark 系统动画
- (void)viewAnimationTwo
{
[UIView animateWithDuration:2 animations:^
{
CGRect frame = self.blueView.frame;
frame.origin.y -= 50;
self.blueView.frame = frame;
}];
}
#pragma mark 动画嵌套
- (void)viewAnimationThree
{
//blueview先上移50,再左移50
[UIView animateWithDuration:2 animations:^
{
CGRect frame = self.blueView.frame;
frame.origin.y -= 50;
self.blueView.frame = frame;
}
completion:^(BOOL finished)
{
[UIView animateWithDuration:2 animations:^
{
CGRect frame = self.blueView.frame;
frame.origin.x -= 50;
self.blueView.frame = frame;
} completion:nil];
}];
}
#pragma mark 延迟执行
- (void)viewAnimationFour
{
[UIView animateWithDuration:2 delay:0.5 options:UIViewAnimationOptionCurveEaseInOut animations:^
{
CGRect frame = self.imageview.frame;
frame.origin.y += 50;
self.imageview.frame = frame;
}
completion:^(BOOL finished)
{
NSLog(@"执行完成");
}];
}
#pragma mark 弹簧效果
- (void)viewAnimationFive
{
/*
usingSpringWithDamping:阻尼值(摩擦力)设定范围为0-1之间,值越小,摩擦力越小;反之,摩擦力越大。
initialSpringVelocity:弹力(动力)值越大,越贴近屏幕(动画幅度越大);
*/
//先变窄20,再变长100
[UIView animateWithDuration:2 delay:0.5 usingSpringWithDamping:0.9 initialSpringVelocity:10 options:UIViewAnimationOptionCurveEaseInOut animations:^
{
CGRect frame = self.blueView.frame;
frame.size.width -= 20;
frame.size.height += 100;
frame.origin.y -= 100;
self.blueView.frame = frame;
}
completion:^(BOOL finished)
{
NSLog(@"执行完毕");
}];
}
#pragma mark 动画组(多个动画同时执行) 通过关键帧实现
- (void)viewAnimationSix
{
[UIView animateKeyframesWithDuration:2 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^
{
/*
StartTime:开始时间,后面的动画开始时间依次类推
relativeDuration:持续时间,如果1秒内执行4个动画,则每个动画持续时间0.25秒
*/
//add Keyframe
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1/3.0 animations:^
{
CGRect frame = self.imageview.frame;
frame.origin.y += 50;
self.imageview.frame = frame;
}];
[UIView addKeyframeWithRelativeStartTime:1/3.0 relativeDuration:1/3.0 animations:^
{
CGRect frame = self.blueView.frame;
frame.origin.y -= 50;
self.blueView.frame = frame;
}];
[UIView addKeyframeWithRelativeStartTime:2/3.0 relativeDuration:1/3.0 animations:^
{
self.blueView.backgroundColor = [UIColor grayColor];
}];
}
completion:^(BOOL finished)
{
NSLog(@"动画结束");
}];
}