Search code examples
iosswiftcocoa-touchcgrect

What's the difference between UIView's frame.height and frame.size.height?


I don't understand what the difference is in a UIView between frame.height and frame.size.height. Why add size? For example:

override func viewDidLoad() {
    super.viewDidLoad()

    scrollView.contentSize.height = self.view.frame.height
    scrollViewHeight = scrollView.frame.size.height
}

Solution

  • It all started with Objective-C and CGRect. It only has two properties - origin and size. size is a CGSize which in turn has a height property. So it is common in Objective-C to get the height of a frame using:

    CGFloat height = frame.size.height;
    

    Technically, the correct solution (to get a proper, normalized height) is to use:

    CGFloat height = CGRectGetHeight(frame);
    

    Then Swift came along and CGRect became a Swift struct. While it also has a size property of type CGSize which in turn has a height property, the Swift CGRect has a height property. In Swift, the two lines above become:

    let height = frame.size.height;
    

    and

    let height = frame.height;
    

    In most cases, there is no difference between the two ways to get the height of a frame. But there is a difference if the frame has a negative height.

    Example:

    let rect = CGRect(x: 0, y: 0, width: 320, height: -40)
    print(rect.height) // 40
    print(rect.size.height) // -40
    

    Accessing size.height gives the raw value used when the CGRect was created. Access height gives a normalized value of the height.

    In most cases you should use the height property and not size.height. But more importantly, be consistent. The code in your question is inconsistent.