【Swift】100 Days of SwiftUI筆記(23-25)

筆記

本篇文章記錄一下100 Days of SwiftUI第23-25天的筆記內(nèi)容

為什么 SwiftUI 使用結(jié)構(gòu)體作為視圖伴箩?

// 性能因素:結(jié)構(gòu)比類更簡單、更快
// 迫使我們考慮以一種干凈的方式隔離狀態(tài)贬堵,因為類可以自由更改其值带族,這可能會導(dǎo)致代碼更加混亂
// 如果在視圖中使用類锁荔,可能會發(fā)現(xiàn)的代碼無法編譯或在運行時崩潰,所以使用結(jié)構(gòu)

SwiftUI 主視圖背后是什么炉菲?

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
            .padding()
            .background(.red)
    }
}
// 這樣并不能實現(xiàn)整個屏幕為紅色堕战,因為Text背后沒有任何東西坤溃,想要整個屏幕為紅色應(yīng)該讓Text占據(jù)整個屏幕的空間
Text("Hello, world!")
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(.red)

為什么修飾符順序很重要拍霜?

Button("Hello, world!") {
    // do nothing
}    
.background(.red)
.frame(width: 200, height: 200)
// 以上的代碼顯示效果并不會看到帶有“Hello, world!”的200x200紅色按鈕嘱丢,而是看到一個200x200的空方塊,上面寫著“Hello, world!” 位于中間祠饺,并在“Hello, world!”周圍有一個紅色矩形
// 這是因為:每個修飾符都會應(yīng)用該修飾符創(chuàng)建一個新結(jié)構(gòu)越驻,而不是僅僅在視圖上設(shè)置屬性
print(type(of: self.body))
// 打印ModifiedContent<ModifiedContent<Button<Text>, _BackgroundStyleModifier<Color>>, _FrameLayout>
// 1.每次我們修改視圖時,SwiftUI 都會通過使用泛型來應(yīng)用該修飾符:ModifiedContent<OurThing, OurModifier>道偷。
// 2.當(dāng)我們應(yīng)用多個修飾符時缀旁,它們只會疊加:ModifiedContent<ModifiedContent<…
// 3.要讀取類型是什么,請從最里面的類型開始并逐步解決勺鸦,每個類型都需要一個要轉(zhuǎn)換的視圖以及要進行的實際更改并巍,而不是直接修改視圖,所以首先按鈕有一些應(yīng)用了背景顏色的文本换途,然后給它一個更大的框架

為什么 SwiftUI 使用“some View”作為其視圖類型懊渡?

// 1.對性能很重要,SwiftUI 需要能夠查看我們顯示的視圖并了解它們?nèi)绾巫兓猓员闼梢哉_更新用戶界面
// 2.因為 SwiftUI 使用ModifiedContent剃执,該View協(xié)議有一個關(guān)聯(lián)的類型,所以View它本身沒有任何意義懈息,我們需要確切地說出它是什么類型的視圖

// VStack是如何工作的肾档?
// 使用VStack時SwiftUI會創(chuàng)建一個TupleView,包含VStack中的視圖辫继,TupleView只能處理10個視圖怒见,也就是為什么SwiftUI 不允許父級內(nèi)部有超過 10 個視圖的原因

// body中創(chuàng)建視圖會做什么處理?
// 與VStack原理相同也是創(chuàng)建一個TupleView包含這些視圖姑宽,并設(shè)置給body的@ViewBuilder這個特殊屬性

條件修飾符

// 通常希望修飾符僅在滿足特定條件時應(yīng)用遣耍,而在 SwiftUI 中,最簡單的方法是使用三元條件運算符
struct ContentView: View {
    @State private var useRedText = false

    var body: some View {
        Button("Hello World") {
            // flip the Boolean between true and false
            useRedText.toggle()            
        }
        .foregroundColor(useRedText ? .red : .blue)
    }
}

環(huán)境修飾符

// 許多修飾符可以應(yīng)用于容器低千,這允許我們同時將相同的修飾符應(yīng)用于多個視圖
VStack {
    Text("Gryffindor")
        .font(.largeTitle) // 子視圖中的修飾符任會替換相同的環(huán)境修飾符配阵,Gryffindor會具有大標(biāo)題
    Text("Hufflepuff")
    Text("Ravenclaw")
    Text("Slytherin")
}
.font(.title)
// 由上述特性可以知道font()是一個環(huán)境修飾符

VStack {
    Text("Gryffindor")
        .blur(radius: 0)
    Text("Hufflepuff")
    Text("Ravenclaw")
    Text("Slytherin")
}
.blur(radius: 5)
// 而blur()是一個常規(guī)修改器,因此應(yīng)用于子視圖的任何模糊都會添加到VStack模糊中示血,而不是替換它

視圖作為屬性

// 有很多方法可以讓您更輕松地在 SwiftUI 中使用復(fù)雜的視圖層次結(jié)構(gòu)棋傍,其中一種選擇是使用屬性 
// 創(chuàng)建一個視圖作為您自己視圖的屬性,然后在布局中使用該屬性
struct ContentView: View {
    let motto1 = Text("Draco dormiens")
    let motto2 = Text("nunquam titillandus")

    var body: some View {
        VStack {
            motto1
                .foregroundColor(.red)
            motto2
                .foregroundColor(.blue)
        }
    }
}

// Swift 不允許我們創(chuàng)建一個引用其他存儲屬性的存儲屬性难审,因為這會在創(chuàng)建對象時引起問題
// 這意味著嘗試創(chuàng)建TextField與本地屬性的綁定將會導(dǎo)致問題
// 但是可以創(chuàng)建計算屬性
var motto1: some View {
    Text("Draco dormiens")
}

// 但是與body不用瘫拣,Swift 不會自動@ViewBuilder在此處應(yīng)用該屬性,因此如果想返回多個視圖還需要調(diào)整告喊,提供一下3種方式
// 1.將視圖放在堆棧中
var spells: some View {
    VStack {
        Text("Lumos")
        Text("Obliviate")
    }
}

// 2.返回一個Group
var spells: some View {
    Group {
        Text("Lumos")
        Text("Obliviate")
    }
}

// 3.自己添加@ViewBuilder屬性
@ViewBuilder var spells: some View {
    Text("Lumos")
    Text("Obliviate")
}

視圖組成

// SwiftUI 允許我們將復(fù)雜的視圖分解為更小的視圖麸拄,而不會產(chǎn)生太大的性能影響
struct ContentView: View {
    var body: some View {
        VStack(spacing: 10) {
            Text("First")
                .font(.largeTitle)
                .padding()
                .foregroundColor(.white)
                .background(.blue)
                .clipShape(Capsule())

            Text("Second")
                .font(.largeTitle)
                .padding()
                .foregroundColor(.white)
                .background(.blue)
                .clipShape(Capsule())
        }
    }
}
// 可以修改為:
struct CapsuleText: View {
    var text: String

    var body: some View {
        Text(text)
            .font(.largeTitle)
            .padding()
            .foregroundColor(.white)
            .background(.blue)
            .clipShape(Capsule())
    }
}

struct ContentView: View {
    var body: some View {
        VStack(spacing: 10) {
            CapsuleText(text: "First")
            CapsuleText(text: "Second")
        }
    }
}

自定義修飾符

// SwiftUI允許創(chuàng)建執(zhí)行特定操作的自定義修飾符
// 創(chuàng)建一個符合ViewModifier協(xié)議的新結(jié)構(gòu)派昧,且必須調(diào)用body方法接受要使用的內(nèi)容,并且必須返回some View
struct Title: ViewModifier {
    func body(content: Content) -> some View {
        content
            .font(.largeTitle)
            .foregroundColor(.white)
            .padding()
            .background(.blue)
            .clipShape(RoundedRectangle(cornerRadius: 10))
    }
}

Text("Hello World")
    .modifier(Title())

// 使用自定義修飾符時拢切,j建議創(chuàng)建View擴展使用
extension View {
    func titleStyle() -> some View {
        modifier(Title())
    }
}

Text("Hello World")
    .titleStyle()

// 自定義修飾符還可以根據(jù)需要創(chuàng)建新的視圖結(jié)構(gòu)
struct Watermark: ViewModifier {
    var text: String

    func body(content: Content) -> some View {
        ZStack(alignment: .bottomTrailing) {
            content
            Text(text)
                .font(.caption)
                .foregroundColor(.white)
                .padding(5)
                .background(.black)
        }
    }
}

extension View {
    func watermarked(with text: String) -> some View {
        modifier(Watermark(text: text))
    }
}

Color.blue
    .frame(width: 300, height: 200)
    .watermarked(with: "Hacking with Swift")
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蒂萎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子淮椰,更是在濱河造成了極大的恐慌五慈,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件主穗,死亡現(xiàn)場離奇詭異泻拦,居然都是意外死亡,警方通過查閱死者的電腦和手機忽媒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門争拐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人晦雨,你說我怎么就攤上這事架曹。” “怎么了金赦?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵音瓷,是天一觀的道長。 經(jīng)常有香客問我夹抗,道長绳慎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任漠烧,我火速辦了婚禮杏愤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘已脓。我一直安慰自己珊楼,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布度液。 她就那樣靜靜地躺著厕宗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪堕担。 梳的紋絲不亂的頭發(fā)上已慢,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機與錄音霹购,去河邊找鬼佑惠。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的膜楷。 我是一名探鬼主播旭咽,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼赌厅!你這毒婦竟也來了穷绵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤察蹲,失蹤者是張志新(化名)和其女友劉穎请垛,沒想到半個月后催训,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洽议,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年漫拭,在試婚紗的時候發(fā)現(xiàn)自己被綠了亚兄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡采驻,死狀恐怖审胚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情礼旅,我是刑警寧澤膳叨,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站痘系,受9級特大地震影響菲嘴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜汰翠,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一龄坪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧复唤,春花似錦健田、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至呈宇,卻和暖如春好爬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背攒盈。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工抵拘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人型豁。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓僵蛛,卻偏偏與公主長得像尚蝌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子充尉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容