iOS SwiftUI基礎(chǔ)學習(三)

第七節(jié) 正向傳值
在之前我們已經(jīng)完成了跳轉(zhuǎn)的部分,但是只是跳轉(zhuǎn)到一個Text View,現(xiàn)在我們新建一個SwiftUI View:SceneryView.swift 文件,用來顯示跳轉(zhuǎn)后的頁面



在新的頁面,我們先創(chuàng)建好所需的視圖,這里我們采用 ZStack 深淺的布局,使得圖片和文字疊加

struct SceneryView: View {
    var body: some View {
        ZStack {
            Image("埃及-金字塔-黃昏")
            Text("埃及")
        }
    }
}

為了能夠在這個頁面接收上一個頁面?zhèn)鬟M來的值,我們定義一個屬性 “scenery”
這個時候在下面的 SceneryView_Previews 預覽代碼就會提示我們,我們定義了一個值,但是沒有進行傳值操作
我們點擊“Fix”自動修復,填入我們之前定義的sceneries數(shù)組


struct SceneryView_Previews: PreviewProvider {
    static var previews: some View {
        SceneryView(scenery: sceneries[0])
    }
}

我們可以發(fā)現(xiàn),在每一個SwiftUI View下方都有一個Previews,它的作用就是讓我們可以調(diào)試數(shù)據(jù),然后預覽效果。它只會在debug狀態(tài)下有效,在運行后這部分的代碼的不會有效的。
我們將代碼修改一下如圖所示,可以看到在Previews中可以測試我們需要顯示的內(nèi)容



然后回到第一個頁面,將跳轉(zhuǎn)的destination目標改為我們新建的SceneryView,并且參照剛才Presviews的代碼,我們寫下如下代碼



這時候點擊右邊畫布的,就可以發(fā)現(xiàn)我們已經(jīng)實現(xiàn)了正向傳值了。
最后我們完善一下SceneryView的布局設置
struct SceneryView: View {
    
    let scenery: Scenery
    
    var body: some View {
        
        // 對齊方式:底部右對齊
        ZStack(alignment: .bottomTrailing) {
            Image(scenery.imageName)
                // 讓圖片不超出父控件范圍
                .resizable()
                // 自適應比例模式
                .aspectRatio(contentMode: .fit)
                // 設置最小、最大寬高
                .frame(minWidth: 0, idealWidth: 0, maxWidth: .infinity, minHeight: 0, idealHeight: 0, maxHeight: .infinity, alignment: .center)
            Text(scenery.location)
                // 字體
                .font(.largeTitle)
                // 四周邊距
                .padding()
                // 顏色
                .foregroundColor(.secondary)
        }
        // 導航欄顯示樣式為inline
        .navigationBarTitle(Text(scenery.name), displayMode: .inline)
    }
}

這里是.infinity是指無窮大,結(jié)合.resizble和.fit的限制,圖片就會在當前區(qū)域自動尋找到最合適的高度,這個應該比較好理解
根據(jù)截圖可以看出Image和Text的區(qū)域



第八節(jié) 狀態(tài)綁定和縮放動畫
為了達到點擊圖片出現(xiàn)縮放的效果,我們需要給圖片添加一個點擊手勢事件,并且需要用一個變量來記錄點擊的狀態(tài),這個我們就需要使用到狀態(tài)綁定這個知識點。
關(guān)于@State的說明:加了@State注解的變量,視圖通過監(jiān)視和讀取該變量來重新渲染UI。其狀態(tài)是由SwiftUI來存儲管理的,作為視圖渲染的單一可信來源。
意思也很簡單,就是一旦使用了@State修飾變量,一旦變量的值發(fā)生改變,SwiftUI就會自動刷新頁面,不需要我們手動去刷新。
我們在View中定義一個用來記錄縮放的變量zoomed,然后根據(jù)zoomed的狀態(tài)來改變圖片的顯示模式,代碼如下

struct SceneryView: View {
    
    let scenery: Scenery
    @State var zoomed = false
    
    var body: some View {
        
        // 對齊方式:底部右對齊
        ZStack(alignment: .bottomTrailing) {
            Image(scenery.imageName)
                // 讓圖片不超出父控件范圍
                .resizable()
                // 根據(jù)zoomed狀態(tài)進行調(diào)整
                .aspectRatio(contentMode: zoomed ? .fill : .fit)
                // 設置最小、最大寬高
                .frame(minWidth: 0, idealWidth: 0, maxWidth: .infinity, minHeight: 0, idealHeight: 0, maxHeight: .infinity, alignment: .center)
                .onTapGesture {
                    // toggle相當于對值取反
                    zoomed.toggle()
                }
            Text(scenery.location)
                // 字體
                .font(.largeTitle)
                // 四周邊距
                .padding()
                // 顏色
                .foregroundColor(.secondary)
        }
        // 導航欄顯示樣式為inline
        .navigationBarTitle(Text(scenery.name), displayMode: .inline)
    }
}

到這里我們就實現(xiàn)了圖片點擊縮放的效果,也是超級簡單。得力于@State狀態(tài)綁定的特性,我們可以很快捷的得到我們想看到的預覽效果。
接下來我們再給縮放添加一個簡單動畫效果:withAnimation

.onTapGesture {
      // toggle相當于對值取反
      withAnimation {
            zoomed.toggle()
      }
}

完成了圖片的處理,緊接著我們開始對Text View的動畫進行處理
首先我們完成消失/顯示的處理

if !zoomed {
    Text(scenery.location)
           .font(.largeTitle)
           .foregroundColor(.secondary)
           .padding()
}

這里就是表示當zoomed為false時,顯示Text View,為true時隱藏Text View。
另外還有一個向右邊移動的動畫,這個時候我們需要使用到 transition
在SwiftUI中,transition決定了某個View如何插入到視圖棧中,或者如何在視圖棧中移除。transition自身并沒有任何效果, 需要配合動畫一起使用

if !zoomed {
    Text(scenery.location)
           .font(.largeTitle)
           .foregroundColor(.secondary)
           .padding()
           // 向右邊邊距移動
           .transition(.move(edge: .trailing))
}

到這里我們所有的代碼都寫完了,可以說總共不到一百行的代碼,卻實現(xiàn)了很多內(nèi)容。不得不說SwiftUI是真的簡潔好用,已經(jīng)不想寫OC的代碼了,哈哈哈。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容