Demo

We can think of a frame as a rect floating on the bounds.

Frame: takes the parent View as the coordinate system bounds: takes itself as the coordinate system

Look at the following example:

  1. The most common code:

     func test1() {
         let view1 = UIView()
         view1.backgroundColor = .red
         view1.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
         view.addSubview(view1)
         
         let view2 = UIView()
         view2.backgroundColor = .blue
         view2.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
         view1.addSubview(view2)
         
         print(view1.frame, view1.bounds, view2.bounds, view2.frame, view2.center, view1.center)
     }
     
    Copy the code

Here we create two views, view1 is a subview of View2. The layout is exactly what we expected.

Then comes the magic point. Look at the following code:

  1. Modify the bounds of view1:

    Func test2() {// Change the origin of bounds to (20, 20), so that the original origin is offset to the upper right corner relative to the current origin. let view1 = UIView() view1.backgroundColor = .red view1.frame = CGRect(x: 100, y: 250, width: 100, height: 100) view1.bounds = CGRect(x: 20, y: 20, width: 100, height: 100) view.addSubview(view1) let view2 = UIView() view2.backgroundColor = .blue view2.frame = CGRect(x: 0, y: 0, width: 50, height: 50) view1.addSubview(view2) print(view1.frame, view1.bounds, view2.bounds, view2.frame, view2.center, view1.center) }Copy the code

In this case, the origin of view2 is shifted (20, 20) to the upper right corner. Why is it shifted to the upper right corner? That’s what I understand. Because view2 is set to view1, view2 is set to 0,0 as the origin of view1’s bounds when the bounds of view1 are moved down, so view2 is set to the upper right corner. I know it’s a little convoluted, but that’s how it’s supposed to be explained. There is a better way to explain, welcome to communicate.

  1. Transform view1 and enlarge it by 2 times

     func test3() {
         
         let view1 = UIView()
         view1.backgroundColor = .red
         view1.frame = CGRect(x: 100, y: 400, width: 100, height: 100)
         view1.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
         view.addSubview(view1)
         
         let view2 = UIView()
         view2.backgroundColor = .blue
         view2.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
         view1.addSubview(view2)
         
         view1.transform = view1.transform.scaledBy(x: 2, y: 2)
         
         print(view1.frame, view1.bounds, view2.bounds, view2.frame, view2.center, view1.center)
         
     }
     
    Copy the code

After execution, frame changes to (50.0, 350.0, 200.0, 200.0), bounds unchanged. There are situations where the size of bounds and frame do not want to wait.