UIView詳解
MVC架構模式
MVC(Model-View-Controller)是實現數據和顯示數據的視圖分離的架構模式(有一定規模的應用都應該實現數據和顯示的分離)。其中,M代表模型,就是程序中使用的數據和狀態,它不理會用戶界面或表現方式,只負責數據和狀態的存儲;V代表視圖,是呈現給用戶看的東西,當然用戶也可以通過視圖來表達想要進行的操作;C代表控制器,它負責協調模型和視圖,當模型更改時要刷新視圖,這通常會包含一些邏輯。
UIView的常用屬性和方法
之前我們說過,UIView可以代表屏幕上的一塊矩形區域,它負責內容的顯示、定位以及響應用戶的觸摸事件,是用戶和應用進行交互的主要方式,我們再來看看UIView的屬性和方法。
繪制和更新視圖的方法
-
-drawRect:方法:繪圖(可以使用貝塞爾曲線進行繪圖)
-
-setNeedsDisplay方法:讓整個視圖重繪
-
-setNeedsDisplayInRect:方法:讓視圖指定的矩形區域重繪
管理手勢操作的方法
-
-addGestureRecognizer:方法:添加手勢識別器
-
-removeGestureRecognizer:方法:刪除手勢識別器
使用Block語法設置動畫的類方法
-
+animateWithDuration:animations:類方法:用指定的持續時間完成通過Block指定的動畫
為視圖添加動畫效果的類方法
-
-
beginAnimations:context:類方法:開始一個動畫
-
-
commitAnimations類方法:執行動畫
-
-
setAnimationStartDate:類方法:設置動畫開始時間
-
-
setAnimationDuration:類方法:設置動畫持續時間
-
-
setAnimationDelay:類方法:設置延遲多少時間播放動畫
-
-
setAnimationRepeatCount:類方法:設置動畫重復播放次數
-
-
setAnimationRepeatAutoreverses:類方法:設置是否反向執行動畫
-
-
setAnimationTransition:forView:cache:類方法:設置動畫的執行效果以及作用于哪個視圖
說明:UIView動畫只能修改關于坐標系統的屬性以及色彩和透明度。
下面的例子演示了一個扯日歷的動畫效果。
[UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:2]; [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.superview cache:YES]; [self removeFromSuperview]; [UIView commitAnimations];
與運動視覺效果相關的方法
-
-
addMotionEffect:方法:添加運動視覺效果
-
-
removeMotionEffect:方法:刪除運動視覺效果
通過標識獲得UIView
-
-
viewWithTag:方法:通過指定的標識值獲取視圖
轉換坐標系統的方法
-
-
convertPoint:toView:方法:將當前視圖上的坐標轉換為指定視圖上的坐標,如果第二個參數為nil,則轉換成窗口坐標
-
-
convertPoint:fromView:方法:將指定視圖上的坐標轉換為當前視圖的坐標
視圖碰撞檢測方法
-
-
hitTest:withEvent:方法:獲得一個點所在的視圖上,如果當前視圖包含這個點則返回點所在的最遠子視圖,如果當前視圖不包括這個點則返回nil
-
-
pointInside:withEvent:方法:判斷一個點有沒有在當前視圖上
視圖相關的回調方法
-
-
didAddSubview:方法:添加子視圖的回調方法
-
-
willRemoveSubview:方法:移除子視圖的回調方法
-
-
willMoveToSuperview:方法:視圖將要移到某個父視圖的回調方法
-
-
didMoveToSuperview:方法:視圖已經移到某個父視圖的回調方法
-
-
willMoveToWindow:方法:視圖將要移到UIWindow對象的回調方法
-
-
didMoveToWindow:方法:視圖已經移到UIWindow對象的回調方法
下面的例子演示了將一個視圖伸縮后再旋轉的動畫效果。
// 橫向拉伸1.5倍,縱向拉伸0.5倍 view.transform = CGAffineTransformMakeScale(1.5, 0.5); // 在剛才的變換的基礎上再旋轉30度 view.transform = CGAffineTransformRotate(view.transform, M_PI / 6);
提示:每一個子視圖只能有一個父視圖,當我們將一個子視圖添加到另一個父視圖上面時,它會脫離原來的父視圖。另外,我們指定子視圖的frame、bounds等屬性時,它的值是相當于父視圖的相對值,而不是屏幕的絕對值,如果父視圖改變了位置,那么這些子視圖也會跟著改變。父視圖如果設置了隱藏或者透明效果,肯定也會影響到子視圖。子視圖超出父視圖的部分,是不能夠接受事件的。
如果需要從父視圖中批量刪除子視圖,可以使用下面的代碼:
NSArray *subViews = self.subViews; if([subViews count] != 0) { [subViews makeObjectPerformSelector:@selector(removeFromSuperview)]; }
CALayer
UIView和CALayer的關系
UIView和CALayer是相互依賴的關系,UIView依賴與CALayer提供的內容,CALayer依賴UIView提供的容器來顯示繪制的內容。CALayer基于圖像管理內容并允許你在這些內容上創建動畫。如果沒有CALayer,UIView自身也不會存在,UIView是一個特殊的CALayer實現,添加了響應事件的能力。一言以蔽之,UIView來自CALayer,高于CALayer,是CALayer高層實現與封裝;UIView的很多特性都源于CALayer對它的支持。
通過CALayer改變UIView的形狀
-
borderColor屬性:邊框顏色。
-
borderWidth屬性:邊框寬度。
-
cornerRadius屬性:邊框轉角半徑(實現圓角效果)。
通過CALayer添加動畫效果
-
transforms屬性:指定對CALayer中的內容做怎樣的變換,支持3D效果和動畫。
UIImageView的使用
UIImageView對象提供了一個基于視圖的容器來展示一張或者一系列圖像,同時也支持以動畫的方式來呈現一組圖像(可以指定播放間隔和頻率)。簡單的說,UIImageView就是UIImage對象的承載者,當需要將UIImage呈現在UIView上時就需要UIImageView。二者的關系就像UILabel和NSString之間的關系。
UIImageView的創建和使用
-
-
initWithImage:方法:這種方式適合創建小圖片,尤其是素材類圖片。
UIImageView的常用屬性和方法
-
contentMode屬性:圖片的填充模式。(繼承自UIView)
-
clipsToBounds屬性:修剪超出邊界的部分。(繼承自UIView)
-
animationImages屬性:裝在用于動畫的圖像的數組。
-
animationDuration屬性:動畫播放的持續時間。
-
animationRepeatCount屬性:動畫的重復次數,0表示循環播放。
-
-
startAnimating方法:開始播放動畫。
-
-
stopAnimating方法:停止播放動畫。
-
-
isAnimating方法:返回BOOL值表示動畫是否正在播放中。
下面用UIImageView來實現一個動畫,完成后的效果如下圖所示。
#import "ViewController.h" @interface ViewController () { NSTimer *timer; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 用一個數組來裝構成動畫的所有圖片 NSMutableArray *imageArray = [NSMutableArray array]; for (int i = 0; i < 6; i++) { [imageArray addObject:[UIImage imageNamed:[NSString stringWithFormat:@"runner%d.jpg", i]]]; } // 創建UIImageView對象并指定相關的動畫圖片 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 150, 75, 100)]; imageView.animationImages = [imageArray copy]; // 設置圖片切換的時間間隔 imageView.animationDuration = 0.5; imageView.tag = 101; // imageView.animationRepeatCount = 10; // 開始動畫 [imageView startAnimating]; [self.view addSubview:imageView]; // 啟動一個計時器讓UIImageView向右移動 timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(runAhead) userInfo:nil repeats:YES]; } // 修改UIImageView的x坐標使其向右移動并在到達邊界時返回 - (void) runAhead { UIImageView *currentView = (id)[self.view viewWithTag:101]; CGRect rect = currentView.frame; rect.origin.x += 1; if(rect.origin.x > self.view.bounds.size.width) { rect.origin.x = -75; } currentView.frame = rect; } @end