The-view-s-frame-change-when-it-s-loaded

1. ViewController

有一个contentView紧贴着屏幕,如下图所示,那么,contentView的frame是如何变化的呢?

class ViewController: UIViewController {

    @IBOutlet weak var contentView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // #1
        debugPrint("viewDidLoad: ", self.contentView.frame)
    }

    override func viewWillAppear(_ animated: Bool) {
        // #2
        debugPrint("viewWillAppear: ", self.contentView.frame)
    }

    override func viewDidAppear(_ animated: Bool) {
        // #3
        debugPrint("viewDidAppear: ", self.contentView.frame)
    }

}

首先是iPhone 6的尺寸:

"viewDidLoad: " (0.0, 20.0, 375.0, 647.0)
"viewWillAppear: " (0.0, 20.0, 375.0, 647.0)
"viewDidAppear: " (0.0, 20.0, 375.0, 647.0)

都没有变化,因此这里有可能让初学者有误区,认为在viewDidLoad或者viewWillAppear中的就已经出现了最终的尺寸。

iPhone 6P:

"viewDidLoad: " (0.0, 20.0, 375.0, 647.0)
"viewWillAppear: " (0.0, 20.0, 375.0, 647.0)
"viewDidAppear: " (0.0, 20.0, 414.0, 716.0)

注意到viewDidAppear中出现的尺寸才是screen中的尺寸。如果在viewDidLoad或者viewWillAppear唤醒了xib中的view,那么需要注意到,在viewWillAppear中我们可能需重新设置最新的frame.

2. View

对于xib中的view来说,将其添加到ViewController中的view时,又是怎样的一个生命周期呢?

这里创建了一个自定义的view, 叫它CustomView

class CustomView: UIView {

    class func instanceFromNib() -> CustomView {
        return UINib(nibName: "View", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! CustomView
    }


    override init(frame: CGRect) {
        super.init(frame: frame)
        debugPrint("init: frame")
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        debugPrint("init: coder")
    }

    override func awakeFromNib() {
        debugPrint("awakeFromNib")
    }

    override func willMove(toSuperview newSuperview: UIView?) {
        debugPrint("willMove: toSuperview")
    }

    override func didMoveToSuperview() {
        debugPrint("didMoveToSuperview")
    }

    override func willMove(toWindow newWindow: UIWindow?) {
        debugPrint("willMove: toWindow")
    }

    override func didMoveToWindow() {
        debugPrint("didMoveToWindow")
    }
}

修改ViewController,

class ViewController: UIViewController {

    @IBOutlet weak var contentView: UIView!
    // New
    var customView: CustomView = CustomView.instanceFromNib()

    override func viewDidLoad() {
        super.viewDidLoad()
        debugPrint("viewDidLoad: ", self.contentView.frame)
        // New
        self.view.addSubview(self.customView)
    }

    override func viewWillAppear(_ animated: Bool) {
        debugPrint("viewWillAppear: ", self.contentView.frame)
    }

    override func viewDidAppear(_ animated: Bool) {
        debugPrint("viewDidAppear: ", self.contentView.frame)
    }

}

最后的出现顺序如下:

"init: coder"
"awakeFromNib"
# "viewDidLoad: " (0.0, 20.0, 375.0, 647.0)
"willMove: toSuperview"
"didMoveToSuperview"
# "viewWillAppear: " (0.0, 20.0, 375.0, 647.0)
"willMove: toWindow"
"didMoveToWindow"
# "viewDidAppear: " (0.0, 20.0, 414.0, 716.0)