- iPhone UIKit詳解
- 王志剛 王中元 朱蕾編著
- 1462字
- 2019-01-01 07:04:22
2.2 內容管理
2.2.1 UIView的內容
繪制原始的UIView時,需要繪制的可能只有背景色。但是當UIView中擁有一些內容后,例如是UILable或UIImageView這樣的組成畫面的基本元素,那么該如何進行UIView的繪制呢?或者說如何控制這些內容的顯示方式呢?本節中,將以擁有各種形式內容的UIView來介紹如何控制具體內容顯示方式的設置方法。
2.2.2 內容的自動尺寸調整
在UIImageView中,根據邊框的大小,可以調整其中包含的圖片的顯示尺寸。默認為延伸到充滿整個邊框所占的空間,此時UIView的contentMode屬性為UIViewcontent ModeScaleToFill。contentMode屬性中可指定UIViewcontentMode類型的常量,通過設置不同常量值來進行內容的尺寸調整或位置調整。如表2-3所示是contentMode屬性與內容尺寸、位置的對應情況。
表2-3 contentMode屬性與內容尺寸、位置的對應關系表
續表
續表
當內容的繪制范圍超出了UIView的frame屬性標示的范圍時,系統將會在frame屬性標示的范圍外進行內容繪制。如果想讓繪制范圍限制在UIView的邊框范圍內,需要事先將clipsToBounds屬性設置為YES。
2.2.3 指定內容的伸縮區域
上一小節介紹了如何通過contentMode屬性來改變UIView中內容的尺寸與位置。從iPhone OS 3.0開始追加了可以在內容伸縮時指定具體可伸縮區域的屬性。這就是contentStretch屬性。在contentStretch屬性中以CGRect類型的數據來指定可伸縮的區域。此時,以x為橫坐標、y為縱坐標,以及分別以0.0到1.0范圍的數字指定寬、高的形式來進行設置。默認如下:
- origin.x = 0.0
- origin.y = 0.0
- size.width = 1.0
- size.height = 1.0
通過調整這些值,可以在調整內容尺寸時改變伸縮的區域。如表2-4所示是設置值與內容伸縮區域變化的對應表。
表2-4 contentStretch屬性與伸縮區域的變化
續表
2.2.4 UIView適應內容
上一小節介紹了讓內容根據UIView的大小進行尺寸調整。本節將介紹UIView本身如何根據內容的大小進行調整的方法。此時使用的是sizeToFit方法。例如在UILabel中使用sizeToFit方法后,可以根據UILabel中保持的文本字符串大小自動調整UILabel的大小。UIButton的情況下,根據按鈕標題的大小自動調整按鈕的大小。下面是使用sizeToFit方法的實例代碼。
// 追加短標簽 UILabel* label1 = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; label1.backgroundColor = [UIColor blueColor]; label1.textColor = [UIColor whiteColor]; label1.text = @"短字符串”; [label1 sizeToFit]; [self.view addSubview:label1]; // 追加長標簽 UILabel* label2 = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; label2.backgroundColor = [UIColor blueColor]; label2.textColor = [UIColor whiteColor]; label2.text = @”長ーーーーーーーーーー字符串”; [label2 sizeToFit]; CGPoint newPoint = label2.center; newPoint.y += 50; label2.center = newPoint; [self.view addSubview:label2];
如圖2-7所示是實例代碼執行的結果。

圖2-7 sizeToFit的執行結果
下面嘗試修改一下sizeToFit方法中的處理。那么在自定義的UIView子類中該如何改變sizeToFit方法的處理呢?默認是無法進行任何改變的。但是sizeToFit方法中調用的sizeThatFits方法是在UIView中定義的,我們可以通過重寫sizeThatFits方法來修改sizeToFit方法的處理。
我們嘗試編寫一個擁有兩個UILabel的DoubleLabel(UIView子類),當此DoubleLabel的sizeToFit方法被調用時,想讓兩個UILabel的位置向里收緊一點。下面是sizeThatFits方法的實現代碼。
// 此類為UIView的子類 // 其中包含了label1_與label2_兩個UILabel -(CGSize)sizeThatFits:(CGSize)size { CGFloat x1,x2,y1,y2; // 將label1_與label2_中延伸的一方左側的坐標設置成x1 if(label1_.frame.origin.x < label2_.frame.origin.x){ x1 = label1_.frame.origin.x; } else { x1 = label2_.frame.origin.x; } // 將label1_與label2_中延伸的一方右側的坐標設置成x2 if(label1_.frame.origin.x + label1_.frame.size.width > label2_.frame.origin.x + label2_.frame.size.width) { x2 = label1_.frame.origin.x + label1_.frame.size.width; } else { x2 = label2_.frame.origin.x + label2_.frame.size.width; } // 將label1_與label2_中向上延伸的一方左側的坐標設置成y1 if(label1_.frame.origin.y < label2_.frame.origin.y){ y1 = label1_.frame.origin.y; } else { y1 = label2_.frame.origin.y; } // 將label1_與label2_中向下延伸的一方右側的坐標設置成y2 if(label1_.frame.origin.y + label1_.frame.size.height > label2_.frame.origin.y + label2_.frame.size.height) { y2 = label1_.frame.origin.y + label1_.frame.size.height; } else { y2 = label2_.frame.origin.y + label2_.frame.size.height; } // 新尺寸的設置 size.width = x2 - x1; size.height = y2 - y1; return size; }
2.2.5 Affine變換(擴大、縮小、反轉、平移)
UIView中提供了對內容進行2次affine變換的功能。具體包括擴大、縮小、旋轉、反轉、平移等。進行affine變換時,要向UIView的transform屬性中設置CGAffineTransform的結構體(見表2-5)。圖2-8中顯示了此結構體的各個值在3×3 affine變換行列式中的具體位置。
表2-5 CGAffineTransform結構體

圖2-8 3×3 affine變換行列式
設置CGAffineTransform結構體的值時,需要有關affine變換行列式的知識。但是UIKit中同樣提供了不需要變換行列式的知識的相關方法。表2-6中就羅列了變形的種類與實現函數的列表。
表2-6 變形種類與CGAffineTransform函數對照表
將這些變形實際使用到UIImageView中的效果如圖2-9所示。

圖2-9 affine變換的使用效果
下面列舉一個將UIImageView旋轉90度的實例代碼。
imageView_.transform = CGAffineTransformMakeRotation(90 *(M_PI/ 180.0));
不僅可在UIImageView中使用,其他如UILabel及UIButton等UIView子類中都可以使用。