您的位置:首页 > 产品设计 > UI/UE

[IOS]今天开始学UI---UIIView的transform和contentMode属性

2015-08-05 21:47 489 查看
要想深入的了解UIView的transform属性

就必须要知道该属性的类型

点开头文件 我们可以看到

struct CGAffineTransform {
CGFloat a, b, c, d;
CGFloat tx, ty;
}


该属性类型为结构体

里面共封装了六个参数,我们将依次讲解该六个属性,这六个属性其实可以分为3对属性(a,d) (b,c) (tx,ty)

ad缩放bc旋转tx,ty位移

我们可以对2d图片进行 缩放,旋转,平移 通过该六个 参数进行设置

假设坐标系内一点(x,y)经过如下图的变换之后得到新的(X,Y)

公式

X=ax+cy+tx

Y=bx+dy+ty
也许你看不懂上面的公式 但是我会接下去慢慢讲解
1.当a = m ,d = n, b = c = 0, tx = ty =0;的时候 (m,n)代表任意常数

我们得到新的(X,Y)是什么 (ax,dy) 那这代表什么? 对 就是缩放 x 缩放成原来的a倍 y缩放成原来的d倍

CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)计算原理

2.当a=cosɵ,b=sinɵ,c=-sinɵ,d=cosɵ,tx=ty=0;的时候e 代表角度

X= x cos e - y sin e

Y= x sin e + y cos e

那么这个新坐标代表了什么呢?代表了点(x,y)经过依照原点(0,0)进行旋转 e 角度后变换后的新 (X,Y)

CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle)计算原理


推导

旋转变换一般是按照某个圆心点,以一定半径 r 旋转一定的角度
α
,为了简单起见我们给出下面的情景

假定点A(x,y)想经过旋转变换到达B(x',y'),已知旋转角度
α
和点A坐标,计算出点B



要计算点B则分别计算他的x'和y'分量



3.当a = d = 1, b = c = 0.tx = m, ty = n;的时候
X= x + m
Y = y + n
这代表什么? 简单的说就是x平移了 m,y平移了 n
CGAffineTransform CGAffineMakeTranslation(CGFloat tx,CGFloat ty)计算原理

如果要综合起来进行变换(缩放,旋转,平移)我们也就得到了
CGAffineTransform CGAffineTransformMake (CGFloat
a,CGFloat b,CGFloat c,CGFloat d,CGFloat tx,CGFloat ty);

讲的再多不如做的 我们动手实验一下

实验1:缩放

新建了两个不同背景色的UIView 镜像开局 唯一不同的就是其中一个x 缩放了 1.5倍 y缩放了1.5倍 缩放是以自身view的中心center缩放的

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];

UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];

view1.backgroundColor = [UIColor redColor];
view2.backgroundColor = [UIColor greenColor];

view1.alpha = 0.5;
view2.alpha = 0.5;

view1.transform = CGAffineTransformMakeScale(1.5, 1.5);

[self.view addSubview:view1];
[self.view addSubview:view2];

}


最后得到的结果



实验2:旋转 默认是顺时针旋转

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];

UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];

view1.backgroundColor = [UIColor redColor];
view2.backgroundColor = [UIColor greenColor];

view1.alpha = 0.8;
view2.alpha = 0.8;

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
label.center = CGPointMake(100, 100);
[label setText:@"Hello World"];
[label setTextAlignment:NSTextAlignmentCenter];
[view1 addSubview:label];
view1.transform = CGAffineTransformMakeRotation(M_PI_4);

[self.view addSubview:view2];
[self.view addSubview:view1];

}


最后得到的结果

同样镜像开局 加入UILabel只是为了看清楚旋转方向



看起来是非常的成功

实验3:平移

x+100,y+100

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];

UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];

view1.backgroundColor = [UIColor redColor];
view2.backgroundColor = [UIColor greenColor];

view1.alpha = 0.8;
view2.alpha = 0.8;

view1.transform = CGAffineTransformMakeTranslation(100, 100);

[self.view addSubview:view2];
[self.view addSubview:view1];

}
结果上来看还是非常成功的



需要特别注意的是 以上三种方法 都是以 起始的center作为参考的

什么意思呢?就是说 哪怕以后再进行重复的变换并不会改变

view1.transform = CGAffineTransformMakeRotation(M_PI_4);

我们都知道 这是对当前的UIView顺时针旋转M_PI/4的角度

假如连续执行两遍并不会转M_PI_2的角度

很多时候我们进行连续变换的时候都需要根据上次的进行变换 而不是以起始点作为参照

这不用担心 本身提供的API提供给我们直接的方法进行调用

CGAffineTransform CGAffineTransformScale(CGAffineTransform t, CGFloat sx,CGFloat
sy)

CGAffineTransform CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)

CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t,CGFloat tx,CGFloat
ty)
这个方法去掉了Make字母 同时添加了一个新的参数CGAffineTransform t
该参数代表了上次进行转换的状态
如果要连续进行三次旋转M_PI/4角度 很简单
咱们直接上代码 不废话

- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];

UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];

view1.backgroundColor = [UIColor redColor];
view2.backgroundColor = [UIColor greenColor];

view1.alpha = 0.8;
view2.alpha = 0.8;

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
label.center = CGPointMake(100, 100);
[label setText:@"Hello World"];
[label setTextAlignment:NSTextAlignmentCenter];
[view1 addSubview:label];
view1.transform = CGAffineTransformMakeRotation(M_PI_4);
view1.transform = CGAffineTransformRotate(view1.transform, M_PI_4);
view1.transform = CGAffineTransformRotate(view1.transform, M_PI_4);

[self.view addSubview:view2];
[self.view addSubview:view1];


结果确实旋转了M_PI/4*3的角度



是不是觉得很有意思呢?

接下来我们来点轻松的UIView的contentMode属性
同样头文件是我们最好的导师
我们去扒扒看

typedef NS_ENUM(NSInteger, UIViewContentMode) {
UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit,      // contents scaled to fit with fixed aspect. remainder is transparent
UIViewContentModeScaleAspectFill,     // contents scaled to fill with fixed aspect. some portion of content may be clipped.
UIViewContentModeRedraw,              // redraw on bounds change (calls -setNeedsDisplay)
UIViewContentModeCenter,              // contents remain same size. positioned adjusted.
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,
};


看来头文件描述不全面啊?所以我们还是去看官方文档里面到底怎么描述这些枚举量的

1.UIViewContentModeScaleToFill:将内容按照本View的长宽比进行缩放
比如一张图片 200x200 我们要放进100x150的UIImageView里面去
嗯 200x0.5= 100 200x0.75=150
所以我们看到的图片是这样的



这里面我放两个UIImageView 下面的是200x200的状态下的显示 而上层则是100x150 看样子是填充满了的说

2.UIViewContentModeScaleAspectFit:图片保持原比例 200x200的放进 100x150 最后变成100x100 那么剩下的位置怎么办 透明
所以就得到下图 注意红色方框



3.UIViewContentModeScaleAspectFill:图片保持比例填充满 部分内容可能被截断以填充视图的边界。
到底是啥呢?实际上两个红块区域就是被裁减部分 但是被裁减部分 仍然显示在边界处



4.UIViewContentModeRedraw:这个我也不太明白? 貌似意思是当视图改变时 重绘?
5.UIViewContentModeCenter:就是图片的中心在该View的中心 但是超出部分 照常存在 就是这么任性



6.UIViewContentModeTop:上边对其 但是超出部分 管我啥事呢?
红色 原本View的bounds 蓝色参照View 的bounds



7.UIViewContentModeBottom下边对齐 效果类比上可得

8.UIViewContentModeLeft 左边对齐

9.UIViewContentModeRight 右边对齐
10.UIViewContentModeTopLeft 左上角对齐
11.UIViewContentModeTopRight 右上角对齐
12.UIViewContentModeBottomLeft 左下角对齐

13.UIViewContentModeBottomRight 右下角对齐

施工完毕
that's all
thx

Everything you see on Screen is UIView.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: