Difference between Frame and Bounds in Swift
This is a question I have personally asked multiple times during my iOS development career. Today I will go over it, it is quite a simple answer, but there are some caveats to watch out for.
TLDR: Bounds refers to the views own coordinate system while Frame refers to the views parent coordinate system.
Let's start with the setup that I am using. I have placed a simple orange rectangle in the middle of the screen with Interface Builder and I have created an outlet for it called orangeView
.
The next thing that I have done is to create a printAll
method that will print the x
, y
, width
and height
of the orangeView
. This print all will print that information for both the frame
and the bounds
so that we can see how it gets affected.
Add the following code:
private func printAll() {
print("=========================")
print("X : ", self.orangeView.frame.origin.x)
print("Y : ", self.orangeView.frame.origin.y)
print("width : ", self.orangeView.frame.size.width)
print("height : ", self.orangeView.frame.size.height)
print("=========================")
print("X : ", self.orangeView.bounds.origin.x)
print("Y : ", self.orangeView.bounds.origin.y)
print("width : ", self.orangeView.bounds.size.width)
print("height : ", self.orangeView.bounds.size.height)
print("=========================")
}
If you call the above method from the viewDidLoad
you should see something similar, the width and height of your frame
and bounds
will probably be different to mine, your x
and y
of your views frame will most likely be different compared to mine too, the x
and y
of your bounds
should be the same as mine.
This is the output that I have when I run the project now:
=========================
X : 87.0
Y : 384.0
width : 240.0
height : 128.0
=========================
X : 0.0
Y : 0.0
width : 240.0
height : 128.0
=========================
As we can see the width
and height
of our frame
and bounds
are the same at the moment.
The next thing I want to do is rotate the orangeView
, create a border based on the frame
of the view and then we can get into the difference between frame
and bounds
.
I have added the below code just above where I called the printAll
method:
self.orangeView.transform = CGAffineTransform(rotationAngle: 5)
If you build and run you should see something similar to this:
The output will also have changed, my console output looks like this:
=========================
X : 111.58938416597198
Y : 314.7747071707769
width : 190.82123166805604
height : 266.45058565844624
=========================
X : 0.0
Y : 0.0
width : 240.0
height : 128.0
=========================
Add the following code between printAll
and self.orangeView.transform
:
let testView = UIView(frame: CGRect(x: self.orangeView.frame.origin.x,
y: self.orangeView.frame.origin.y,
width: self.orangeView.frame.size.width,
height: self.orangeView.frame.size.height))
testView.layer.borderColor = UIColor.red.cgColor
testView.layer.borderWidth = 2
self.view.addSubview(testView)
This will draw a red border based on the frame
's location and size. If you build and run the app again you should see something similar to the following:
Now that we have the project setup, we can take a look at what is happening. Let's start off with the bounds
.
In the picture above the bounds
would represent the orange rectangle. The bounds
of a view describes the views location
and size
in its own coordinate system.
This is what the Apple
documentation says:
The bounds rectangle, which describes the view’s location and size in its own coordinate system.
Even when rotate the x
, y
, width
and height
will stay the same. The same cannot be said for frame
.
The frame
has to do with where the view is situated(location) within the parent view, but also, something like a rotation will affect it too.
The frame rectangle, which describes the view’s location and size in its superview’s coordinate system.
Let's talk about the location of the frame. When using the frame
the x
and y
properties will represent where it is located within the parent view. If we rotate our view, the x
and y
coordinates will change.
If we don't start changing the view or rotating it etc, the width
and height
will be the same as the bounds
, but when we start doing things like rotation then it will all change.
You can think of the frame as a picture frame. The frame will be framing the view. So if we rotate the view, the frame will adjust its size in order to fit the rectangle, the same happens with the x
and y
coordinates. The frame will change because it try and wrap as tightly as possible around the view as you can see in the above image, the red border is perfectly sized to hold the orange rectangle.
Conclusion
bounds
refers to the views coordinate system while the frame
refers to the superviews coordinate system. Depending on the type of work that you are doing, this can have a big impact, but luckily it is something that should be quite obvious.
Full source code is available here.