Lời mở đầu
Ở phần 3 chúng ta đã được làm quen với việc tạo constraints bằng code. Vậy nên bài viết này mình sẽ chia sẻ với các bạn về việc làm sao để tạo constraints bằng code dễ dàng hơn, tiết kiệm thời gian hơn. Và làm thế nào để debug UI.
- iOS/Auto Layout – Phần 1: Auto layout là gì?
- iOS/Auto Layout – Phần 2: Sử dụng “XCode/Interface Builder” sao cho hiệu quả?
- iOS/Auto Layout – Phần 3: Anatomy of a Constraint, cách để tạo constraints bằng code
- iOS/Auto Layout – Phần 6: Những trường hợp đặc biệt trong Auto Layout
- iOS/Auto Layout – Phần 7: UI Debugging
Sử dụng extension
Việc sử dụng extension để mở rộng các class giúp chúng ta có thể tạo constraint dễ dàng và tiết kiệm nhiều thời gian. Việc của các bạn là nghĩ và tạo ra các func có thể hay được sử dụng.
1. UIView
Ví dụ chung ta có thể tạo ra một func trong extension UIView giúp chúng ta tạo các constraints liên kết với SuperView như sau:
extension UIView {
/// Returns a collection of constraints to anchor the bounds of the current view to the given view.
///
/// - Parameter view: The view to anchor to.
/// - Returns: The layout constraints needed for this constraint.
func constraintsForAnchoringTo(boundsOf view: UIView) -> [NSLayoutConstraint] {
return [
topAnchor.constraint(equalTo: view.topAnchor),
leadingAnchor.constraint(equalTo: view.leadingAnchor),
view.bottomAnchor.constraint(equalTo: bottomAnchor),
view.trailingAnchor.constraint(equalTo: trailingAnchor)
]
}
}
Từ đây các bạn có thể tha hồ nghĩ thêm các func để giúp cho việc tạo constraints của mình trở nên đơn giản và tiết kiệm thời gian hơn nhiều so với việc hì hục ngồi code.
1.2 Xử lí ưu tiên
Khi bạn phải đặt độ ưu tiên cho các constraints của mình để tránh phá vỡ các constraint khác. Bạn có thể sẽ cần đến extension này:
extension NSLayoutConstraint {
/// Returns the constraint sender with the passed priority.
///
/// - Parameter priority: The priority to be set.
/// - Returns: The sended constraint adjusted with the new priority.
func usingPriority(_ priority: UILayoutPriority) -> NSLayoutConstraint {
self.priority = priority
return self
}
}
extension UILayoutPriority {
/// Creates a priority which is almost required, but not 100%.
static var almostRequired: UILayoutPriority {
return UILayoutPriority(rawValue: 999)
}
/// Creates a priority which is not required at all.
static var notRequired: UILayoutPriority {
return UILayoutPriority(rawValue: 0)
}
}
Độ ưu tiên của constraint là phần khá là hay ho, nên mình sẽ dành một mục ở bài viết tiếp theo.
1.3 Tạo Auto layout property wrapper
Khi auto layout bằng code, để tránh việc phải viết đi viết lại nhiều lần dòng code dưới đây:translatesAutoresizingMaskIntoConstraints = false
Chúng ta sẽ tạo ra Property Wrapper như dưới đây:
@propertyWrapper
public struct UsesAutoLayout<T: UIView> {
public var wrappedValue: T {
didSet {
wrappedValue.translatesAutoresizingMaskIntoConstraints = false
}
}
public init(wrappedValue: T) {
self.wrappedValue = wrappedValue
wrappedValue.translatesAutoresizingMaskIntoConstraints = false
}
}
final class MyViewController {
@UsesAutoLayout
var label = UILabel()
}
Lưu ý: Nó không sử dụng được cho biến Local
Giới thiệu về Snapkit
Nếu như các bạn lười nghĩ và viết các extension để hỗ trợ cho việc tạo constraint bằng code. Thì chúng ta lại có một giải pháp khác là dùng của thằng khác :D. Của ăn sẵn nhiều khi cũng tốt mà. Tiện đây mình xin giới thiệu với các bạn về thư viện Snapkit một thư việt rất mạnh về Auto layout bằng code. Giúp chúng ta xử lí Autolayout một cách đơn giản, gọn gàng và tiết kiệm khá nhiều thời gian.
Ưu điểm
– Code nhìn gọn gàng, dễ hiểu hơn
– Tiết kiệm thời gian khi code
Nhược điểm
– Sẽ có những thành viên không sử dụng snapkit mà dùng API default của apple dẫn đến thời gian đầu làm việc gặp khó khăn.
Cài đặt
CocoaPods, Carthage hoặc ném nó vào project của bạn.
Tham khảo link này nhé.
Cách sử dụng
1.Tạo constraint
func makeConstraintBySnapkit1() {
let iView = UIView()
let oView = UIView()
iView.backgroundColor = .red
oView.backgroundColor = .blue
view.addSubview(oView)
oView.addSubview(iView)
oView.snp.makeConstraints { (make) in
make.width.height.equalTo(200)
make.center.equalToSuperview()
}
iView.snp.makeConstraints { (make) in
make.top.leading.equalToSuperview().offset(20)
make.bottom.trailing.equalToSuperview().offset(-20)
}
}
Để tạo được constraint có kết quả như hình này bằng code sử dụng API mặc định của apple chúng ta sẽ phải viết khá nhiều dòng code.
2. Giữ reference của constraint và thay đổi nó giá trị của nó khi cần.
var myConstraint: Constraint?
iView.snp.makeConstraints { (make) in
self.myConstraint = make.top.leading.equalToSuperview().offset(20).constraint
make.bottom.trailing.equalToSuperview().offset(-20)
}
myConstraint?.update(offset: 40)
3. Update constraint
Update constraint giúp chúng ta update tùy ý bất kể 1 constraint nào đó của View.
Để update constraint ta chỉ cần viết như sau:
iView.snp.updateConstraints { (edit) in
edit.top.leading.equalToSuperview().offset(0)
}
Kết quả thu được sẽ là:
4. Remake constraint
Khác với updateContraint, remake constraint sẽ remove toàn bộ constraints cũ đi và bạn sẽ tạo lại constraint từ đầu như hàm makeConstraint.
Câu lênh của nó sẽ như sau:
iView.snp.remakeConstraints { (remake) in
remake.top.leading.equalToSuperview().offset(20)
remake.bottom.trailing.equalToSuperview()
}
Kết quả thu được
Để có thể thành thạo sử dụng Auto Layout và Snapkit chúng ta chỉ có 1 cách đó là làm nhiều, nhiều nữa và nhiều mãi thế thôi =)) Cố gắng lên anh em :))
Tổng kết
Mình hi vọng bài viết này sẽ giúp các bạn phần nào sử dụng Auto Layout dễ dàng và tiết kiệm thời gian hơn.
- iOS/Auto Layout – Phần 1: Auto layout là gì?
- iOS/Auto Layout – Phần 2: Sử dụng “XCode/Interface Builder” sao cho hiệu quả?
- iOS/Auto Layout – Phần 3: Anatomy of a Constraint, cách để tạo constraints bằng code
- iOS/Auto Layout – Phần 6: Những trường hợp đặc biệt trong Auto Layout
- iOS/Auto Layout – Phần 7: UI Debugging