iPhone UIKit详解
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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子类中都可以使用。