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

要想深入的了解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)计算原理

推导

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

假定点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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值