UIView常見屬性應用執行個體,uiview應用執行個體
上篇主要介紹了UIView的幾個主要屬性,分別為frame,bounds,center,transform,本篇通過一個簡單的執行個體來驗證這幾個屬性的功能.
軟體介面如下:
主要功能:通過介面上的上下左右按鈕來移動上面的圖片,通過+-來放到縮小圖片,下面兩個旋轉按鈕實現了旋轉的功能(transform的應用);複位按鈕實現了還原的功能(transform的功能)
介面上顯示圖片的是一個Button,通過點擊圖片,會更換圖片.
首先附上原始碼:
1 // 2 // ViewController.m 3 // 03-常見屬性 4 // 5 // Created by hukezhu on 15/5/9. 6 // 7 // 8 9 #import "ViewController.h"10 11 @interface ViewController ()12 /**13 * 圖片屬性(Button)14 */15 @property (weak, nonatomic) IBOutlet UIButton *head;16 /**17 * 點擊按鈕回應程式法18 */19 -(IBAction)move:(UIButton *)btn;20 21 22 @end23 24 @implementation ViewController25 26 - (void)viewDidLoad {27 [super viewDidLoad];28 }29 -(IBAction)move:(UIButton *)btn{30 31 //CGRect tempframe = self.head.frame;32 33 //將改變的大小提取出來,便於擴充34 CGFloat margin = 80;35 //動畫的開始36 [UIView beginAnimations:nil context:nil];37 //設定動畫期間38 [UIView setAnimationDuration:2.0];39 //根據tag值來擷取是哪個按鈕點擊了40 switch (btn.tag) {41 case 1:42 //tempframe.origin.y -= margin;43 //向上移動44 self.head.transform = CGAffineTransformTranslate(self.head.transform, 0, -margin);45 break;46 47 case 2:48 //tempframe.origin.y += margin;49 //向下移動50 self.head.transform = CGAffineTransformTranslate(self.head.transform, 0, margin);51 break;52 case 3:53 //tempframe.origin.x -= margin;54 //向左移動55 self.head.transform = CGAffineTransformTranslate(self.head.transform, -margin, 0);56 break;57 case 4:58 //tempframe.origin.x += margin;59 //向右移動60 self.head.transform = CGAffineTransformTranslate(self.head.transform, margin, 0);61 break;62 case 5:63 // tempframe.size.height += margin;64 // tempframe.size.width += margin;65 //放大66 self.head.transform = CGAffineTransformScale(self.head.transform, 1.5, 1.5);67 break;68 case 6:69 //tempframe.size.height -= margin;70 //tempframe.size.width -= margin;71 //縮小72 self.head.transform = CGAffineTransformScale(self.head.transform, 0.8, 0.8);73 break;74 case 7:75 //向左旋轉(逆時針旋轉)76 self.head.transform = CGAffineTransformRotate(self.head.transform, -M_PI_4);77 break;78 case 8:79 //向右旋轉(順時針旋轉)80 self.head.transform = CGAffineTransformRotate(self.head.transform, M_PI_4);81 break;82 case 9:83 //複位功能84 self.head.transform =CGAffineTransformIdentity;85 break;86 }87 //self.head.frame = tempframe;88 89 //提交動畫(動畫結束)90 [UIView commitAnimations];91 }92 93 @end
上面這段代碼是使用了transform屬性實現了最初預想的功能.
上面放置的源碼已經實現了預想的功能,下面分析一下其中的細節部分.
1.上下左右 移動
實現上下左右移動,就是利用空間的位置,通過修改x/y值來進行移動,這裡仍用上面這個小程式的代碼來進行示範:
self.head.frame.origin.y -=10;//這句話會報錯(錯誤:Expression is not assignable),因為這個屬性不允許直接修改.
所以這裡有一個結論:不能直接存取對象的結構體屬性的成員變數
但是可以訪問對象的結構體屬性,將這個結構體屬性取出來,再進行修改
1 1>取出對象的結構體屬性值frame,然後複值給臨時變數2 CGRect tempFrame = self.head.frame;3 2>修改臨時變數的值4 tempFrame.origin.y -= 10;5 3>用臨時變數覆蓋原來的frame6 self.head.frame = tempFrame;
所以通過frame屬性實現上述功能的代碼如下:
-(IBAction)up{ //self.head.frame.origin.y -=10; CGRect tempFrame = self.head.frame; tempFrame.origin.y -= 10; self.head.frame = tempFrame;}-(IBAction)down{ CGRect tempFrame = self.head.frame; tempFrame.origin.y += 10; self.head.frame = tempFrame;}-(IBAction)left{ CGRect tempFrame = self.head.frame; tempFrame.origin.x -= 10; self.head.frame = tempFrame;}-(IBAction)right{ CGRect tempFrame = self.head.frame; tempFrame.origin.x += 10; self.head.frame = tempFrame;}
觀察上面代碼,有太多的重複的代碼,所以可以將這些重複的代碼提取出來,封裝成另外一個方法:
1 -(IBAction)move:(UIButton *)btn{ 2 3 //開始動畫 4 [UIView beginAnimations:nil context:nil]; 5 6 //動畫持續2秒 7 [UIView setAnimationDuration:2.0]; 8 9 10 //取出原來的屬性11 CGRect tempFrame = self.head.frame;12 13 CGFloat delta = 100;14 switch (btn.tag) {15 case 1:16 tempFrame.origin.y -= delta;17 break;18 case 2:19 tempFrame.origin.y += delta;20 break;21 case 3:22 tempFrame.origin.x -= delta;23 break;24 case 4:25 tempFrame.origin.x += delta;26 break;27 }28 self.head.frame = tempFrame;29 30 31 //提交動畫32 [UIView commitAnimations];33 }
這段代碼使用了tag屬性,每個控制項都有一個tag值,預設為0(當然這個tag值是允許重複的,不是唯一的)在開發過程中,每個視圖一般都有多個子視圖,我們給每個子視圖設定不同的tag值,可以通過這個tag值來擷取到這個視圖,方法為:Viewwithtag:
2.center屬性:
控制項中點的位置(以父控制項的左上方為座標原點),通過修改center 的值也可以實現上下左右移動
1 - (void)move:(UIButton *)btn{ 2 3 // 0.開啟動畫 4 [UIView beginAnimations:nil context:nil]; 5 // 0.1設定動畫的時間 6 [UIView setAnimationDuration:1.5]; 7 // 1.取出對象的結構體屬性center,賦值給臨時的變數 8 CGFloat delat = 100; 9 CGPoint tempCenter = self.head.center;10 switch (btn.tag) {11 case 10:12 tempCenter.y -= delat;13 break;14 case 20:15 tempCenter.y += delat;16 break;17 case 30:18 tempCenter.x -= delat;19 break;20 case 40:21 tempCenter.x += delat;22 break;23 24 }25 // 3.用臨時變數的值覆蓋原來的值26 self.head.center = tempCenter;27 // 4.提交動畫28 [UIView commitAnimations];29 30 } 3.transform屬性:
這個屬性在本篇一開始就已經說過了,最上面的代碼實現就是使用transform實現的
2.放大和縮小
放大和縮小也就是修改控制項的尺寸,上篇也介紹過了,修改尺寸,可以使用frame\bounds\transform,其中transform屬性已經在本篇一開始就使用了,下面說一下frame和bounds屬性
1.frame屬性:
1 -(IBAction)big{ 2 3 [UIView beginAnimations:nil context:nil]; 4 [UIView setAnimationDuration:2.0]; 5 CGRect tempFrame = self.head.frame; 6 tempFrame.size.height += 10; 7 tempFrame.size.width += 10; 8 self.head.frame = tempFrame; 9 [UIView commitAnimations];10 }11 12 -(IBAction)small{13 14 CGRect tempFrame = self.head.frame;15 tempFrame.size.height -= 10;16 tempFrame.size.width -= 10;17 self.head.frame = tempFrame;18 19 }
2.bounds屬性:
1 - (void)big{ 2 // 0.開啟動畫 3 [UIView beginAnimations:nil context:nil]; 4 // 0.1設定動畫的時間 5 [UIView setAnimationDuration:1.5]; 6 // 1.取出對象的結構體屬性bounds,賦值給臨時的變數 7 CGRect tempBounds = self.head.bounds; 8 // 2.修改臨時變數的值 9 // tempFrame.origin.y = tempFrame.origin.y - 10;10 tempBounds.size.width += 10;11 tempBounds.size.height += 10;12 // 3.用臨時變數的值覆蓋原來的值13 self.head.bounds = tempBounds;14 // 4.提交動畫15 [UIView commitAnimations];16 17 18 19 }20 - (void)small{21 // 0.開啟動畫22 [UIView beginAnimations:nil context:nil];23 // 0.1設定動畫的時間24 [UIView setAnimationDuration:1.5];25 // 1.取出對象的結構體屬性bounds,賦值給臨時的變數26 CGRect tempBounds = self.head.bounds;27 // 2.修改臨時變數的值28 // tempFrame.origin.y = tempFrame.origin.y - 10;29 tempBounds.size.width -= 10;30 tempBounds.size.height -= 10;31 // 3.用臨時變數的值覆蓋原來的值32 self.head.frame = tempBounds;33 [UIView commitAnimations];34 35 36 }
3.旋轉
這個目前只能使用transform屬性來實現,見本篇最開始的代碼.
transform屬性注意點
1 *transform 是一種狀態,並且只有一種狀態2 * 向上移動3 (1)CGAffineTransformMakeTranslation(<#CGFloat tx#>, <#CGFloat ty#>):只能變化一次,因為這種方式的變化始終是以最原始的狀態值進行變化的,所以只能變化一次4 5 (2)CGAffineTransformTranslate(CGAffineTransform t, <#CGFloat tx#>, <#CGFloat ty#>):能夠多次變化,每次變化都是以上一次的狀態(CGAffineTransform t)進行的變化,所以可以多次變化
所以我們一般使用的是CGAffineTransformTranslate這個方法,如果使用CGAffineTransformMakeTranslation這個方法,則只能變化一次
附:storyboar拖線;