轉自:http://www.cnblogs.com/wqcoder/p/5511434.html
簡要
自動布局最重要的是約束:UI元素間關係的數學運算式。約束包括尺寸、由優先順序和閾值管理的相對位置。它們是添加劑,可能導致約束衝突 、約束不足造成布局無法確定 。這兩種情況都會產生異常。 使用前:AutoLayout關於更新的幾個方法的區別 setNeedsLayout:告知頁面需要更新,但是不會立刻開始更新。執行後會立刻調用layoutSubviews。 layoutIfNeeded:告知頁面配置立刻更新。所以一般都會和setNeedsLayout一起使用。如果希望立刻產生新的frame需要調用此方法,利用這點一般布局動畫可以在更新布局後直接使用這個方法讓動畫生效。 layoutSubviews:系統重寫布局 setNeedsUpdateConstraints:告知需要更新約束,但是不會立刻開始 updateConstraintsIfNeeded:告知立刻更新約束 updateConstraints:系統更新約束 使用
1. 基本使用 mas_makeConstraints:添加約束 mas_updateConstraints:更新約束、亦可添加新約束
mas_remakeConstraints:重設之前的約束
multipler屬性工作表示約束值為約束對象的乘因數, dividedBy屬性工作表示約束值為約束對象的除因數,可用於設定view的寬高比
// 進行螢幕的適配的時候,往往需要根據螢幕寬度來適配一個相應的高度,在此推薦使用如下約束的方式來進行控制項的適配[self.topView addSubview:self.topInnerView];[self.topInnerView mas_makeConstraints:^(MASConstraintMaker *make) { make.height.equalTo(self.topView.mas_height).dividedBy(3); make.width.and.height.lessThanOrEqualTo(self.topView); make.width.and.height.equalTo(self.topView).with.priorityLow(); make.center.equalTo(self.topView);}]; priorityLow()設定約束優先順序 #define MAS_SHORTHAND_GLOBALS使用全域宏定義,可以使equalTo等效於mas_equalTo #define MAS_SHORTHAND使用全域宏定義, 可以在調用masonry方法的時候不使用mas_首碼
// 這裡注意到一個地方,就是當使用了這個全域宏定義之後,發現可以有個類`NSArray+MASAdditions.h`,看了之後發現可以self.buttonViews = @[ raiseButton, lowerButton, centerButton ];// 之後可以在updateConstraints 方法中- (void)updateConstraints { [self.buttonViews updateConstraints:^(MASConstraintMaker *make) { make.baseline.equalTo(self.mas_centerY).with.offset(self.offset); }]; [super updateConstraints]; } 動態修改視圖約束:
// 建立視圖約束[blueView mas_makeConstraints:^(MASConstraintMaker *make) { self.animatableConstraint = make.edges.equalTo(superview).insets(paddingInsets).priorityLow();]];// 更改約束 (另一處方法中)UIEdgeInsets paddingInsets = UIEdgeInsetsMake(padding, padding, padding, padding);self.animatableConstraint.insets = paddingInsets;[self layoutIfNeeded]; debug模式:
// 對某個view添加key值greenView.mas_key = @"greenView";// 或者如下順序MASAttachKeys(greenView, redView, blueView, superview);// 同樣的對每條約束亦可以添加keymake.height.greaterThanOrEqualTo(@5000).key(@"ConstantConstraint");
preferredMaxLayoutWidth: 多行label的約束問題
// 已經確認好了位置// 在layoutSubviews中確認label的preferredMaxLayoutWidth值- (void)layoutSubviews { [super layoutSubviews]; // 你必須在 [super layoutSubviews] 調用之後,longLabel的frame有值之後設定preferredMaxLayoutWidth self.longLabel.preferredMaxLayoutWidth = self.frame.size.width-100; // 設定preferredLayoutWidth後,需要重新布局 [super layoutSubviews];} scrollView使用約束的問題:原理通過一個contentView來約束scrollView的contentSize大小,也就是說以子控制項的約束條件,來控制父視圖的大小
// 1. 控制scrollView大小(顯示地區)[self.scrollView makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view);}];// 2. 添加一個contentView到scrollView,並且添加好約束條件[contentView makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.scrollView); // 注意到此處的寬度約束條件,這個寬度的約束條件是比添加項 make.width.equalTo(self.scrollView);}];// 3. 對contentView的子控制項做好約束,達到可以控制contentView的大小 新方法:2個或2個以上的控制項等間隔排序
/** * 多個控制項固定間隔的等間隔排列,變化的是控制項的長度或者寬度值 * * @param axisType 軸線方向 * @param fixedSpacing 間隔大小 * @param leadSpacing 頭部間隔 * @param tailSpacing 尾部間隔 */- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing l eadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;/** * 多個固定大小的控制項的等間隔排列,變化的是間隔的空隙 * * @param axisType 軸線方向 * @param fixedItemLength 每個控制項的固定長度或者寬度值 * @param leadSpacing 頭部間隔 * @param tailSpacing 尾部間隔 */- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;
使用方法很簡單,因為它是NSArray的類擴充:
// 建立水平柏拉圖標 arr中放置了2個或連個以上的初始化後的控制項// alongAxis 軸線方向 固定間隔 頭部間隔 尾部間隔[arr mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:20 leadSpacing:5 tailSpacing:5];[arr makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@60); make.height.equalTo(@60);}];
2. 注意事項 約束視圖對象只有在被addSubview之後,才能給視圖添加約束 當你的所有約束都在 updateConstraints 內調用的時候,你就需要在此調用此方法,因為 updateConstraints方法是需要觸發的
// 調用在view 內部,而不是viewcontroller+ (BOOL)requiresConstraintBasedLayout { return YES;}/** * 蘋果推薦 約束 增加和修改 放在此方法種 */- (void)updateConstraints { [self.growingButton updateConstraints:^(MASConstraintMaker *make) { make.center.equalTo(self); make.width.equalTo(@(self.buttonSize.width)).priorityLow(); make.height.equalTo(@(self.buttonSize.height)).priorityLow(); make.width.lessThanOrEqualTo(self); make.height.lessThanOrEqualTo(self); }]; //最後記得回調super方法 [super updateConstraints];} 如果想要約束變換之後實現動畫效果,則需要執行如下操作
// 通知需要更新約束,但是不立即執行[self setNeedsUpdateConstraints];// 立即更新約束,以執行動態變換// update constraints now so we can animate the change[self updateConstraintsIfNeeded];// 執行動畫效果, 設定動畫時間[UIView animateWithDuration:0.4 animations:^{ [self layoutIfNeeded];}];
文/碼碼樂趣(簡書作者)
原文連結:http://www.jianshu.com/p/1d1a1165bb04
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。