Autolayout Priority

Mình thấy rất nhiều bạn bị hổng kiến thức rất nhiều về autolayout, đặc biệt là phần Autolayout priority. Nay có thời gian rảnh thì mình sẽ viết về đề tài này để các bạn nắm được để giải quyết các vấn đề liên quan tới UI của App iOS. Chúng ta cùng bắt đầu!

Constraint priority

Constraint priority là độ ưu tiên của constraint. Dùng để autolayout engine có thể giải quyết các xung đột xảy ra khi thực hiện layout giao diện.

Giả xử chúng ta phải tạo ra một giao diện như thế này. Có giao diện tab để chuyển đổi hiển thị giữa Content1Content2. 2 phần content này có chiều cao khác nhau. Bên dưới có 2 chức năng là OKCancel. Nhiệm vụ của chúng ta là layout làm sao khi chuyển tab thì phần content bên trong vừa khít với view cha là Contents.

Chúng ta để ý, Content1Content2 đều có bottom constraint với view cha. Trong Content1Content2 có label có thể tự xác định chiều cao của content. Chúng ta sẽ dùng priority để xác định Content1 hoặc Content2 sẽ quyết định chiều cao của view Contents.

Chúng ta sẽ thực hiện thay đổi priority bằng code khi chuyển tab.

@interface ViewController ()
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *content1BottomConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *content2BottomConstraint;
@property (weak, nonatomic) IBOutlet UIView *content1View;
@property (weak, nonatomic) IBOutlet UIView *content2View;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self tap1DidTap:nil];
    // Do any additional setup after loading the view.
}
- (IBAction)tap1DidTap:(id)sender {
    self.content1BottomConstraint.priority = 999;
    self.content2BottomConstraint.priority = 222;
    self.content1View.hidden = NO;
    self.content2View.hidden = YES;
}
- (IBAction)tap2DidTap:(id)sender {
    self.content2BottomConstraint.priority = 999;
    self.content1BottomConstraint.priority = 222;
    self.content2View.hidden = NO;
    self.content1View.hidden = YES;
}
@end
Và đây là kết quả

Lưu ý: Chỉ thay đổi priority khi constraint chưa được add. Nếu chúng ta thay đổi priority trong trường hợp trên thì phải để priority ở storyboard/xib khác 1000.

Example: https://github.com/ThanhDev2703/DemoAutolayoutPriority

Intrinsic content size

Intrinsic content size là kích thước tự nhiên của view đó, được xác định bằng chính nó hoặc subview của nó. Lấy ví dụ UILabel, UIButton, UITextView luôn có giá trị Intrinsic content size bằng kích thước của text và image (đối với UIButton) của nó.

Content hugging priority

Content hugging priority là độ ưu tiên quyết định tới việc giới hạn kích thước của view không lớn hơn intrinsic content size. Các bạn có thể hiểu là Content hugging priority là độ ưu tiên quyết định view không bị dãn ra.

Ví dụ chúng ta có custom cell có chiều cao động.

TitlesubTitle được layout cho nhau, autolayout engine không thể quyết định label nào sẽ có kích thước bằng intrinsic content size nên phải dựa vào Content hugging priority để quyết định. Trong trường hợp này ta sẽ set Content hugging priority của Title lớn hơn của SubTitle.

Note: Mặc định giá trị Content hugging priority là 250 (UILabel là 251) cho cả 2 chiều (chiều ngang và dọc)

Content compression resistance priority

Content compression resistance priority là độ ưu tiên quyết định tới việc kích thước của view không nhỏ hơn intrinsic content size. Hay có thể hiểu là nó là độ ưu tiên quyết định view không bị co vào.

Ví dụ chúng ta có một button để chuyển màn hình search và một button đang hiển thị tên tỉnh thành.

2 button đó đều có text rất dài, không thằng nào chịu nhường.

Trong trường hợp này chúng ta phải giải quyết thằng cách thay đổi Content compressing resistence priority. Ở trường hợp này tôi muốn button chuyển màn search hiển thị hết content nên tôi cho Content compressing resistence priority của nó cao hơn. Và vậy thì content của thằng button hiển thị city sẽ bị co lại.

Ngon rồi ?

Note: Mặc định giá trị Content compressing resistence priority là 750 cho cả 2 chiều (chiều ngang và dọc)

Tổng kết

Qua bài này chắc các bạn cũng hiểu thêm về Autolayout priority rồi nhỉ. Chúc các bạn may mắn ?.

Tham khảo:
https://medium.com/@abhimuralidharan/ios-content-hugging-and-content-compression-resistance-priorities-476fb5828ef
https://krakendev.io/blog/autolayout-magic-like-harry-potter-but-real

Leave a Reply