Autolayout và lifecycle trong IOS
Autolayout và lifecycle trong IOS 1. Lý thuyết: Trước hết, mình xin nói về một vài life-cycle trong swift để mọi người nhớ lại. Một câu hỏi phổ biến là khi nào ghi override viewDidLayoutSubviews, viewDidLoad và viewWillAppear. a. viewDidLoad: viewDidLoad được gọi sau khi View ...
Autolayout và lifecycle trong IOS
1. Lý thuyết:
Trước hết, mình xin nói về một vài life-cycle trong swift để mọi người nhớ lại. Một câu hỏi phổ biến là khi nào ghi override viewDidLayoutSubviews, viewDidLoad và viewWillAppear.
a. viewDidLoad:
- viewDidLoad được gọi sau khi View Controller đã load cấu trúc cơ bản (hierarchy) vào bộ nhớ từ XIB hay Storyboard
- khi phần viewDidLoad được gọi, bạn hiểu là các IBOutlet, IBAction đã được kết nối, ngoài ra view chưa được vẽ trong lúc này
- viewDidLoad sẽ không được gọi lại một khi đã load lên và add vào trong 1 navigation stack.
- viewDidLoad được dùng để configure những gì mà bạn không configure trong XIB hoặc trong Storyboard.
b. viewWillAppear:
- viewWillAppear được gọi để báo rằng viewController đã sẵn sàng cho việc hiển thị lên màn hình.
- override method khi bạn muốn setup những func mà bạn muốn VC thực hiện mỗi lần nó hiển thị, ví dụ như là deselected row v..v
c. viewDidLayoutSubviews:
- Khi thay đổi bounds (ví dụ như thay đổi kích cỡ simulator hay xoay dọc/ ngang), method này sẽ được gọi sau khi có tín hiệu báo là vị trí (position) và kích cỡ (size) của subviews đã thay đổi.
- Đây là nơi mà ta sẽ setup layout lại cho subviews, trước khi nó xuất hiện trên màn hình
- Bất cứ điều gì phụ thuộc vào bounds cần được thực hiện ở viewDidLayoutSubviews
- Bởi vì frame và bounds của 1 view sẽ không được finalized cho đến khi AutoLayout làm xong hết việc layout cho view và subviews.
d. Tổng kết
Tóm lại: Quy trình như sau:
- Nó sẽ tạo ra các connections
- Nó tô màu, tạo các tính chất cho UI
- Autolayout các UI
- Check thử các bounds có bị khác so với khi thiết kế không, nếu có thì co giãn theo design
2. Tình huống thực tế:
a. Tình huống 1:
Giả sử mình có 1 button. Width/ Height = 50 trên Regular, và 25 trên Compact. Sẽ dùng code để cho Button thành hình tròn.
Mình đi theo 2 bước:
- Autolayout trên storyboard
- Code thành hình tròn:
func configureButton()
{
editButton.layer.cornerRadius = 0.5 * editButton.bounds.size.awidth
editButton.layer.borderWidth = 2.0
editButton.clipsToBounds = true
}
Func này chỉ được gọi 1 khi mà bounds của button được biết. Nếu để func này ở viewDidLoad hay viewWillAppear thì sẽ không hiển thị hình tròn mà chỉ có awidth height được design. Vì code đã được gọi trước khi bounds được set. Chỉ khi để func trong viewDidLayoutSubViews()
b. Tính huống 2:
Khi sử dụng CollectionView, mình thường có các func điều chỉnh Edge để tránh các tính trạng Padding Bottom hay Padding Top.
Nếu đặt func trong các viewDidLoad hay viewWillAppear thì nó sẽ được apply/ work đúng trên các màn hình lớn hơn màn hình thiết kế. Khi đưa xuống các màn hình nhỏ hơn nó sẽ bị sai lệch đi. Với các lý do đã phân tích ở trên, ta nên để các func điểu chỉnh liên quan đến Edge, Bounds ở viewDidLayoutSubViews().
Nguồn:
http://www.iosinsight.com/override-viewdidlayoutsubviews/
https://stackoverflow.com/questions/36125101/when-the-autolayout-constraints-set-frames-during-view-controller-life-cycle
https://iosprogrammingknowledge.blogspot.com/2016/03/van-e-autolayout-chua-uoc-load-o.html