目錄:
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(@"動畫結束");
}];
}