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

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

SwiftUI學(xué)習(xí)100天(Day80 - 項(xiàng)目 16,第二部分)

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

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

以下內(nèi)容僅供學(xué)習(xí)參考:

今天你將以 Swift?Result類型的形式處理一個(gè)棘手的概念,但為了平衡事情,我們還將涵蓋兩個(gè)更簡單的概念,希望你今天不會(huì)發(fā)現(xiàn)太多工作。

Swift 的Result類型旨在解決當(dāng)你知道事情 A 可能為真或事情 B 可能為真時(shí)的問題,但在任何給定時(shí)間只有一個(gè)可以為真。如果你將它們想象成布爾屬性,那么每個(gè)屬性都有兩種狀態(tài)(真和假),但它們加起來有四種狀態(tài):

  1. A是假的,B是假的

  2. A為真,B為假

  3. A為假,B為真

  4. A為真,B為真

如果你確定選項(xiàng) 1 和 4 永遠(yuǎn)不可能——A 或 B 必須為真但它們不能都為真——那么你可以立即將邏輯的復(fù)雜性減半。

美國作家厄休拉·K·勒金曾說過:“唯一使生活成為可能的是永久的、無法忍受的不確定性;不知道接下來會(huì)發(fā)生什么。”?優(yōu)秀軟件的情況恰恰相反:我們可以執(zhí)行的確定性越強(qiáng),我們可以應(yīng)用的約束越多,我們的代碼就越安全,Swift 編譯器可以為我們做的工作就越多。

因此,盡管Result需要你考慮將轉(zhuǎn)義閉包作為參數(shù)傳入,但回報(bào)更智能、更簡單、更安全——完全值得。

今天你要完成三個(gè)主題,你將在其中學(xué)習(xí)Result、objectWillChange和圖像插值。

手動(dòng)發(fā)布 ObservableObject 變化

符合ObservableObject協(xié)議的類可以使用 SwiftUI 的@Published屬性包裝器來自動(dòng)宣布對(duì)屬性的更改,以便使用該對(duì)象的任何視圖都可以重新調(diào)用其body屬性并與其數(shù)據(jù)保持同步。這在很多時(shí)候都非常有效,但有時(shí)你想要更多的控制,SwiftUI 的解決方案被稱為objectWillChange.

每個(gè)符合ObservableObject的類都會(huì)自動(dòng)獲得一個(gè)名為objectWillChange.?這是一個(gè)publisher,這意味著它與屬性包裝器@Published做同樣的工作:它通知任何正在觀察該對(duì)象的視圖一些重要的東西已經(jīng)改變。顧名思義,應(yīng)該在我們進(jìn)行更改之前立即觸發(fā)此發(fā)布者,這允許 SwiftUI 檢查我們的 UI 狀態(tài)并為動(dòng)畫更改做準(zhǔn)備。

為了證明這一點(diǎn),我們將構(gòu)建一個(gè)自我更新 10 次的ObservableObject類。我們將使用一個(gè)名為 DispatchQueue.main.asyncAfter()的方法,它允許我們?cè)谶x擇的延遲后運(yùn)行附加的閉包,這意味著我們可以說“1 秒后執(zhí)行此工作”而不是“現(xiàn)在執(zhí)行此工作”。

在此測(cè)試用例中,我們將在asyncAfter()從 1 到 10 的循環(huán)中使用,因此我們將整數(shù)值遞增 10。該整數(shù)將被包裝使用@Published以便將更改公告發(fā)送到正在觀看它的任何視圖。

在你的代碼中的某處添加此類:

要使用它,我們只需要在 ContentView中添加一個(gè)@StateObject屬性,然后在我們的主體中顯示該值,如下所示:

當(dāng)你運(yùn)行該代碼時(shí),你會(huì)看到該值一直向上計(jì)數(shù),直到達(dá)到 10,這正是你所期望的。

現(xiàn)在,如果你刪除@Published屬性包裝器,你將看到 UI 不再發(fā)生變化。在幕后,所有asyncAfter()工作仍在進(jìn)行,但不會(huì)再導(dǎo)致 UI 刷新,因?yàn)椴粫?huì)發(fā)送任何更改通知。

我們可以通過使用我之前提到的objectWillChange屬性手動(dòng)發(fā)送更改通知來解決這個(gè)問題。這讓我們可以隨時(shí)發(fā)送更改通知,而不是依賴@Published自動(dòng)執(zhí)行。

嘗試將value屬性更改為此:

現(xiàn)在你將再次獲得舊行為 - 用戶界面將像以前一樣計(jì)數(shù)到 10。除了這一次,我們有機(jī)會(huì)在該觀察者willSet中添加額外的功能。也許你想記錄一些東西,也許你想調(diào)用另一個(gè)方法,或者你想把整數(shù)限制在value里面,這樣它就不會(huì)超出范圍——現(xiàn)在一切都在我們的控制之下。

理解 Swift 的Result類型

Swift 提供了一種特殊類型Result,它允許我們將成功的值或某種錯(cuò)誤類型封裝在一個(gè)單獨(dú)的數(shù)據(jù)片段中。因此,就像一個(gè)可選項(xiàng)可能包含一個(gè)字符串或可能什么都不包含一樣,例如,Result可能包含一個(gè)字符串或可能包含一個(gè)錯(cuò)誤。起初使用它的語法有點(diǎn)奇怪,但它確實(shí)在我們的項(xiàng)目中扮演著重要的角色。

要查看Result實(shí)際效果,我們可以從編寫一個(gè)方法開始,該方法從服務(wù)器下載一組數(shù)據(jù)讀數(shù),如下所示:

該代碼工作得很好,但它沒有給我們很大的靈活性——如果我們想把工作藏在某個(gè)地方并在它運(yùn)行時(shí)做其他事情怎么辦?如果我們想在未來的某個(gè)時(shí)候讀取它的結(jié)果,也許完全在其他地方處理任何錯(cuò)誤怎么辦?或者如果我們只是因?yàn)椴辉傩枰肴∠趺崔k?

好吧,我們可以通過使用 Result獲得所有這些,并且實(shí)際上可以通過你之前遇到過的 API 獲得它:Task。我們可以將上面的代碼重寫為:

我們之前使用過Task來啟動(dòng)工作,但在這里我們給Task對(duì)象起了一個(gè)名字fetchTask——這給了我們額外的靈活性來傳遞它,或者在需要時(shí)取消它。并注意我們的Task閉包現(xiàn)在如何返回一個(gè)值?該值存儲(chǔ)在我們的Task實(shí)例中,以便我們將來準(zhǔn)備好時(shí)可以讀取它。

更重要的是,Task如果拋出網(wǎng)絡(luò)獲取失敗,或者數(shù)據(jù)解碼失敗,這可能會(huì)引發(fā)錯(cuò)誤,這就是Result進(jìn)來的地方:我們?nèi)蝿?wù)的結(jié)果可能是一個(gè)字符串,上面寫著“找到 10000 個(gè)讀數(shù)”,但它也可能包含一個(gè)錯(cuò)誤。找出答案的唯一方法是查看內(nèi)部——它與可選項(xiàng)非常相似。

要從 一個(gè)Task中讀取結(jié)果,請(qǐng)像這樣讀取其result屬性:

注意到我們沒有使用try讀出Result嗎?那是因?yàn)?strong>Result將它保存在自身內(nèi)部——可能會(huì)拋出一個(gè)錯(cuò)誤,但除非我們?cè)敢?,否則我們現(xiàn)在不必?fù)?dān)心它。

如果你查看result的類型,你會(huì)發(fā)現(xiàn)它是一個(gè)Result<String, Error>– 如果它成功,它將包含一個(gè)字符串,但它也可能失敗并包含一個(gè)錯(cuò)誤。

你可以直接從 if 中讀取成功值Result,但你需要確保并適當(dāng)?shù)靥幚礤e(cuò)誤,如下所示:

或者,你可以在switch中用Result,編寫代碼來檢查成功和失敗情況。這些情況中的每一個(gè)都有它們的值(成功的字符串和失敗的錯(cuò)誤),因此 Swift 讓我們使用特制的匹配來讀取這些值case

無論你如何處理它,Result的優(yōu)點(diǎn)是它可以讓我們將某些工作的全部成功或失敗存儲(chǔ)在一個(gè)值中,將其傳遞到我們需要的任何地方,并且僅在我們準(zhǔn)備好時(shí)才讀取錯(cuò)誤。

在 SwiftUI 中控制圖像插值

如果你創(chuàng)建一個(gè) SwiftUI?Image視圖,將其內(nèi)容拉伸到大于其原始大小,會(huì)發(fā)生什么情況?默認(rèn)情況下,我們得到圖像插值,這是 iOS 如此平滑地混合像素的地方,你甚至可能根本沒有意識(shí)到它們已經(jīng)被拉伸了。這當(dāng)然會(huì)帶來性能成本,但大多數(shù)時(shí)候不值得擔(dān)心。

但是,圖像插值在一個(gè)地方會(huì)導(dǎo)致問題,那就是當(dāng)你處理精確像素時(shí)。例如,GitHub 上這個(gè)項(xiàng)目的文件包含一個(gè)名為 example@3x.png 的小卡通外星人圖像——它取自https://kenney.nl/assets/platformer-art-deluxe上的 Kenney Platform Art Deluxe 捆綁包和在公共領(lǐng)域下可用。

繼續(xù)將該圖形添加到你的資產(chǎn)目錄,然后將你的ContentView結(jié)構(gòu)更改為:

這會(huì)在黑色背景下呈現(xiàn)外星人角色,使其更容易看到,并且由于它的大小可調(diào)整,SwiftUI 會(huì)將其拉伸以填充所有可用空間。

仔細(xì)觀察顏色的邊緣:它們看起來參差不齊,但也很模糊。鋸齒狀部分來自原始圖像,因?yàn)樗拇笮H為 66x92 像素,但模糊部分是 SwiftUI 在像素被拉伸時(shí)試圖混合像素以使拉伸不那么明顯的地方。

通常這種混合效果很好,但在這里很難,因?yàn)樵磮D片很?。ㄒ虼诵枰罅炕旌喜拍芤晕覀兿胍拇笮★@示),而且因?yàn)閳D像有很多純色所以混合像素很突出很明顯。

對(duì)于這種情況,SwiftUI 為我們提供了interpolation()修改器,讓我們可以控制像素混合的應(yīng)用方式。這有多個(gè)層次,但實(shí)際上我們只關(guān)心一個(gè):.none。這將完全關(guān)閉圖像插值,因此它們不會(huì)混合像素,而是會(huì)按比例放大并帶有銳利的邊緣。

因此,將你的圖像修改為:

現(xiàn)在你會(huì)看到外星人角色保留了它的像素化外觀,這不僅在復(fù)古游戲中特別受歡迎,而且對(duì)于線條藝術(shù)也很重要,因?yàn)榫€條藝術(shù)在模糊時(shí)看起來會(huì)很糟糕。


SwiftUI學(xué)習(xí)100天(Day80 - 項(xiàng)目 16,第二部分)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
喀喇| 资溪县| 延长县| 察隅县| 左贡县| 璧山县| 襄樊市| 鹿邑县| 南汇区| 台东市| 乐陵市| 东丰县| 平乡县| 休宁县| 乌鲁木齐市| 三明市| 屏东县| 定襄县| 焦作市| 合山市| 且末县| 夏河县| 工布江达县| 达拉特旗| 成安县| 泌阳县| 武胜县| 台前县| 赣州市| 于都县| 平乐县| 光山县| 永兴县| 莱芜市| 房产| 江油市| 道孚县| 井研县| 大丰市| 岚皋县| 明溪县|