先簡(jiǎn)單介紹一下凉当,這幾個(gè)方法的使用場(chǎng)景
mas_makeConstraints
: 一個(gè)視圖,剛創(chuàng)建出來(lái)茂契,沒(méi)有任何約束。用這個(gè)方法慨绳,給視圖創(chuàng)建 x,y,w,h的約束掉冶。
mas_updateConstraints
: 一個(gè)視圖,之前已經(jīng)有約束了脐雪,因?yàn)闂l件變了厌小,需要變位置(x,y),變寬高(w,h),需要修改約束战秋。
mas_remakeConstraints
: 一個(gè)視圖璧亚,之前有約束,但之前的約束脂信,全都不要了(x,y,w,h),需要全部重新創(chuàng)建癣蟋。
重點(diǎn)說(shuō)明 mas_updateConstraints
mas_updateConstraints 使用場(chǎng)景是透硝,某個(gè)視圖之前已經(jīng)有 x,y,w,h 約束了。
現(xiàn)在因?yàn)槟承┰蚍杞粒枰薷哪硞€(gè)約束濒生。
比如修改位置 x, y。
修改寬高 w,h幔欧。
但是罪治,mas_updateConstraints 是一直都有效的嗎?
場(chǎng)景一
兩個(gè) view。橙色的 view礁蔗,是父視圖觉义。
紫色的 view 是子視圖。
UIView *testView = [[UIView alloc] init];
testView.backgroundColor = [UIColor orangeColor];
[self.view addSubview:testView];
[testView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.offset(20);
make.height.width.offset(200);
}];
_testView = testView;
UIView *test2View = [[UIView alloc] init];
test2View.backgroundColor = [UIColor purpleColor];
[testView addSubview:test2View];
[test2View mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.offset(20); // x,y 依賴于父容器
make.height.offset(100); // width 和父容器沒(méi)有一毛錢關(guān)系
make.width.offset(100); // height 和父容器沒(méi)有一毛錢關(guān)系
}];
_testView2 = test2View;
testView2 是子容器浴井,約束設(shè)置的條件是 晒骇,除了 x,y 和父容器有關(guān)系之外(也不可能沒(méi)有關(guān)系)
width & height 都寫(xiě)的是常量,和父容器沒(méi)有任何關(guān)系滋饲。
在 touchesBegan 測(cè)試 mas_updateConstraints,來(lái)修改 testView2 的 width厉碟,height。
(這個(gè)寬高和父容器沒(méi)有一毛錢關(guān)系)
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[_testView2 mas_updateConstraints:^(MASConstraintMaker *make) {
make.width.offset(150);
make.height.offset(150);
}];
}
運(yùn)行結(jié)果:
查看控制臺(tái)屠缭,非常干凈箍鼓,沒(méi)有報(bào)約束沖突的問(wèn)題。
場(chǎng)景二
還是兩個(gè) view呵曹。橙色的 view款咖,是父視圖。
紫色的 view 是子視圖奄喂。
testView.backgroundColor = [UIColor orangeColor];
[self.view addSubview:testView];
[testView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.offset(20);
make.height.width.offset(200);
}];
_testView = testView;
UIView *test2View = [[UIView alloc] init];
test2View.backgroundColor = [UIColor purpleColor];
[testView addSubview:test2View];
[test2View mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.offset(20); // x,y 依賴于父容器
make.height.equalTo(testView).multipliedBy(0.5);// width 和父容器有關(guān)系了,它是父容器寬度的一半
make.width.equalTo(testView).multipliedBy(0.5); // height 和父容器有關(guān)系了,它是父容器高度的一半
// make.height.offset(100); // width 和父容器沒(méi)有一毛錢關(guān)系
// make.width.offset(100); // height 和父容器沒(méi)有一毛錢關(guān)系
}];
_testView2 = test2View;
現(xiàn)在 testView2 的 width
& height
也是約束設(shè)置的铐殃,但是已經(jīng)和父容器建立關(guān)系了。
它們分別是父容器寬高的一半跨新。
現(xiàn)在在使用 mas_updateConstraints 來(lái)更新testView2的寬高約束富腊。
[_testView2 mas_updateConstraints:^(MASConstraintMaker *make) {
make.width.offset(150);
make.height.offset(150);
}];
運(yùn)行結(jié)果:
testVIew2使用mas_updateConstraints 并沒(méi)有成功的修改自己的寬高(因?yàn)楹透溉萜鹘⒘岁P(guān)系了)
在來(lái)看看控制臺(tái)輸出:
很不幸的是,控制臺(tái)報(bào)出了約束異常域帐。
mas_updateConstraints 好像赘被,并不是萬(wàn)能的?
不是一句簡(jiǎn)單的 更新視圖的約束就能說(shuō)明白的肖揣。
那如何去修正呢民假?
修正步驟:
- 記錄和父容器產(chǎn)生了關(guān)系的約束對(duì)象。
- 更新這些約束對(duì)象之前龙优,先把之前的約束對(duì)象卸載羊异。
聲明兩個(gè)約束對(duì)象,width & height
MASConstraint *_heightConstraint; // 子視圖寬度約束
MASConstraint *_widthConstraint; // 子視圖高度約束
記錄和父容器產(chǎn)生了關(guān)系的約束對(duì)象
_heightConstraint = make.height.equalTo(testView).multipliedBy(0.5);
_widthConstraint = make.width.equalTo(testView).multipliedBy(0.5);
在更新這些和父視圖建立了關(guān)系的約束之前,必須先卸載之前的約束對(duì)象野舶。
然后再使用 mas_updateConstraints 更新全新的約束
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[_widthConstraint uninstall]; // 先卸載之前的寬度約束(multipliedBy)
[_heightConstraint uninstall]; // 先卸載之前的高度約束(multipliedBy)
[_testView2 mas_updateConstraints:^(MASConstraintMaker *make) {
make.width.offset(150);
make.height.offset(150);
}];
}
運(yùn)行結(jié)果:
再看看看控制臺(tái):
非常干凈易迹。沒(méi)有報(bào)任何沖突。
當(dāng)然還有 centerX,centerY 位置相關(guān)的(x,y不沖突平道,不代表 centerX,centerY 不沖突)等約束赴蝇,大家可以自己做測(cè)試看看。
最后結(jié)論:
- mas_updateConstraints 并是一個(gè)簡(jiǎn)單的更新視圖約束就能說(shuō)明白的巢掺。
- 某些和父親容器建立了約束關(guān)系的約束,在使用 mas_updateConstraints 之前劲蜻,必須先卸載之前的約束陆淀。
- 對(duì)于子視圖的 x,y 約束,使用mas_updateConstraints先嬉,總是有效的轧苫。(有人會(huì)說(shuō),x,y 也和父視圖建立了關(guān)系了呀疫蔓?那你能找一個(gè) x,y 和父視圖沒(méi)有建立關(guān)系的約束嗎含懊?)
- 對(duì)于父視圖是控制器根 view 的情況下,mas_updateConstraints衅胀。這是因?yàn)楦?view 的大小基本都是定死的岔乔。
- 當(dāng)使用mas_updateConstraints遇到約束問(wèn)題時(shí),可以先想想滚躯,是哪些約束事先需要?jiǎng)h除但沒(méi)有刪除的雏门?
一個(gè)比較暴力的解決 在使用 mas_updateConstraints 出現(xiàn)約束沖突的問(wèn)題方法。
更新哪個(gè)約束出沖突了掸掏,就把哪個(gè)約束刪除了茁影,在更新。也省的去研究丧凤,為什么會(huì)出沖突了募闲。
約束本身就是個(gè)比較蛋疼的東西。