iOS开发中的frame和bounds

,ios开发中有两个属性可以设置控件的坐标frame和bounds

  1. frame
    1. 以父视图的坐标系为参考系
    2. 定义了一个相对于父视图的容器
  2. bounds
    1. 以自身的坐标系为参考系
    2. 是控件的真实显示效果

既生瑜何生亮,也就是说平常我们开发中用到的都是frame,那么为什么还要有bounds呢,下面我们就看下frame和bounds的关系,到底谁说了算?

  1. frame大于bounds
    测试代码
UIView *view1 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
    view1.backgroundColor = [UIColor yellowColor];
    [view1 setBounds:CGRectMake(0, 0, 50, 50)];
    [self.view addSubview:view1];
    NSLog(@"view1 frame:%@  bounds:%@",NSStringFromCGRect(view1.frame),NSStringFromCGRect(view1.bounds));

运行结果
这里写图片描述
运行图片
这里写图片描述
分析:
1. frame从设置的{0,0,200,200}变成了{75,75,50,50}
2. bounds从设置的{0,0,50,50}还是{0,0,50,50}
3. 运行的效果证明最终的尺寸是bounds的尺寸,可是位置又是怎么回事呢
* 上面说到bounds时真实的显示效果,frame是相对于使徒的一个容器,结合这两句话来解释
* 因为bounds是最终显示的效果,所以最终大小是bounds的大小
* farme是相对于视图的容器,frame一开始的坐标是0,0,最后他根据bounds的大小调整了自己的大小之后,他会把上下左右平衡一下,所以x和y都会加上(200-50)/75的长度,最后的frame就变成了{75,75,50,50}

  1. frame小于bounds
    测试代码
    UIView *view1 = [[UIView alloc]initWithFrame:CGRectMake(0, 0,50, 50)];
    view1.backgroundColor = [UIColor yellowColor];
    [view1 setBounds:CGRectMake(0, 0, 150, 150)];
    [self.view addSubview:view1];
    NSLog(@"view1 frame:%@  bounds:%@",NSStringFromCGRect(view1.frame),NSStringFromCGRect(view1.bounds));

运行
这里写图片描述
运行效果
这里写图片描述
分析:
1. frame从{0,0,50,50}变成了{-50,-50,150,150}
2. bounds开始是{0,0,150,150},最终还是{0,0,150,150}
3. 结合上面分析的原因
* bounds负责真是的显示效果,所以bounds大小是{150,150},frame要是想要放的下bounds就要被撑到,所以大小也变成了{150,150}
* frame的大小变了,就会影响他的位置,长度和宽度分别增加了100,上下左右平衡一下,分别是50,因为frame是被撑大的,所以上面左右的值是从中心发散出去,x向左变小,一开始是0,再所以是-50,y向上变小,一开始是0,再变小就是-50
* 最终的显示效果就是上面那样了

综合分析
1. 从上面的结果可以看出,视图真正显示的大小的bounds的大小决定的
2. frame是决定他摆放的位置,frame的size会随着bounds进行收缩和扩张,进而会影响frame的横纵坐标进行调整(正常情况下,如果view发生旋转了,那么frame的size和bounds的size就不相等了)
3. 综上所述,bounds的大小会影响到frame

这是bounds对于自身显示效果的影响,那么父控件的bounds的改变对子控件有什么影响呢,看下面的


测试代码

UIView *view1 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
    view1.backgroundColor = [UIColor yellowColor];
    [view1 setBounds:CGRectMake(-50, -50, 200, 300)];
    [self.view addSubview:view1];
    UIView *view2 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
    view2.backgroundColor = [UIColor blueColor];
    [view1 addSubview:view2];
    NSLog(@"view1 frame:%@  bounds:%@",NSStringFromCGRect(view1.frame),NSStringFromCGRect(view1.bounds));
    NSLog(@"view2 frame:%@  bounds:%@",NSStringFromCGRect(view2.frame),NSStringFromCGRect(view2.bounds));

运行
这里写图片描述
运行截图
这里写图片描述
描述:一个view1的frame是{0,0,200,200},view2的frame也是{0,0,200,200},view2是加在view1上的,可是一般不是两个重合了吗,那么为什么会发生这样的情况
因为加了

  [view1 setBounds:CGRectMake(-50, -50, 200, 200)];

这一行代码,View1的bounds的改变影响了view2
的位置

分析
1. view2是view1 的子view,所以view2的frame是以view1的坐标系为参考系的
2. view1的本身的坐标系又是通过bounds设置的
3. view2相对于view1的x,y一开始都是0,当view1的坐标系的圆点变成了{-50,-50}
4. view2为了 相对于view1的frame的x,y的坐标不发生改变,所以x,y就变成了{50,50},这样就相对原来的还是0


根据以上的分析,我们发现了bounds的两个特点

  1. 对自身的影响,会影响自身frame的大小的变化,最后又引发frame的横纵坐标的改变
  2. 对子控件的影响,会影响子控件相对于自身的位置

有了上面的两个特点,我们能做什么呢
1. 对自身的影响:控制cell的拉伸
代码如下:自定义cell中像下面这样写

-(void)layoutSubviews{
    self.bounds = CGRectMake(self.bounds.origin.x,
                             self.bounds.origin.y,
                             self.bounds.size.width - 50,
                             self.bounds.size.height);

    [super layoutSubviews];

}

会发现cell由图1变成了图2(cell颜色是黄色)
图1
这里写图片描述

图2
这里写图片描述

当把cell的x变小,最终的效果也变了
2. 对子控件的影响:可以实现view的滚动,scrollerView就是这样做的
滚动scrollView打印bounds
这里写图片描述
bound的y不断变大,这样子控件为了和父控件位置相对不变,就会y就会不断减小,在坐标系中,越往下越大,越往上越小,这样子控件就会往上跑,最终时间view的滚动

猜你喜欢

转载自blog.csdn.net/li15809284891/article/details/77585121
今日推荐