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

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

SwiftUI學習100天(Day44 - 項目 9,第二部分)

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

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

以下內容僅供學習參考:

今天,我們將通過一點點創(chuàng)意繼續(xù)我們對 SwiftUI 繪圖系統(tǒng)的了解——我想你會驚訝地發(fā)現(xiàn),只需將你所知道的大部分知識與一些新技術相結合,就可以如此輕松地制作出令人著迷的東西。

今天,你還將遇到drawingGroup()修改器,它讓我們可以將視圖渲染結合到由 Apple 的高性能圖形 API Metal 提供支持的單一過程中。過去很多人問我是否打算寫一本關于 Metal 的書,答案是否定的——不僅已經(jīng)有一本非常好的書了,而且從 API 中獲得任何好的東西也非常困難.

那不是因為 Metal 不好——相信我,它太棒了!– 而是因為 Apple 最優(yōu)秀的工程師在使用 Metal 時努力使 SwiftUI 盡可能高效,而且,坦率地說,我不太可能做得更好。

你會發(fā)現(xiàn),切換 Metal 并不是你經(jīng)常需要的事情,盡管這很容易做到。著名的軟件開發(fā)人員 Kent Beck 曾經(jīng)說過,我們的流程應該是“讓它工作、讓它正確、讓它快速”,他說得很對。但是,如果你發(fā)現(xiàn)你的繪圖在不切換到 Metal 的情況下工作速度很快,那么通常最好保持原樣。

不管怎樣,聊夠了——我說我們會做一些令人著迷的事情,所以讓我們開始吧!

今天,你要完成三個主題,在這些主題中你將了解CGAffineTransform、ImagePaintdrawingGroup()等等。

使用 CGAffineTransform 和奇偶填充變換形狀

當你超越簡單的形狀和路徑時,SwiftUI 的兩個有用功能將結合在一起,以非常少的工作創(chuàng)建一些美麗的效果。第一個是CGAffineTransform,它描述了路徑或視圖應該如何旋轉、縮放或剪切;第二個是(even-odd fills)奇偶填充,它允許我們控制重疊形狀的渲染方式。

為了演示這兩者,我們將用幾個旋轉的橢圓花瓣創(chuàng)建一個花的形狀,每個橢圓圍繞一個圓定位。這背后的數(shù)學原理相對簡單,有一個問題:CGAffineTransform用弧度而不是度數(shù)來測量角度。如果你上學已經(jīng)有一段時間了,你至少需要知道的是:3.141 弧度等于 180 度,所以 3.141 弧度乘以 2 等于 360 度。3.141 并非巧合:實際值是數(shù)學常數(shù) pi。

所以,我們要做的是:

  • 創(chuàng)建一個新的空路徑。

  • 從 0 數(shù)到 pi 乘以 2(以弧度表示的 360 度),每次以 pi 的八分之一計數(shù)——這將給我們 16 個花瓣。

  • 創(chuàng)建等于當前數(shù)字的旋轉變換。

  • 添加到該旋轉等于我們繪制空間寬度和高度的一半的運動,因此每個花瓣都以我們的形狀為中心。

  • 為花瓣創(chuàng)建一條新路徑,等于特定大小的橢圓。

  • 將我們的變換應用于該橢圓,使其移動到位。

  • 將該花瓣的路徑添加到我們的主路徑中。

一旦你看到代碼正在運行,這將更有意義,但首先我想添加三件小事:

  1. 旋轉然后移動它不會產(chǎn)生與移動然后旋轉相同的結果,因為當你先旋轉它時它移動的方向將與它不旋轉時不同。

  2. 為了真正幫助你了解正在發(fā)生的事情,我們將使我們的花瓣橢圓使用一些我們可以從外部傳入的屬性。

  3. 如果你想一次數(shù)一個數(shù),那么范圍1...5非常好,但是如果你想以 2 秒為單位進行計數(shù),或者在我們的例子中以“pi/8”為單位進行計數(shù),則應該改用stride(from:to:by:)。

好了,廢話不多說了——現(xiàn)在將這個形狀添加到你的項目中:

我意識到這是相當多的代碼,但希望當你嘗試它時它會變得更加清晰。將你的ContentView修改為:

現(xiàn)在試試看。一旦開始拖動偏移量和寬度滑塊,你應該能夠準確地看到代碼是如何工作的——它只是一系列旋轉的橢圓,以圓形形式放置。

這本身就很有趣,但是通過一個小的改變,我們可以從有趣變成崇高。如果你看一下我們畫橢圓的方式,它們經(jīng)常重疊——有時一個橢圓畫在另一個橢圓上,有時畫在其他幾個橢圓上。

如果我們使用純色填充我們的路徑,我們會得到一個相當不起眼的結果。試試這樣:

但作為替代方案,我們可以使用奇偶規(guī)則填充形狀,該規(guī)則決定是否應根據(jù)路徑包含的重疊部分對路徑的一部分進行著色。它是這樣工作的:

  • 如果路徑?jīng)]有重疊,它將被填充。

  • 如果另一條路徑與其重疊,則重疊部分將不會被填充。

  • 如果第三條路徑與前兩條路徑重疊,則它將被填充。

  • …等等。

只有實際重疊的部分受此規(guī)則影響,它會產(chǎn)生一些非常漂亮的結果。更好的是,Swift UI 使它的使用變得簡單,因為每當我們一個形狀上調用fill()時,我們都可以傳遞一個FillStyle結構,要求啟用奇偶規(guī)則。

試試這個:

現(xiàn)在運行程序并開始游戲——老實說,考慮到我們所做的工作如此之少,結果非常令人著迷!


使用 ImagePaint 的創(chuàng)意邊框和填充

SwiftUI 嚴重依賴協(xié)議,這在處理繪圖時可能會有點混亂。例如,我們可以用Color作視圖,但它也符合ShapeStyle?- 用于填充、描邊和邊框的不同協(xié)議。

實際上,這意味著我們可以修改默認文本視圖,使其具有紅色背景:

或紅色邊框:

相反,我們可以使用圖像作為背景:

但是使用相同的圖像作為邊框是行不通的:

如果你考慮一下,這是有道理的——除非圖像的尺寸完全正確,否則你幾乎無法控制它的外觀。

為了解決這個問題,SwiftUI 為我們提供了一種專用類型,它以一種我們可以完全控制圖像呈現(xiàn)方式的方式包裝圖像,這反過來意味著我們可以毫無問題地將它們用于邊框和填充。

該類型稱為ImagePaint,它是使用一到三個參數(shù)創(chuàng)建的。至少你需要給它一個Image作為它的第一個參數(shù)的工作,但你也可以在該圖像中提供一個矩形以用作在 0 到 1 范圍內指定的繪圖源(第二個參數(shù)),以及該圖像的比例(第三個參數(shù))。第二個和第三個參數(shù)具有合理的默認值“整個圖像”和“100% 比例”,因此你有時可以忽略它們。

例如,我們可以使用 0.2 的比例渲染示例圖像,這意味著它以正常尺寸的 1/5 顯示:

如果你想嘗試使用sourceRect參數(shù),請確保你傳入了CGRect相對大小和位置的參數(shù):0 表示“開始”,1 表示“結束”。例如,這將顯示示例圖像的整個寬度,但只顯示中間的一半:

值得添加的是,ImagePaint可用于視圖背景和形狀筆觸。例如,我們可以創(chuàng)建一個膠囊,我們的示例圖像平鋪為其筆畫:

ImagePaint將自動繼續(xù)平鋪其圖像,直到填滿其區(qū)域——它可以處理任何大小的背景、筆觸、邊框和填充。

使用 drawingGroup() 啟用高性能 Metal 渲染

SwiftUI 默認使用 Core Animation 進行渲染,它提供了開箱即用的出色性能。然而,對于復雜的渲染,你可能會發(fā)現(xiàn)你的代碼開始變慢——任何低于每秒 60 幀 (FPS) 的東西都是一個問題,但實際上你應該瞄準更高的目標,因為許多 iOS 設備現(xiàn)在以 120fps 渲染。

為了證明這一點,讓我們看一些示例代碼。我們將創(chuàng)建一個顏色循環(huán)視圖,以一系列顏色呈現(xiàn)同心圓。結果看起來像徑向漸變,但我們將添加兩個屬性以使其更具可定制性:一個用于控制應繪制多少個圓圈,另一個用于控制顏色循環(huán)——它將能夠移動漸變開始和結束顏色。

我們可以通過使用Color(hue:saturation:brightness:)初始化器獲得顏色循環(huán)效果:色調是一個從 0 到 1 的值,控制著我們看到的顏色種類——紅色既是 0 又是 1,所有其他色調都介于兩者之間。為了計算出特定圓圈的色調,我們可以用圓圈數(shù)(例如 25)除以圓圈數(shù)(例如 100),然后加上我們的顏色循環(huán)量(例如 0.5)。所以,如果我們是 100 的第 25 圈,循環(huán)量為 0.5,我們的色調將為 0.75。

這里的一個小復雜性是色調在我們達到 1.0 后不會自動換行,這意味著 1.0 的色調等于 0.0 的色調,但 1.2 的色調不等于 0.2 的色調。因此,我們將手動包裝色調:如果它超過 1.0,我們將減去 1.0,以確保它始終位于 0.0 到 1.0 的范圍內。

這是代碼:

我們現(xiàn)在可以在布局中使用它,將其顏色循環(huán)綁定到由滑塊控制的本地屬性:

如果你運行該應用程序,你會看到我們有一個整潔的彩色波浪效果,完全通過在滑塊周圍拖動來控制,而且效果非常流暢。

你現(xiàn)在看到的是由 Core Animation 提供支持的,這意味著它將把我們的 100 個圓圈變成 100 個單獨的視圖繪制到屏幕上。這在計算上是昂貴的,但正如你所見,它運行良好——我們獲得了平穩(wěn)的性能。

然而,如果我們稍微增加復雜性,我們會發(fā)現(xiàn)事情并不那么樂觀。用這個strokeBorder()替換現(xiàn)有的修改器:

現(xiàn)在呈現(xiàn)出柔和的漸變,在圓圈頂部顯示明亮的顏色,在底部顯示較暗的顏色?,F(xiàn)在,當你運行該應用程序時,你會發(fā)現(xiàn)它的運行速度要慢得多——SwiftUI 正在努力渲染 100 個漸變作為 100 個獨立視圖的一部分。

我們可以通過應用一個名為drawingGroup().?這告訴 SwiftUI 它應該將視圖的內容渲染到屏幕外圖像中,然后再將其作為單個渲染輸出放回到屏幕上,這樣速度要快得多。在幕后,這是由 Metal 提供支持的,Metal 是 Apple 的框架,用于直接與 GPU 一起工作以獲得極快的圖形。

因此,將ColorCyclingCircle正文修改為:

現(xiàn)在再次運行它 - 有了這個微小的添加,您現(xiàn)在會發(fā)現(xiàn)我們得到了正確渲染的所有內容,并且即使使用漸變,我們也可以全速返回。

重要提示:了解修飾符并保存在你的drawingGroup()武器庫中有助于解決性能問題,但你不應該經(jīng)常使用它。添加離屏渲染通道可能會降低 SwiftUI 的簡單繪圖速度,因此你應該等到遇到實際性能問題后再嘗試引入drawingGroup().


SwiftUI學習100天(Day44 - 項目 9,第二部分)的評論 (共 條)

分享到微博請遵守國家法律
三亚市| 徐水县| 渝中区| 迭部县| 长宁县| 安康市| 门头沟区| 澄江县| 刚察县| 博野县| 壤塘县| 德惠市| 新兴县| 密山市| 板桥市| 丰原市| 广安市| 宁明县| 鹤岗市| 泽州县| 鹤山市| 宿州市| 通城县| 平远县| 武汉市| 石首市| 永登县| 龙州县| 淅川县| 广饶县| 洞头县| 湘乡市| 皋兰县| 台北县| 邵武市| 安达市| 彩票| 尚志市| 株洲县| 柞水县| 塔城市|