看視頻可以直觀的獲取知識舵抹,然而我們可能會遺失一些關鍵信息點肪虎。因此我匯總講稿,方便大家可以反復快速學習惧蛹。
開場白
技術交流
QQ:3365059189
SwiftUI技術交流QQ群:518696470
您好扇救,歡迎來到WWDC。 Cody Brimhall:您好赊淑,歡迎來到SwiftUI中的Stacks爵政,Grids和Outlines仅讽。我是Cody陶缺,是處理SwiftUI的工程師,在本演講的稍后部分洁灵,我的同事Curt將加入我的行列饱岸。
SwiftUI 具有多種內置布局原語
SwiftUI具有多種內置布局原語,用于按水平和垂直順序排列視圖集合徽千。這些原語可以單獨用于滿足基本的布局需求苫费,也可以將它們組合在一起以構建具有自定義行為的復雜視圖。
推薦開發(fā)模式
macOS中的新通知中心是通過SwiftUI實現的双抽,它是工作中這種組合過程的一個很好的例子百框。簡單的堆棧和網格使用層次結構,對齊方式和間距一起工作以組織大量信息牍汹,結果既美觀又可用铐维。在開發(fā)自己的應用程序時柬泽,我建議您以類似的方式考慮。
合成的重要性
SwiftUI的布局原語在設計時就考慮了合成嫁蛇。通常锨并,當一個簡單類型不能完成您需要做的所有事情時,前進的道路就是將它與另一個具有互補行為的簡單類型結合起來睬棚。具有多種內置布局原語
演講的主要內容
- 回顧最基本的類型第煮,即水平和垂直堆棧,并介紹一對新的類型抑党,以創(chuàng)建延遲增長的網格布局包警。
- 看一下現有Lists類型的新功能,該功能允許呈現分層數據
- Curt將深入研究輪廓和表單底靠,并展示一些逐步顯示用戶界面控件的技術揽趾。
Stacks堆棧SwiftUI中最簡單的布局原語
我將從堆棧開始,這是SwiftUI中最簡單的布局原語苛骨。但是首先篱瞎,為了談論堆疊,我需要談論三明治痒芝。如果您聽了《 SwiftUI簡介》演講俐筋,您會知道我的朋友Jacob一直在努力制作三明治應用。我想自己是個三明治鑒賞家严衬,我認為將Jacob的應用程序放到畫廊視圖中展示特別難忘的午餐照片會很有趣澄者。
我要使用的數據模型非常簡單:
- ID
- 名稱
- 星級
- 畫廊的英雄形象
在畫廊中顯示單個三明治的視圖也同樣簡單。它顯示可調整大小的英雄圖像请琳,并添加一個包含有關三明治信息的覆蓋圖粱挡。覆蓋每個英雄圖像的橫幅視圖使用VStack排列三明治的標題和星級評定指示器。星級只是圖像的水平疊放俄精。我最初的實現非常簡單询筏。我在展示我的畫廊時使用的是一疊垂直的三明治視圖。
使用Lazy的原因
隨著拍攝更多照片竖慧,我的三明治列表將動態(tài)增長嫌套,因此我需要包含一個ForEach視圖,該視圖將枚舉每個三明治并為每個三明治做一個視圖圾旨。此外踱讨,堆棧不會自行滾動。因此砍的,我需要將所有內容包裝在滾動視圖中痹筛。到目前為止,我對此非常滿意。但是帚稠,當我開始在三明治照片的后部目錄中加載時产雹,我開始注意到一個問題。我的畫廊需要顯示的照片越多翁锡,顯示時屏幕變得響應時間就越長蔓挖。我想要的是一個惰性堆棧,該堆椆菹危可以逐步構建自身瘟判,這樣一開始,只有第一個充滿圖像的屏幕才需要渲染角溃。其余的可以在用戶滾動瀏覽圖庫時按需加載拷获。
我們將引入兩種新的SwiftUI堆棧類型,它們可以直接解決此問題减细。 LazyVStack和LazyHStack匆瓜。延遲堆棧就像它們的VStack和HStack對應對象一樣,只不過它們在可見時會逐漸遞增其內容未蝌。這非常適合我的需求驮吱。該視圖不會阻止主線程加載和測量每個圖像,并且該應用程序的內存占用不會不必要地增大萧吠。我需要做的就是用LazyVStack替換我的VStack左冬,現在我的圖庫會逐漸加載。我想在這里提出另外一點纸型。如果您從評級視圖的定義中回想起拇砰,定義英雄視圖庫的垂直堆棧并不是此處顯示的唯一堆棧。每個HeroView都有自己的水平堆棧來布置星級評定指示器狰腌,還有一個ZStack可以將等級覆蓋在英雄圖像的頂部除破。
注意不是所以視圖都需要lazy
因此,值得一提的是琼腔,由于我使外部堆棧變得很懶瑰枫,所以這些堆棧也應該也很懶嗎?在這種情況下展姐,答案是否定的躁垛。雖然我希望垂直堆棧特別懶惰剖毯,因為它可以滾動圾笨,但是我不想花時間在大多數內容不滾動而無法看到的情況下預先渲染所有內容。另一方面逊谋,使給定英雄視圖中的堆棧變得懶惰實際上并沒有帶來任何好處擂达。該視圖一出現在屏幕上,內容就立即可見胶滋,因此無論容器的默認行為如何板鬓,都必須立即加載所有內容悲敷。
通常,如果不確定使用哪種堆棧俭令,請使用VStack或HStack后德。
Grids
使用LazyVGrid,我可以輕松實現多列布局以增加視圖的三明治密度抄腔。讓我們看一下它是如何工作的瓢湃。這是我們之前看到的,為iPad擴展的同一個惰性堆棧赫蛇。我將其更新為三列三明治绵患,而不是一列。
與前面的示例的主要區(qū)別是我的布局容器悟耘。我使用LazyVGrid而不是LazyVStack落蝙,并且傳遞了一組值,這些值告訴SwiftUI如何計算網格中列的寬度暂幼。一秒鐘內會更多筏勒。除了列描述之外,我還像定義堆棧一樣定義了網格旺嬉,方法是傳入視圖構建器以生成構成網格的各個視圖奏寨。為了描述網格的列,我創(chuàng)建了一個GridItem值數組鹰服。每一項都指定如何計算單個列的寬度病瞳。在這里,我定義了三列悲酷。 GridItems默認情況下是靈活的套菜,因此這種安排將用等寬的列填充網格。這與橫向相同设易。列數是相同的逗柴,只是更寬。網格布局還可以適應可用于創(chuàng)建可變列數的空間顿肺。例如戏溺,在這里,我聲明了一個自適應網格項屠尊,該網格項在保持指定的最小列寬的同時旷祸,會產生盡可能多的等寬列。這對于橫向模式非常有用讼昆,在橫向模式中有足夠的空間容納更多列托享。自適應網格項在macOS上也非常有用,在macOS中,可以任意調整窗口的大小闰围。這些新原語的表現力令我感到非常興奮赃绊。我想在移交給Curt之前討論的最后一個主題是列表。列表不僅僅是基本的布局基元羡榴。它們是交互式的碧查,并支持選擇管理和滾動。列表內容總是延遲加載⌒B兀現在我不認識你么夫,但是到那時我已經吃了很多三明治。
開源個新App給大家ShapeEdit
讓我們看一下Curt一直在開發(fā)的一個很酷的新應用肤视,名為Shape Edit档痪。 Shape Edit是基于文檔的應用程序,可在macOS邢滑,iPadOS和iOS上運行腐螟。如果放大,我們可以在Shape Edit中看到Windows邊欄視圖困后,其中我們使用了一個列表來枚舉畫布中的形狀乐纸。我們當前在畫布上有一組圖形,并使用圖形數組填充側欄中的內容行摇予,從而生成平面形狀列表汽绢。超酷。
我在使用此應用程序的過程中一直玩得很開心侧戴,以至于我被啟發(fā)添加一個功能來將形狀收集到組中宁昭。組還可以包含其他組,因此我們的平面列表現在需要表示任意深的元素樹酗宋。
List中添加了一個新功能
我們在List中添加了一個新功能积仗,非常適合此功能,我很高興談論它蜕猫。要將列表變成輪廓寂曹,我只需要告訴列表如何遍歷數據樹即可。
我將使用新的初始化程序在圖形模型上提供子級鍵路徑回右,而SwiftUI將完成其余的工作隆圆。經過這一更改,我的側邊欄現在顯示了完整的形狀層次結構翔烁。太棒了正如您可能想象的那樣渺氧,為了自動創(chuàng)建此輪廓,正在進行很多有趣的工作租漂。
現在阶女,我將交給Curt颊糜,后者將向您展示如何使用相同的工具列表在您自己的UI中實施漸進式披露哩治。 秃踩? Curt Clifton:謝謝,Cody业筏。
將列表轉換成這樣的輪廓非炽狙睿酷。我想深入了解它的工作原理蒜胖。我認為細節(jié)非常棒消别,您也可以在自己的應用中使用其中的一些內容。 Cody向我們展示了Shape Edit如何繞過列表的子級鍵路徑在邊欄中顯示圖形的輪廓台谢。
我一直認為在我們的應用程序中支持多個畫布會很酷寻狂,并繪制了一個模型。該模型對每個畫布使用不同的部分朋沮,并且在每個部分內部有單獨的輪廓蛇券。讓我們看看如何實現這樣的自定義大綱。
正如Cody所提到的纠亚,列表是有助于管理選擇的高級結構,因此我們保留了這一點筋夏。然后在列表中蒂胞,我們使用ForEach遍歷畫布。對于每個畫布条篷,我們使用Section添加一個顯示畫布名稱的標題骗随。最后,本節(jié)的內容是SwiftUI的新視圖:OutlineGroup赴叹。 OutlineGroup與ForEach相似蚊锹,只是OutlineGroup遍歷樹結構數據而不是遍歷平面集合。
這里需要一系列圖形和子級鍵路徑稚瘾。 OutlineGroup生成一個輪廓牡昆,其中每個項目都是一個圖形行。
讓我們切換到Xcode摊欠,看看它是如何工作的丢烘。這是預覽中顯示的圖形輪廓。 SwiftUI大綱不僅可以在macOS上使用些椒,而且還可以在iOS上使用播瞳。在iPad和iPhone上具有強大的內置輪廓功能真是太好了。
讓我們進行實時預覽免糕,看看這些組如何工作赢乓。我可以點擊披露指標來展開和折疊組忧侧。讓我們更新此視圖以顯示所有畫布。首先牌芋,我們將在包裝此圖形行的列表內添加一個OutlineGroup蚓炬。
然后,將前兩個參數從List移到OutlineGroup躺屁。
請注意我們的預覽如何尚未更改肯夏。直接在列表內部的OutlineGroup與使用children參數的列表相同。接下來犀暑,讓我們將視圖更改為使用畫布而不是圖形驯击。通過單擊命令并選擇重復,將這個OutlineGroup包裝在ForEach中耐亏。然后徊都,將參數替換為模型中的畫布...
...并重命名此參數。最后广辰,我將更改OutlineGroup以在單個畫布上遍歷圖形∠窘茫現在,我們可以從所有畫布上看到圖形轨域,但是它們都可以一起運行袱耽。讓我們添加一些節(jié)標題。我可以按Shift-Command-L打開庫干发,然后過濾以顯示部分朱巨。我可以將其拖入其中,然后使標題顯示畫布名稱枉长。
注意冀续,因為我們使用的是側邊欄列表樣式,所以我們在iOS 14中引入了這些漂亮的粗體標題必峰。我們也可以擴展和折疊它們洪唐。我覺得這很酷。通過分層列表和大綱組吼蚁,SwiftUI在Mac和iOS上提供了兩個很棒的新工具來逐步顯示信息凭需。有時,應用程序要求隱藏和顯示不遵循常規(guī)層次結構的控件或其他信息肝匆,例如Inspector Popover粒蜈。對于這種情況,
第三個新工具DisclosureGroups
我很高興介紹第三個新工具DisclosureGroups旗国。 DisclosureGroup提供了公開指示器枯怖,標簽和內容。當您的用戶點擊或單擊公開指示器時能曾,將顯示內容度硝。當他們再次點擊或單擊它時肿轨,內容將被隱藏。讓我們看看如何使用它蕊程。這是我們的檢查員椒袍。我們具有用于調整填充,陰影和文本屬性的控件存捺。
所有這些都包裝在一個Form中槐沼,這是此類控件集合的理想選擇曙蒸。您也可以在macOS的新“設置”場景中使用“表單”捌治。讓我們快速看一下檢查器在應用程序中的工作方式。
Shape Edit在iPad上效果很好纽窟。我可以選擇一個形狀肖油,然后打開檢查器。我可以更改顏色臂港,添加陰影甚至更改形狀森枪。讓我們回到代碼。這個檢查器工作很好审孽,但是有點忙县袱。讓我們看看是否可以整理一下。首先佑力,我將所有這些填充控件包裝在DisclosureGroup中式散。我將從庫中獲取一個DisclosureGroup ...
并設置標題以填充。注意打颤,填充控件現在在檢查器中一起折疊暴拄。就像輪廓一樣,我們可以展開和折疊DisclosureGroup编饺。該小組實際上可以使用一個圖標乖篷。我們可以為此使用標簽。我們只是刪除了此便捷屬性透且,并為標簽添加了尾隨閉包撕蔼。
我可以在這里放置任何視圖,但是新標簽類型是在語義上組合標題和圖標的便捷方法秽誊。我可以在這里使用出色的SFSymbol圖像之一鲸沮。我的最愛之一是rectangle.3.offgrid.fill。很好看讓我們對陰影和文本控件進行相同的處理养距。完成此操作后诉探,該檢查員看起來非常不錯。我只想更改一件事棍厌。
我認為我的用戶會大量調整填充設置肾胯,因此我希望他們在打開檢查器時可見∈現在開始吧。 SwiftUI中的DisclosureGroups可以綁定到控制擴展的布爾屬性敬肚。我將添加布爾狀態(tài)以充當真相的來源...
...并將其默認設置為true毕荐。然后,我將配置DisclosureGroup以綁定到我們的新狀態(tài)⊙蘼現在憎亚,我們的填充控件默認擴展為-不錯!我們已經了解了如何使用大綱和披露組來管理應用程序中信息的逐步披露弄慰。在總結之前第美,讓我們看一下OutlineGroup的實際工作方式。這是科迪提到的構圖原理的一個很好的例子陆爽。不必使用大綱和公開組來了解這一點什往,但我認為這很酷,希望您也能這樣做慌闭。
探索原理
在這里别威,我們在一組圖形上有一個OutlineGroup。 SwiftUI在相同的圖形集合上將OutlineGroup擴展為ForEach驴剔。該ForEach的主體是DisclosureGroup省古。請注意,每個DisclosureGroup的標簽都是使用原始集合的單個元素生成的丧失,而每個DisclosureGroup的內容都是另一個OutlineGroup豺妓,這次是在該單個元素的子元素上。展開過程一直持續(xù)到找到沒有子代的圖形為止利花。但是由于SwiftUI僅在有人打開DisclosureGroup后才評估它的內容科侈,因此實際上僅執(zhí)行了最小量的過程。
如前所述炒事,您無需了解使用大綱和公開組的輕松過程臀栈,但我只喜歡遞歸和組合的組合,這使OutlineGroup成為可能挠乳。實際上权薯,我希望這次SwiftUI顯示數據的工具會有所幫助。我們看到HStack和VStack是控制固定項目集放置的正確工具睡扬。新的惰性堆棧在滾動視圖中非常有用盟蚣,可顯示可變的,可能較大的項目集卖怜。惰性網格提供了一種方便的新方法來在網格中顯示集合屎开。列表是強大的工具,可為您提供選擇马靠,滾動奄抽,內容的延遲加載以及今年新的分層數據顯示的支持蔼两。使用窗體進行設置和其他控件列表,就像我們在檢查器示例中看到的那樣逞度。最后额划,新的大綱和公開組使您能夠定制適合您應用程序的漸進式信息顯示。
下載源碼
要了解有關如何最好地在應用程序中顯示數據的更多信息档泽,可以從developer.apple.com下載Shape Edit的代碼俊戳。另外,請確保簽出SwiftUI中的App Essentials馆匿,以了解有關在應用程序中創(chuàng)建設置場景的更多信息抑胎,以及簽入SwiftUI中的Data Essentials,以獲取有關將模型連接至視圖的詳細信息甜熔。有關三明治的更多信息圆恤,請查看WWDC20中的SwiftUI簡介突倍。