CocoaTouch: Frame and Bounds
One of the most important part in App Development are user interfaces. Our job is to create an outstanding user experience to stand out against other apps. But let us dive into the basics first.
When it comes to UI Components we have to think about two things:
- How big is my element?
- Where should it be placed?
How big is my element?
You have to think about the width and the height of your UI element. Core Graphics provides a struct for this use-case.
struct CGSize {
CGFloat width;
CGFloat height;
};
Where should it be placed?
UI elements are positioned using a coordinate system. This begins (in iOS) at the top-left point of the screen. Specify the location with the CGPoint struct.
struct CGPoint {
CGFloat x;
CGFloat y;
};
Both in together
Now we have the size and position. These two in combination form a “rectangle”. There is also a struct which contains both information and it’s called CGRect.
struct CGRect {
CGPoint origin;
CGSize size;
};
Taking a closer look at the source, we will see that the rectangle is a structure that contains the already known ones (CGSize and CGPoint).
Frame
Let’s create a new UIView. Specify the rectangle (the size and the position) as CGRect and pass it as parameter to the constructor.
let rect = CGRect(x: 70, y: 70, width: 160, height: 100)
let myView = UIView(frame: rect)
Our View will be placed at 70 points away from the left side and also 70 points from the top of the superview. It will be 160 points width and has a hight of 100 points.
The position we just specified is relative to its superviews coordinate system. If you have a simple View Controller, this will be the whole screen. If you add the rect to an Table Cell for example, the superview will be the cell; so it will be placed relative to the cells coordinate system.
This values (the position and the size) are stored in the frame attribute. This is actually what happens when you’re creating a UIView instance. It’s the frame your stuff gets drawn into.
Bounds
When drawing into a frame sometimes things won’t match the frame exactly.
So there’s another attribute that seems pretty similar at first sight. It specifies the bounds of the view. It’s relative to its own coordinate system. That means the X and Y value is typically 0/0 if not other specified. In this simple case the width and height are similar because the frame is fully filled out.
The values vary when we rotate the view for example. The red displayed area is the frame our rectangle gets drawn in. Because it is rotated the frame area is wider and higher than the actual filled view.
When to use what?
You have to specify the frame when you define a UIView (manually). But when it comes to working with existing UIViews it’s mostly better to use the bounds.
Imagine the yellow colored rectangle is a image and in the left bottom corner we want a text. If you refer the frame attribute it will be exactly drawn in the bottom left corner. And it would work well in the first example. However when it comes to the rotated example the text would be outside the image.