Search code examples
iosxcodeuiviewcontrollerswift-playgroundviewdidload

ViewController in Xcode Playground - frame reporting double sized (viewDidLoad)


I am using a UIViewController subclass in an Xcode Swift playground. The view of the controller is apparently reporting as double-sized. Am I doing something wrong or did I stumble into a bug?

When I place a yellow subview of half the width into the view, it's covering the entire width.

Xcode Version 8.2.1 (8C1002)

import UIKit
import PlaygroundSupport


class ViewController : UIViewController {
  override func viewDidLoad() {
    title = "Double Frame"
    super.viewDidLoad()
    view.frame // inspecting the frame size: 768 x 1024

    let halfV = UIView(frame: CGRect(x: 0, y: 200,
                                     width: Int(view.frame.width / 2),
                                     height: Int(view.frame.width / 2)))
    halfV.backgroundColor = UIColor.yellow
    view.addSubview(halfV)

  }
}
PlaygroundPage.current.liveView = UINavigationController(rootViewController: ViewController())

enter image description here


Solution

  • You view controller's view is going to be sized using auto layout. The auto layout pass is going to occur after viewDidLoad. If you want to programmatic size your subview by referencing the frame of your view controller's view, you should move that code to viewDidLayoutSubviews. For example:

    class ViewController : UIViewController {
        let halfV = UIView()
    
        override func viewDidLoad() {
            title = "Double Frame"
            super.viewDidLoad()
            view.frame // inspecting the frame size: 768 x 1024
    
    
            halfV.backgroundColor = UIColor.yellow
            view.addSubview(halfV)
        }
    
        override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
            halfV.frame = CGRect(x: 0, y: 200,
                   width: CGFloat(view.frame.width / 2),
                   height: CGFloat(view.frame.width / 2))
        }
    }
    PlaygroundPage.current.liveView = UINavigationController(rootViewController: ViewController())