SwiftUI - Stack布局詳解(2)

在上一節(jié)中,看到當(dāng)沒有加入任何限制時闸迷,HStack是如何分配空間給自己的子元素的烘苹,通過迭代依次進行。在本節(jié)中坝茎,將講解.layoutPriority.frame這兩個modifier是如何影響布局結(jié)果的涤姊。

布局優(yōu)先級修飾符.layoutPriority

繼續(xù)使用上一節(jié)中的例子,使用HStack依次平鋪三個Text嗤放,下面的示例代碼中思喊,沒有任何的優(yōu)先級區(qū)別,采用默認(rèn)的方式進行布局次酌。

struct DemoView: View {
    var body: some View {
        HStack {
            Text("A great and warm welcome to Kuchi")
                .background(Color.red)
            Text("A great and warm welcome to Kuchi")
                .background(Color.red)
            Text("A great and warm welcome to Kuchi")
                .background(Color.red)
        }.background(Color.yellow)
    }
}

那么.layoutPriority這個modifier是什么呢恨课?先來看一下官方文檔的解釋:

Sets the priority by which a parent layout should apportion space to the child.
The default priority is 0. In a group of sibling views, raising a view’s layout priority encourages that view to shrink later when the group is shrunk and stretch sooner when the group is stretched.
A parent layout should offer children with the highest layout priority all the space offered to the parent minus the minimum space required for all its lower-priority children, and so on for each lower priority value.

提煉一下重點:

  1. 當(dāng)沒有使用該modifier時,默認(rèn)值為0岳服;
  2. 回想一下上一節(jié)中的布局迭代的順序剂公,父視圖在挑選子元素布局的順序,依賴于該modifier的大小吊宋,modifier值越大纲辽,優(yōu)先級越高;
  3. 取得最高優(yōu)先級的元素后璃搜,該子元素可用于布局的空間是父視圖空間減去剩下元素個數(shù)乘以一個minimum space拖吼,再減去子元素間的默認(rèn)間隔(這個默認(rèn)間隔可以通過Stack的初始化函數(shù)進行修改)后的大小,這個minimum space在之后的實例中可以看到这吻。

修改一下之前的示例代碼吊档,添加.layoutPriority

struct DemoView: View {
    var body: some View {
        HStack {
            Text("A great and warm welcome to Kuchi")
                .layoutPriority(-1)
                .background(Color.red)
            Text("A great and warm welcome to Kuchi")
                .layoutPriority(1)
                .background(Color.red)
            Text("A great and warm welcome to Kuchi")
                .background(Color.red)
        }.background(Color.yellow)
    }
}

它們的優(yōu)先級分別為-1,1唾糯,0怠硼。最后一個Text由于沒有給它設(shè)置優(yōu)先級鬼贱,所以它的優(yōu)先級為默認(rèn)值0,得到的結(jié)果如下圖所示:

priority 1.png

從這個結(jié)果中香璃,可以看到第一個Text由于優(yōu)先級最低-1这难,被壓縮成了一個細(xì)條,這個細(xì)條的寬度就是上面解釋中所說的minimum space增显,兩個Text中間的間隔就是一個默認(rèn)間隔雁佳。

小結(jié)

當(dāng)設(shè)置了優(yōu)先級以后,布局的過程便和上一節(jié)中所說的有所不同了同云,總結(jié)如下:

  1. 父視圖給出了可用于布局(可以自己支配)的frame糖权;
  2. 當(dāng)有多個子視圖時,在子視圖中進行挑選找出優(yōu)先級最高的炸站,選擇第一個子視圖星澳。
  3. 對第二步找到的子視圖進行布局,把自己的可支配的大小減去剩下元素個數(shù)乘以minimum space旱易,再減去子元素間的間隔禁偎,將這一部分空間分配給該視圖進行布局
  4. 子視圖基于父視圖提供的frame來看看自己到底占據(jù)的大小
  5. 子視圖算好之后,父視圖會減去這個子視圖所占據(jù)的size阀坏,把剩下的部分分配給其余的子視圖如暖,回到步驟2,進行下一次循環(huán)忌堂,直到所有子視圖繪制完成盒至。
  6. 當(dāng)所有子視圖繪制結(jié)束后,父視圖再根據(jù)子視圖所占據(jù)空間來調(diào)整自己的size

當(dāng)有多個子視圖具有相同優(yōu)先級時士修,第三步的計算方式將優(yōu)先不同:

對第二步找到的子視圖進行布局枷遂,把自己的可支配的大小減去剩下低優(yōu)先級元素個數(shù)乘以minimum space,再減去子元素間的間隔棋嘲,將這一部分空間均分給和當(dāng)前視圖具有相同優(yōu)先級的元素酒唉,而這個元素所占面積為其中一份。

priority 2.png

Tips: 如果對于這種布局結(jié)果有疑問沸移,比如為何第一個和第二個Text所占的空間為什么會不相同痪伦,請查閱上一節(jié)。

frame修飾符

那么再來看看frame修飾符雹锣,frame具有最高的優(yōu)先級流妻,布局時,會優(yōu)先為有frame的子視圖進行布局笆制,示例代碼如下:

struct DemoView: View {
    var body: some View {
        HStack {
            Text("A great and warm welcome to Kuchi")
                .frame(width: 200, height: 200)
                .background(Color.red)
            Text("A great and warm welcome to Kuchi")
                .layoutPriority(1)
                .background(Color.red)
            Text("A great and warm welcome to Kuchi")
                .background(Color.red)
        }.background(Color.yellow)
    }
}
priority 3.png

frame是最好理解的布局修飾符,尤其對應(yīng)熟悉UIKit的同學(xué)涣达,在這里也就無需多介紹了在辆。了解了視圖的布局后证薇,其實會發(fā)現(xiàn),在平時的開發(fā)過程中匆篓,他們的使用場景其實并不多浑度,通常情況下,都會給出固定的位置鸦概,來放置元素箩张。只有當(dāng)我們需要類似自動填充的流式布局時,才需要了解并掌握這些布局的原理窗市。

題外話

在之前的講解中說到了布局中先慷,兩個相鄰子元素的默認(rèn)間隔,這個間隔可以通過構(gòu)造函數(shù)進行修改:

@inlinable public init(alignment: VerticalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content)

它的第二個參數(shù)spacing就是間隔咨察,默認(rèn)值為nil论熙,也就是默認(rèn)間隔∩阌可以通過將其設(shè)置為0脓诡,來取消這個間隔。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末媒役,一起剝皮案震驚了整個濱河市祝谚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酣衷,老刑警劉巖交惯,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鸥诽,居然都是意外死亡商玫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門牡借,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拳昌,“玉大人,你說我怎么就攤上這事钠龙【嫣伲” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵碴里,是天一觀的道長沈矿。 經(jīng)常有香客問我,道長咬腋,這世上最難降的妖魔是什么羹膳? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮根竿,結(jié)果婚禮上陵像,老公的妹妹穿的比我還像新娘就珠。我一直安慰自己,他們只是感情好醒颖,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布妻怎。 她就那樣靜靜地躺著,像睡著了一般泞歉。 火紅的嫁衣襯著肌膚如雪逼侦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天腰耙,我揣著相機與錄音榛丢,去河邊找鬼。 笑死沟优,一個胖子當(dāng)著我的面吹牛涕滋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挠阁,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼宾肺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了侵俗?” 一聲冷哼從身側(cè)響起锨用,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎隘谣,沒想到半個月后增拥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡寻歧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年掌栅,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片码泛。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡猾封,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出噪珊,到底是詐尸還是另有隱情晌缘,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布痢站,位于F島的核電站磷箕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏阵难。R本人自食惡果不足惜岳枷,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嫩舟,春花似錦氢烘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽椎工。三九已至饭于,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間维蒙,已是汗流浹背掰吕。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留颅痊,地道東北人殖熟。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像斑响,于是被迫代替她去往敵國和親菱属。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容