? ? ? ? ?筆者自大學(xué)畢業(yè)后即開始從事ios開發(fā)斩熊,在學(xué)習(xí)之初即發(fā)現(xiàn)線性代數(shù)與控件條件之間有一種微妙的關(guān)系往枣,而且如果一個理論能夠找到數(shù)學(xué)的支持,那么這個理論將會有非常強(qiáng)大的理論支持粉渠,而不再是經(jīng)驗(yàn)支持分冈。本數(shù)學(xué)建模算法主要解決我們在進(jìn)行控件布局過程中的約束過少,約束過多霸株,約束沖突等問題雕沉。但是一個好的理論應(yīng)該具有一般性和通用性,于是筆者并未在工作之初就發(fā)表文章去件,而是在工作中深入研究這種算法坡椒,并驗(yàn)證算法的一般性,雖然在IOS中我們可以利用像Masonry這樣的第三方框架加上豐富的經(jīng)驗(yàn)尤溜,可以完成約束倔叼,但是本數(shù)學(xué)建模算法對于使用StoryBoard和XIB會非常有用,即使是在純代碼配合Masonry情況下宫莱,進(jìn)行非常復(fù)雜的控件布局缀雳,也依然非常有效和好用,最重要的是我們可以給我們的布局約束找到很好的數(shù)學(xué)支持梢睛,而不再是通過經(jīng)驗(yàn)這種不是百分之百拿得準(zhǔn)的不穩(wěn)定支持肥印,本文以IOS為例講解识椰,相信其他前端開發(fā)的讀者也可以找到合適的對應(yīng)的東西。
? ? ? ? ? 我們先通過一些簡單的回憶給后面的數(shù)學(xué)建模打下基礎(chǔ)深碱,但凡學(xué)習(xí)過數(shù)學(xué)的人應(yīng)該對二元一次非齊次方程組有解的條件非常熟悉
以上的這個式子在我們初中就已經(jīng)會做了腹鹉,大學(xué)的時(shí)候進(jìn)入了深入的學(xué)習(xí),探討了其有解的本質(zhì)敷硅,此方程組的系數(shù)矩陣為
此系數(shù)舉證在經(jīng)過線性變換后功咒,可以保證矩陣的秩為滿,這就是式1具有特解的原因绞蹦。這是我們的第一種情況力奋,方程組系數(shù)矩陣滿秩,有特解
同時(shí)我們再看一個列子
此方程組的系數(shù)矩陣為
可以看出此方程組的系數(shù)矩陣通過線性變換后不滿秩幽七,那么肯定就沒有特解了景殷,同時(shí),上下方程明顯矛盾澡屡,造成連通解也沒有鳍寂,這是第二種情況伊佃,方程組系數(shù)矩陣不滿秩没讲,且式子有沖突絮识,無特解。
再舉一個例子室埋,這是第三種種情況
此方程組的系數(shù)矩陣和式4是一樣的办绝,系數(shù)矩陣不滿秩,即沒有特解姚淆,但是由于上下式子沒有沖突八秃,此方程組存在通解,這就是第三種情況肉盹,方程組系數(shù)矩陣不滿秩昔驱,但是有通解。
第四種情況
此方程的系數(shù)矩陣為
? ? ? ?很顯然系數(shù)矩陣方程滿秩上忍,但是這里多了一個方程骤肛,例如最后一個方程可以由第三個方程和第二個方程變換得來。這是第四種情況窍蓝,系數(shù)矩陣滿秩腋颠,有特解,但是條件多了
?? ? ? 其實(shí)確定我們一個控件的位置吓笙,一般情況下(在IOS中淑玫,UILable,UITextField等除外)需要確定4個參數(shù),即frame中x,y,width,height四個參數(shù)絮蒿,那么按照我們上述的理論尊搬,我們就需要四個方程式來解出這四個參數(shù),當(dāng)然土涝,我們根本就不需要解出這四個值佛寿,我們只需要得到系數(shù)矩陣判斷我們的約束是否合適,為了更方便地建模但壮,我們需要對常用的其他控件位置大小描述方法做一個約定,而且width和height分別簡稱為w和h冀泻,屏幕寬度或父控件高度分別為W和H,常數(shù)量為c,如果本控件是相對于另外一個控件的相對位置,則另外一個空間的四個未知數(shù)表示為x',y',w',h'蜡饵,centerX=x+1/2w弹渔,centerY=y+1/2h。trailing = x+w,bottom=y+h ?溯祸。以此肢专,maxX,midX,maxY,midY讀者按照剛才的方法也可以轉(zhuǎn)換為x和w的關(guān)系式您没。接下來我們將對XCode提供的StoryBoard系統(tǒng)方法進(jìn)行數(shù)學(xué)建模。
? ? 按照圖1提供的約束方法胆绊,數(shù)學(xué)式分別為:Leading Edges:x = x'.? Trailing Edges: x+w = x'+w'. Top Edges: y=y'.? Bottom Edges:y+h = y'+h'.? Horizontal Centers:x+1/2w = x'+1/2w'.? Vertical Centers:y+1/2h = y'+1/2h'.Horizontally in Container:x+1/2w = 1/2W.? Vertically in Container:y+1/2h = 1/2H
? ? ?按照圖二提供的約束方法,數(shù)學(xué)式分別為:top:x=c. left:y=c. bottom:y+h+c=H. right:x+w+c=W. ?height:h=c. width:w=c. Equal Width:w = w'. Equal Height:h = h'氨鹏。
? ? ? 現(xiàn)在我們已經(jīng)對系統(tǒng)給的重要約束方法有了一個完整的數(shù)學(xué)建模,及時(shí)是Masonry提供的方法压状,幾乎也離不開此數(shù)學(xué)建模仆抵,我們將舉例說明我們在文章最初說的三種情況,因?yàn)榻M合的可能性太多种冬,我就不一一列舉所有的組合情況镣丑,關(guān)于系數(shù)矩陣解的情況分別只列舉一個例子
? ? ? 第一種情況:方程組系數(shù)矩陣滿秩,有非齊次特解娱两,即能確定控件的位置和大小莺匠,先以單控件為例,我們經(jīng)常使用的top.left.bottom.right十兢∪たⅲ可以得到一個方程組
其中C1,C2,C3,C4為我們自己設(shè)置的常數(shù),此方程組的系數(shù)矩陣為
? ? ? ? ?顯然旱物,在經(jīng)過線性變換后遥缕,該系數(shù)矩陣方程滿秩,由我們上述的結(jié)論宵呛,該方程組有特解单匣,我們可以唯一確定控件大小和位置。
? ? ? ? ?第二種情況。例如我們設(shè)置了top和bottom户秤,此時(shí)根據(jù)上文的數(shù)學(xué)建模的兩個式子码秉,我們可以得到兩個式子y=c1 ,y+h=H-c2。有這兩個式子虎忌,我們已經(jīng)可以得到控件的唯一高度泡徙,如果此時(shí)我們再對控件的高度進(jìn)行設(shè)置,且高度設(shè)置不等于唯一特解膜蠢,即出現(xiàn)約束沖突堪藐,此時(shí)XCode會報(bào)出紅色箭頭警報(bào)。如果此時(shí)我們也設(shè)置了高度挑围,但是高度和唯一特解一致礁竞,則出現(xiàn)第四種情況
同時(shí)我們在此處再舉一個有通解的,我們在實(shí)際編程中可能出現(xiàn)的問題杉辙。
以圖中兩個控件為例模捂,我們分別設(shè)置了兩個控件的上下左右約束,只不過左邊控件的right約束以右邊控件的左邊為參考蜘矢,右邊控件的Left以左邊控件的right為參考狂男。在XCode8.0之前不會報(bào)出紅色箭頭和綠色箭頭,運(yùn)行之后卻發(fā)現(xiàn)不是我們想要的效果品腹。XCode8.0后有綠色箭頭警報(bào)岖食,我們更新布局之后發(fā)現(xiàn),控件的大小和位置也不是我們想的那樣舞吭,是因?yàn)榇藭r(shí)的左邊控件的方程組為
右邊控件的方程組為
可以看出此時(shí)為變相的系數(shù)矩陣秩不滿泡垃。因?yàn)閮蓚€方程組有一個式子完全相同,相當(dāng)于多了一個未知數(shù)
? ? ?其實(shí)在我們經(jīng)驗(yàn)性地約束控件時(shí)羡鸥,我們是在潛意識地運(yùn)用線性代數(shù)避免此類情況的發(fā)生蔑穴,我們通常讓一個控件的方程組右邊等于常數(shù)或依賴于屏幕的長寬。還是以上一個例子為例惧浴,比如我們的左邊控件的right以屏幕為參考存和,式10的第三個方程式變換為x+w=W-c3.此時(shí)就可以完全確認(rèn)左邊控件大小位置的唯一特解。右邊控件的約束不變衷旅,但是此時(shí)的式11第三個方程式中的x此時(shí)不再是未知數(shù)哑姚,而是一個常數(shù),即右邊控件也有大小位置的唯一特解芜茵。
? ? ?此數(shù)學(xué)建模算法對于數(shù)學(xué)基礎(chǔ)不是很好的讀者可能會造成一定的困擾叙量,但是對于數(shù)學(xué)基礎(chǔ)良好的讀者能夠在實(shí)際編程中瞬間理解本文的中心思想,同時(shí)數(shù)學(xué)基礎(chǔ)不是很好的讀者在閱讀本文兩至三次后九串,理解了本文的中心思想后绞佩,會有一種恍然大悟的感覺寺鸥。同時(shí)作者也盡力以通俗的語言去解釋本觀點(diǎn)。
? ? ?作者的一位同事在一次復(fù)雜布局中品山,遇到了麻煩胆建,但是在作者詳細(xì)講述本文觀點(diǎn)后,非常順利地完成了布局約束肘交。本文為作者多年工作經(jīng)驗(yàn)總結(jié)笆载,引用本文觀點(diǎn)請注明出處或聯(lián)系作者,未經(jīng)允許不得轉(zhuǎn)載涯呻,請尊重作者的勞動凉驻。