最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

SwiftUI學習100天(Day47 - 里程碑:項目7-9)

2023-02-19 12:00 作者:愛上樹の蝸牛  | 我要投稿

原創(chuàng)鏈接:https://www.hackingwithswift.com/100/swiftui

以下內容僅供學習參考:

你現(xiàn)在已經掌握了一些重量級技能,所以在我們繼續(xù)之前,是時候回顧一下所涵蓋的內容,詳細介紹一些主題,并迎接新的挑戰(zhàn)。

恭喜你完成了另外三個項目!在我們的繪圖技術項目之后,你可能會感到疲倦,但今天和明天應該是一個很好的節(jié)奏變化——今天是鞏固的一天,明天會有所不同。

今天的挑戰(zhàn)很有趣,老實說,如果你有時間的話,它有很大的潛力可以開發(fā)成更大的應用程序。像今天這樣的日子很重要,因為它們給了你一個完全在你掌握之中的想法,并給了你時間和范圍來執(zhí)行它。希望你能充分利用這一點——正如宇航員梅杰米森曾經說過的那樣,“我喜歡將想法視為潛在的能量:它們真的很棒,但除非我們冒險將它們付諸行動,否則什么都不會發(fā)生?!?/p>

所以,今天是行動日:你前面有很多編碼,如果你想進一步推進項目,還有更多編碼的潛力。讓我們開始吧!

今天你有三個主題要完成,其中之一是你的挑戰(zhàn)。

你學到了什么

希望你覺得這些項目開始對你有所幫助,不僅可以進一步提高你的 SwiftUI 技能,還可以教你一些更高級的 Swift。此外,當然,你還有兩個新構建的 SwiftUI 項目——你可以繼續(xù)自定義所有你想要的項目,將它們放在 GitHub 上,或者將它們轉換成更適合你口味的其他項目。

以下是我們在過去三個項目中涵蓋的所有新事物的快速回顧:

  • 為什么@State只適用于結構。

  • 如何使用@ObservedObject類工作。

  • @Published如何讓我們宣布正在觀察的任何 SwiftUI 視圖的屬性更改。

  • 使用sheet()修飾符和dismiss環(huán)境鍵呈現(xiàn)和關閉視圖。

  • 使用onDelete(perform:)啟用滑動刪除。

  • 添加EditButton到導航欄項目,讓用戶更輕松地編輯列表數(shù)據(jù)。

  • 使用 UserDefaults讀取和寫入數(shù)據(jù)。

  • 使用 Codable歸檔和取消歸檔數(shù)據(jù),包括處理存儲在層次結構中的數(shù)據(jù)。

  • 使用Identifiable協(xié)議來確保所有項目都可以在我們的用戶界面中被唯一標識。

  • 如何使用GeometryReader使內容適合屏幕。

  • ScrollView用于在可滾動區(qū)域中布置自定義視圖。

  • 使用 NavigationLink將新視圖推送到導航堆棧。

  • 使用 Swift 的泛型系統(tǒng)編寫處理不同類型數(shù)據(jù)的方法。

  • 創(chuàng)建自定義路徑和形狀。

  • 使用 InsettableShape創(chuàng)建可以插入并描邊邊框的形狀。

  • 用于CGAffineTransform創(chuàng)建旋轉和平移。

  • 使用 ImagePaint制作創(chuàng)意邊框和填充。

  • 啟用 Metal 以使用drawingGroup().

  • 修改混合模式和飽和度。

  • 使用animatableDataAnimatablePair對形狀進行動畫處理

我希望你會很認同這些,而且范圍很廣——我們已經從硬核語言特性到面向用戶的視圖,甚至更進一步到 Swift 繪圖系統(tǒng)的創(chuàng)造性使用。有些人會更喜歡純語言的東西,而另一些人會更喜歡編碼的更有創(chuàng)意的一面,這沒關系——我們的學習方式都不一樣!

關鍵點

雖然我們在前三個項目中涵蓋了很多內容,但我想更詳細地介紹三件具體的事情。別擔心——繪畫不是其中之一!

類與結構:有什么區(qū)別,為什么重要?

Swift 為我們提供了兩種創(chuàng)建我們自己的復雜數(shù)據(jù)類型的方法,理解我們?yōu)槭裁匆褂盟鼈円约盀槿魏谓o定任務選擇哪種方法很重要。

類和結構的根本區(qū)別在于,一個是值類型,另一個是引用類型。這些是我們如何處理數(shù)據(jù)的標準編程術語:數(shù)據(jù)只是一個簡單的值,例如“Hello”或 5,還是僅僅是一個路標,上面寫著“我的數(shù)據(jù)存儲在 RAM 中的這個位置”。

一旦你理解了這種差異,結構和類就變成了兩種截然不同的東西,但是當你學習這些差異時,你會覺得它們根本沒有什么不同??梢赃@樣想:當我們創(chuàng)建一個包含結構的變量時,該數(shù)據(jù)實際上存儲在變量中。相比之下,當我們使用一個類時,數(shù)據(jù)被放在內存中的某個地方,并且變量持有一個長數(shù)字來標識該內存的位置。

這就是這個名字的由來:“引用類型”被存儲為對某處內存的引用,有點像路標。它不是一個直接指向我家的變量,而是指向一個指向我家的路標——有一個額外的間接層。這就是為什么如果你將兩個或多個變量指向一個類的同一個實例,它們可以修改相同的數(shù)據(jù):你只有幾個路標都指向同一個房子。

這也是為什么引用類型和值類型在用作常量時表現(xiàn)不同的原因。如果我們創(chuàng)建一個類的常量實例,我們所做的就是創(chuàng)建一個常量路標——我們說過“這個路標總是指向門牌號 24601,不能指向不同的房子?!?然而,這并不能阻止我們改造房子:也許我們想加一層樓,或者改變廚房,或者甚至可能完全拆除房子并建造新的。如果你想讓這些東西固定——如果你想讓實際的房子本身保持不變——那么你需要為你的類使用常量屬性。

因此,我們可以在擁有可變數(shù)據(jù)?(let myHouse = House()?) 的同時制作一個不變的路標 (?var numberOfFloors = 3)。但我們也可以反過來:我們可以制作一個可變路標(var myHouse = House)的同時讓他具有常量數(shù)據(jù)?(?let numberOfFloors = 3),并且它的行為非常不同:我們可以移動路標,使其指向不同的房屋,但我們不能改造房子自己。

現(xiàn)在想想所有這些與 Swift、SwiftUI 甚至 UIKit 有何關系。如果你的應用程序中有三個屏幕,所有這些屏幕都共享相同的數(shù)據(jù),那么確保數(shù)據(jù)在后臺(所有變量包含相同的值)和給用戶展示的界面(我們所有的列表/文本視圖?/ etc 顯示相同的值)保持同步是很重要的。

SwiftUI 提供了諸如@State和之類的包裝器,@ObservedObject以確保我們的視圖在數(shù)據(jù)更改時保持更新,但是這些包裝器無法與 UIKit 一起使用——你需要自己響應更改,然后更新用戶界面以反映這些更改。

這產生了一個問題:

  • 視圖 A 可以創(chuàng)建一個類的實例。

  • 視圖 A 可以將其傳遞給視圖 B,以便他們共享它。

  • 然后視圖 B 可以更改數(shù)據(jù)并更新其 UI。

  • 視圖 A 不會知道數(shù)據(jù)已更改,并且會顯示舊的 UI。

因此,UIKit 開發(fā)人員通常將結構用于數(shù)據(jù),因為這意味著每個視圖都有自己的數(shù)據(jù)副本,并且不會意外更改。更有趣的是,所有 UIKit 的視圖類型都是使用類構建的,這意味著 UIKit 開發(fā)人員將他們的視圖構建為類并使用結構來存儲他們的數(shù)據(jù)——這與 SwiftUI 完全相反。

明智地使用 UserDefaults

UserDefaults讓我們輕松存儲少量數(shù)據(jù)——它會自動附加到我們的應用程序,這意味著它可以在我們的應用程序啟動后立即加載。雖然它非常有用(而且你會嚴重依賴它?。?,但它確實有兩個缺點:

  1. 你應該只在那里存儲少量數(shù)據(jù)——任何超過 512KB 的數(shù)據(jù)都是可怕的。

  2. 你只能輕松存儲某些類型的數(shù)據(jù);其他一切都必須首先使用Codable來獲取一些二進制數(shù)據(jù)。

UserDefaults支持的類型列表簡短而精確:字符串、數(shù)字、日期、URL 和二進制數(shù)據(jù),以及這些類型的數(shù)組和字典。不包括 URL(實際上只是花哨的字符串),所有這些都是可以存儲在 plist 文件中的相同類型——屬性列表的縮寫。

這不是巧合:UserDefaults實際上就像我們的 Info.plist 文件一樣使用屬性列表寫出它的數(shù)據(jù)。事實上,記住這個鏈接真的可以幫助你充分利用UserDefaults——如果我們的 Info.plist 文件包含 100,000 個數(shù)據(jù)條目,把 100,000 個項目放在UserDefaults,那會很奇怪。

因此,按照其設計目的使用UserDefaults系統(tǒng)——正如 Apple 自己的文檔所說,它被稱為用戶默認值,“因為它們通常用于確定應用程序在啟動時的默認狀態(tài)或默認情況下的行為方式。”

何時使用泛型

我們使用泛型來創(chuàng)建一種解碼方法,該方法能夠從應用程序包中獲取任何 JSON 文件并加載到我們選擇的Codable類型中。但是——這是一個很大的但是!– 我們首先將方法編寫為非泛型:如果你還記得的話,它最初解碼了一組宇航員,然后升級為加載任何Codable類型。

那不是我在浪費你的時間,而是向你介紹了一種思考泛型和協(xié)議的明智方法。在這個項目中,我們需要解碼來自?astronauts.json 中的Astronaut實例數(shù)組,因此我們編寫了一個方法來精確地做到這一點——沒有協(xié)議也沒有泛型,只是一個簡單的擴展Bundle來幫助保持代碼的組織性。這模仿了我們大腦的思維方式:我們可以理解像宇航員這樣的具體事物,并且可以很容易地描述它們。

但是,對于協(xié)議和泛型,事情并不是那么簡單——我們現(xiàn)在有一系列可能的類型可以使用,除了遵循相同的協(xié)議之外,它們可能完全無關。例如,整數(shù)和字符串符合 Swift 的內置Comparable協(xié)議,這就是為什么 Swift 知道如何對它們的數(shù)組進行排序,但除此之外它們是完全不同的東西。

也許令人困惑的是,我們無法比較兩個可比較的對象,事實上,即使試圖從方法中返回Comparable也行不通。如果你不相信我,請嘗試一下:

這不會編譯,并且有充分的理由:Comparable它本身并不意味著什么。正如我所說,字符串和整數(shù)都符合Comparable協(xié)議,但這意味著你可以將一個整數(shù)與另一個整數(shù)進行比較,而不是你可以將任何Comparable類型與另一種類型進行比較——這沒有任何意義。

這就是通用約束如此有用的原因:它們讓我們說“這可以是任何類型的對象,只要……”然后提供一些限制。而且——也許違反直覺——添加限制通常會啟用更多功能。如你所見,當我們說我們的解碼方法可以用于任何類型時,這意味著我們不能使用JSONDecoder;在我們明確添加Codable限制之前,Swift 無法知道它可以安全地將 JSON 解碼為該類型。

所以,用好泛型的關鍵是一開始不要使用它們,當你確實需要它們時添加限制,這樣你就可以獲得盡可能多的功能。

挑戰(zhàn)

在我們繼續(xù)下一批項目之前,你需要完成一個新的挑戰(zhàn)。這意味著使用你在前三個項目中獲得的技能,自己從頭開始構建一個完整的應用程序。

這次你的目標是為那些想要跟蹤他們做了多少事情的人開發(fā)一個習慣跟蹤應用程序。這可能是學習一門語言、練習一種樂器、鍛煉身體等等——他們可以決定添加哪些活動,并根據(jù)需要進行跟蹤。

至少,這意味著應該有一個他們想要跟蹤的所有活動的列表,以及一個用于添加新活動的表格——一個標題和描述就足夠了。

對于更大的挑戰(zhàn),點擊其中一項活動應該會顯示帶有描述的詳細信息屏幕。對于艱巨的挑戰(zhàn)——請參閱下面的提示!– 使該詳細信息屏幕包含他們完成的次數(shù),以及一個增加完成次數(shù)的按鈕。

如果你想讓該應用程序真正有用,請使用Codable并使用UserDefaults加載和保存你的所有數(shù)據(jù)。

因此,此應用程序分為三個級別,你可以根據(jù)自己有多少時間以及想要推動自己走多遠來選擇想要走多遠。不過,我確實建議你至少嘗試每個級別——你獲得的每一點練習都有助于鞏固你的學習!

提示:

  • 從你的數(shù)據(jù)開始:定義一個包含單個活動的結構,以及一個包含一系列活動的類。

  • 該類將需要符合ObservableObject并給屬性使用@Published。

  • 你的主要列表和表單都應該能夠讀取共享活動對象。

  • 確保你的活動符合Identifiable以避免出現(xiàn)問題。

  • 使用 sheet()顯示你的添加表單,使用NavigationLink顯示你的活動詳細信息視圖(如果你添加了一個)

制作增加完成計數(shù)的按鈕會給你帶來挑戰(zhàn),因為你需要修改傳入的活動。如果你遇到困難,最簡單的方法是:

  1. 讓你的結構符合Equatable.?你在這里不需要任何特別的東西——只需在Equatable之后添加CodableIdentifiable。

  2. 將選定的活動和ObservableObject課程都傳遞到你的詳細信息視圖中。

  3. 當點擊增量按鈕時,復制現(xiàn)有活動并將其完成計數(shù)加 1。

  4. 使用firstIndex(of:)查找上一個活動在類數(shù)組中的位置,然后將其更改為你的新活動 - 類似data.activities[index] = newActivity的東西會起作用。(這需要Equatable步驟 1 的一致性?。?/p>

這是一個真正有用的應用程序,特別是如果它專門針對特定興趣 - 如果目標是練習樂器,那么你可以想象一個更高級的應用程序會建議不同的練習,或者如果目標是鍛煉,那么它可能會建議新的練習讓事情變得混亂。

事實上,這個挑戰(zhàn)只是一個小應用程序,但我希望它至少能讓你思考。祝你好運!

注意:如果你沒有在分配給他們的那一天完成挑戰(zhàn),請不要擔心——在未來的日子里,你會發(fā)現(xiàn)你有一些空閑時間,所以挑戰(zhàn)是你可以在未來返回的。



SwiftUI學習100天(Day47 - 里程碑:項目7-9)的評論 (共 條)

分享到微博請遵守國家法律
镇远县| 奉节县| 上犹县| 开原市| 武夷山市| 巍山| 大埔县| 红河县| 靖宇县| 梧州市| 莱州市| 广元市| 于都县| 白水县| 吴江市| 宜春市| 舞钢市| 城口县| 沭阳县| 固镇县| 邵阳市| 江门市| 武穴市| 泰和县| 通渭县| 祥云县| 名山县| 普宁市| 利津县| 东辽县| 英山县| 抚顺县| 正阳县| 修武县| 交城县| 长春市| 桐乡市| 唐海县| 景谷| 襄汾县| 阳山县|