溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SwiftUI中@ViewBuilder的原理和作用

發(fā)布時(shí)間:2021-07-08 17:16:03 來源:億速云 閱讀:1549 作者:chen 欄目:開發(fā)技術(shù)

這篇文章主要介紹“SwiftUI中@ViewBuilder的原理和作用”,在日常操作中,相信很多人在SwiftUI中@ViewBuilder的原理和作用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對(duì)大家解答”SwiftUI中@ViewBuilder的原理和作用”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

前言

在SwiftUI框架中使用很多的注解,雖然使語法看上去非常簡潔,但是增加了初學(xué)者的理解難度,這篇文章我們來看一下@ViewBuilder的相關(guān)知識(shí)。主要包括以下內(nèi)容:

  1. resultBuilder/functionBuilder是什么以及用法

  2. ViewBuilder結(jié)構(gòu)體

  3. @ViewBuilder修飾符的用法

  4. 使用@ViewBuilder完成一個(gè)自定義視圖

@resultBuilder注解

@resultBuilder是在Swift5.4添加的,之前是叫@_functionBuilder,在這里我們可以簡單了解一下它的作用。

一個(gè)類、結(jié)構(gòu)體添加@resultBuilder注解時(shí)必須包含至少一個(gè)buildBlock方法,并且這個(gè)方法是static靜態(tài)的。這個(gè)方法可以接收0個(gè)或多個(gè)參數(shù),在函數(shù)內(nèi)部確定了參數(shù)的組成形式。

比如下面這個(gè)例子:

@resultBuilder struct StringBuilder {
    static func buildBlock(_ string1: String, _ string2: String, _ string3: String) -> String {
        string1 + " - " + string2 + " - " + string3
    }
}

func test(@StringBuilder strings: () -> String) {
    print(strings())
}

test {
    "1"
    "2"
    "3"
}

StringBuilder是一個(gè)字符串構(gòu)建者結(jié)構(gòu)體,里面的buildBlock方法接收3個(gè)參數(shù),并且在3個(gè)參數(shù)中間插入” - “作為函數(shù)的返回值。

test函數(shù)接收一個(gè)使用@StringBuilder修飾的名為strings的閉包作為參數(shù),函數(shù)體是調(diào)用這個(gè)閉包并打印到控制臺(tái)。

最后使用3個(gè)字符串作為參數(shù)調(diào)用test函數(shù),執(zhí)行這段代碼后會(huì)得到”1 - 2 - 3”的輸出結(jié)果

@ViewBuilder定義

先來看ViewBuilder的定義:

@resultBuilder struct ViewBuilder

ViewBuilder本質(zhì)上是一個(gè)結(jié)構(gòu)體,并且被@resultBuilder注解,也就是說ViewBuilder是一個(gè)reult builder(結(jié)果建造者)類型了。

ViewBuilder結(jié)構(gòu)體有11個(gè)名為buildBlock的函數(shù),分別接收從0到10個(gè)View類型的參數(shù),因此在SwiftUI中一個(gè)接收@ViewBuilder類型參數(shù)的視圖容器最多能接收10個(gè)子視圖,如果不能滿足需求可以通過拆分來增加子視圖的個(gè)數(shù)。

@ViewBuilder的用法

使用@resultBuilder注解ViewBuilder結(jié)構(gòu)體后,就可以用@ViewBuilder修飾閉包,這個(gè)閉包可以接收多個(gè)指定類型的對(duì)象,而這些對(duì)象會(huì)按照buildBlock函數(shù)的實(shí)現(xiàn)進(jìn)行組織。

A custom parameter attribute that constructs views from closures.

這是Apple的官方文檔對(duì)ViewBuilder的定義,簡單來說ViewBuilder就是一個(gè)包含多個(gè)視圖的閉包。

在SwiftUI框架中,所有的容器視圖都是使用@ViewBuilder來修飾最后一個(gè)參數(shù),因此這些容器視圖可以接受多個(gè)子視圖作為參數(shù)。比如HStack/VStack/ScrollView等。

// HStack
public struct HStack<Content> : View where Content : View {
    ...

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

    ...
}

這是HStack的初始化方法,其中前面的幾個(gè)參數(shù)都是可選項(xiàng),它們不在本篇文章的討論范圍內(nèi)。

它的最后一個(gè)參數(shù)content的類型是一個(gè)返回值為Content的閉包,單看()->Content是一個(gè)沒有參數(shù)的閉包,但是前面使用了@ViewBuilder修飾,這就是一個(gè)可以接收多個(gè)視圖的閉包了,最終看起來像是這樣的:(view1: Content, view2: Content....) -> Content。

下面我們通過自定義一個(gè)視圖來看@ViewBuilder的用法。

實(shí)踐

下面通過實(shí)現(xiàn)一個(gè)自定義的容器視圖來展示@ViewBuilder的用法:

SwiftUI中@ViewBuilder的原理和作用

@ViewBuilder示例

自定義一個(gè)繼承自View名為CustomContainerView的視圖,它僅有一個(gè)接收@ViewBuilder類型參數(shù)的初始化方法,并使用常量content接收這個(gè)參數(shù)。

在body中構(gòu)建當(dāng)前視圖:@ViewBuilder中可能包含多個(gè)子視圖,因此使用VStack把這些子視圖縱向排列,之后使用多個(gè)視圖修改器自定義子視圖的外觀。

在源文件的第29行,ContentView中創(chuàng)建了CustomContainerView并給它傳遞了3個(gè)Text子視圖。通過Xcode右側(cè)的即時(shí)預(yù)覽可以看到這三個(gè)子視圖正是以我們?cè)贑ustomContainerView中要求的方式展現(xiàn)出來——縱向排列、綠色的背景色、紅色的文字顏色等。

總結(jié)

至此,關(guān)于@ViewBuilder的相關(guān)知識(shí)基本都涉及到了,相信通過本篇文章的學(xué)習(xí)你一定也對(duì)它有了一個(gè)非常全面的掌握,那么趕快到實(shí)戰(zhàn)項(xiàng)目中用起來吧?。

到此,關(guān)于“SwiftUI中@ViewBuilder的原理和作用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI