Auto Layout: Programmatic Constraints - BNR

  繼續Auto Layout - BNR篇。html

打開BNRDetailViewController.m文件,重載viewDidLoad方法來建立UIImageView對象。當你想要給經過加載NIB文件建立的視圖層級添加約束時,須要重載viewDidLoad方法。以下:spa

1 - (void)viewDidLoad {
2     [super viewDidLoad];
3     
4     UIImageView *iv = [[UIImageView alloc] initWithImage:nil];
5     iv.contentMode = UIViewContentModeScaleAspectFill;
6     iv.translatesAutoresizingMaskIntoConstraints = NO;
7     [self.view addSubview:iv];
8     self.imageVeiw = iv;
9 }

  每一個視圖都有一個 translatesAutoresizingMaskIntoConstraints 屬性,默認爲YES,即iOS會自動建立一些約束來匹配視圖自動調整。code

  Apple推薦使用Visual Format Language(VFL)來程序化建立約束。orm


 

VFL:一種用字符串常量來描述約束的方式。htm

   @"H:|-0-[imageView|-0-" ,其中H:指該約束是針對水平位置的。方括號內的imageView指要約束的視圖。符號|表示視圖的容器。此字符串表示:imageView離其容器左右邊緣的距離爲0點。同時,可簡化爲: @"H:|[imageView|" 對象

   @"V:[dateLabel]-8-[imageView]-8-[tooBar]" ,其指imageView的頂部離dateLabel的距離爲8點,imageView的底部離tooBar的距離爲8點。可簡化爲: @"V:[dateLabel]-[imageView]-[tooBar]" blog

   @"V:[someView(==50)]" ,指視圖的高度約束爲50點。ip


 

  一個約束即NSLayoutConstraint類的對象,可將其添加到一個視圖中。字符串

修改viewDidLoad方法,建立imageView水平和垂直方向的約束。以下:get

 1 - (void)viewDidLoad {
 2     [super viewDidLoad];
 3     
 4     UIImageView *iv = [[UIImageView alloc] initWithImage:nil];
 5     iv.contentMode = UIViewContentModeScaleAspectFill;
 6     iv.translatesAutoresizingMaskIntoConstraints = NO;
 7     [self.view addSubview:iv];
 8     self.imageVeiw = iv;
 9     
10     NSDictionary *nameMap = @{@"imageVeiw":self.imageVeiw, @"dateLabel":self.dateLabel, @"toolBar":self.toolBar};
11     NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[imageVeiw]-0-|"
12                                                                              options:0
13  metrics:nil
14  views:nameMap];
15     NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[dateLabel]-[imageVeiw]-[toolBar]"
16                                                                            options:0
17                                                                            metrics:nil
18                                                                              views:nameMap];
19 }

NSLayoutConstraint的類方法constraintsWithVisualFormat:options:metrics:views的第四個參數爲:視覺格式化字符串中的名字與視圖層級中的名字的映射。


 

添加約束的規則:

1)若是一個約束影響了兩個具備相同父視圖的view,則約束應添加到父視圖中。

2)若是一個約束隻影響到一個視圖,該約束應添加到其所影響的視圖中。

3)若是一個約束影響了兩個不具備相同父視圖的view,但共享一個ancestor,則該ancestor得到該約束。

4)若是一個約束影響一個視圖和其父視圖,則該約束添加到父視圖中。

  所以,在viewDidLoad方法中,將建立的約束添加到父視圖中,添加以下粗體代碼:

1     NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[dateLabel]-[imageView]-[toolBar]"
2                                                                            options:0
3                                                                            metrics:nil
4                                                                              views:nameMap];
5  [self.view addConstraints:horizontalConstraints]; 6     [self.view addConstraints:verticalConstraints];

  Intrinsic Content Size:指一個視圖的大小基於其要顯示的內容。

 contentCompressionResistancePriority 當其值小於1000時,Auto Layout可能壓縮視圖。

 contentHuggingPriority 當其值小於1000時,Auto Layout可能增長視圖的大小。

viewDidLoad方法添加代碼以下:

1     ......
2     self.imageVeiw = iv;
3     
4     [self.imageVeiw setContentHuggingPriority:200 forAxis:UILayoutConstraintAxisVertical]; 5     [self.imageVeiw setContentCompressionResistancePriority:700 forAxis:UILayoutConstraintAxisVertical]; 6     ......

建立基於比率的約束時,不能使用VFL,此時須要用到NSLayoutConstraint類的 constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant: 類方法。其中multiplier屬性是建立基於比率約束的關鍵。

1 NSLayoutConstraint *aspectConstraint = [NSLayoutConstraint constraintWithItem:self.imageVeiw
2                                                                         attribute:NSLayoutAttributeWidth
3                                                                         relatedBy:NSLayoutRelationEqual
4                                                                            toItem:self.imageVeiw
5                                                                         attribute:NSLayoutAttributeHeight
6                                                                        multiplier:1.5
7                                                                          constant:0.0];

添加的約束至關於 imageVeiw.width = 1.5 * imageVeiw.height + 0.0 。


  autoresizing masks:約束一個視圖和其父視圖的關係,但不會影響同級視圖間的關係。默認狀況下,會基於autoresizing masks,給視圖建立和添加約束。但其常常會與用程序代碼添加的約束髮生衝突。此時,只需將視圖的 translatesAutoresizingMaskIntoConstraints 屬性設爲NO便可。

相關文章
相關標籤/搜索