Difference between frame.size.width and frame.width

9.4k views Asked by At

I was writing a program in swift and just now I noticed that I can directly access a CGRect frame's width and height properties directly without using the CGSize width and height. That is I am now able to write a code like this.

@IBOutlet var myView: UIView!

override func viewDidLoad()
{
    super.viewDidLoad()
    var height = myView.frame.height
    var height1 = myView.frame.size.height
}

In Objective C, when I tried to write the same code, the line height = view.frame.height is throwing an error. Can anyone please tell me the difference(if any) in these two lines of code.

3

There are 3 answers

2
Vinay Jain On BEST ANSWER

I just looked into the CGRect structure reference. In Swift there is an extension defined which have members height and width. Please have a look at the code below

struct CGRect {
var origin: CGPoint
var size: CGSize
}

extension CGRect {
    ...
    var width: CGFloat { get }
    var height: CGFloat { get }
    ...
}

So that you can directly fetch height and width values from a CGRect. As you can see these are only getters, so you will get an error if you try to set these values using view.frame.height = someValue

0
Silk Song On

frame is of CGRect structure, apart from its width and height have only getters, they can only be positive. From the documentation:

Regardless of whether the height is stored in the CGRect data structure as a positive or negative number, this function returns the height as if the rectangle were standardized. That is, the result is never a negative number.

However, size is of CGSize structure, from the documentation:

A CGSize structure is sometimes used to represent a distance vector, rather than a physical size. As a vector, its values can be negative. To normalize a CGRect structure so that its size is represented by positive values, call the standardized function.

So the difference is obvious.

0
Nikolai Ruhe On

In Objective C, when I tried to write the same code, the line height = view.frame.height is throwing an error. Can anyone please tell me the difference (if any) in these two lines of code.

CGGeometry.h defines a couple of types, among them the C struct CGRect. This struct has two members: origin and size.

That's all you can access in C (and Objective-C) using dot notation. Neither C nor Objective-C offer extensions for structs.

Swift imports the type as a Swift struct. The difference is that Swift does allow for extensions on structs. So it exposes several free C functions as extensions:

CGRectGetMinX() — CGRect.minX
CGRectGetMidX() — CGRect.midX
CGRectGetMaxX() — CGRect.maxX
CGRectGetWidth() — CGRect.width
[... same for y]

These C functions are there since ages—they just live in a dusty corner of CoreGraphics.

They are quite useful but you have to know their semantics (which differ a bit from the standard accessors): They normalise the dimensions.

This means that they convert a rect with negative width or height to a rect that covers the same area with positive size and offset origin.

let rect = CGRect(x: 0, y: 0, width: 10, height: -10)
assert(rect.width == rect.size.width)   // OK
assert(rect.height == rect.size.height) // boom