iOS 用SwiftUI寫一個(gè)簡單頁面

前言:
之前同事WYongW寫了一篇《用Flutter寫一個(gè)簡單頁面》,本篇將和大家一起調(diào)研一下蘋果今年推出的SwiftUI框架。
接下來,讓我們一起入門一下SwiftUI(嘗嘗鮮)。


一、SwiftUI是什么?

1. 定義:

簡單來說,SwiftUI是蘋果在“WWDC-2019”推出的一款全新的“聲明式UI”框架。
拆開看,Swift + UI。(由此可以看出Swift越來越重要)

2. 特點(diǎn):
  • “簡潔迅速”的Swift:越來越簡潔的Swift語法,配上Swift迅速的優(yōu)勢。

  • “即視”的UI:降低調(diào)試成本,一邊寫code、一邊就可查看UI。

  • 跨平臺(tái):一套代碼,即可完成iOS、iPadOSmacOS、watchOS的開發(fā)與適配。

  • “聲明式”編程

簡單來說,對(duì)比之前的“指令式”編程,我們通常需要告訴計(jì)算機(jī)“怎么做”?
“聲明式”編程是讓我們告訴計(jì)算機(jī)“做什么”?(至于最底層怎么做,我們無需關(guān)心。)

舉個(gè)例子,對(duì)于寫UI而言,

  • 指令式編程:就是,怎么畫?把每個(gè)frame、layout等等統(tǒng)統(tǒng)需要計(jì)算到位。
  • 聲明式編程:就是,畫什么?把想要的效果描述出來,其他都交給框架去做。
3. 開發(fā)環(huán)境:

這么新的技術(shù)肯定需要環(huán)境的支持。SwiftUI所需要的開發(fā)環(huán)境,如下:

  • Xcode:Xcode 11.1+
  • MacOS:MacOS 10.15+。
  • iOS:iOS 13+。

PS:由于SwiftUI只能應(yīng)用與iOS 13系統(tǒng)以上的設(shè)備。
因此,這項(xiàng)技術(shù)不建議用在需要適配低版本(iOS 13 以下)的App上。
不過如果是無需適配低版本的新項(xiàng)目,或者學(xué)習(xí)者全可以上手“玩一玩”。
畢竟蘋果的新技術(shù)還是很有意思的嘛~

二、SwiftUI的基本組件(語法)

這塊知識(shí)比較“基礎(chǔ)”且“重要”。只有記住了這些基本組件,我們才能用較少的代碼開發(fā)出精美的App。

下面,我將給大家介紹一些重要的SwiftUI組件:

組件介紹:

名稱 含義
Text 用來顯示文本的組件,類似UIKit中的UILabel
Image 用來展示圖片的組件,類似UIKit中的UIImageView
Button 用于可點(diǎn)擊的按鈕組件,類似UIKit中的UIButton。
List 用來展示列表的組件,類似UIKit中的UITableView。
ScrollView 用來支持滑動(dòng)的組件,類似UIKit中的UIScrollView。
Spacer 一個(gè)靈活的空間,用來填充空白的組件。
Divider 一條分割線,用來劃分區(qū)域的組件。
VStack 將子視圖按“豎直方向”排列布局。(Vertical stack
HStack 將子視圖按“水平方向”排列布局。(Horizontal stack
ZStack 將子視圖按“兩軸方向均對(duì)齊”布局(居中,有重疊效果)

基本組件:

  • Text:用來顯示文本的組件,類似UIKit中的UILabel
Text("Hello, we are QiShare!").foregroundColor(.blue).font(.system(size: 32.0))
  • Image:用來展示圖片的組件,類似UIKit中的UIImageView
Image.init(systemName: "star.fill").foregroundColor(.yellow)
  • Button:用于可點(diǎn)擊的按鈕組件,類似UIKit中的UIButton
Button(action: { self.showingProfile.toggle() }) {
    Image(systemName: "paperplane.fill")
        .imageScale(.large)
        .accessibility(label: Text("Right"))
        .padding()
}
  • List:用來展示列表的組件,類似UIKit中的UITableView。
List(0..<5){_ in
        NavigationLink.init(destination: VStack(alignment:.center){
            Image.init(systemName: "\(item+1).square.fill").foregroundColor(.green)
            Text("詳情界面\(item + 1)").font(.system(size: 16))
    }) {
          //ListRow
       }
  • ScrollView:用來支持滑動(dòng)的組件,類似UIKit中的UIScrollView。

  • Spacer:一個(gè)靈活的空間,用來填充空白的組件。

  • Divider:一條分割線,用來劃分區(qū)域的組件。

布局組件:

  • VStack:將子視圖按“豎直方向”布局。(Vertical stack)

  • HStack:將子視圖按“水平方向”布局。(Horizontal stack)

  • ZStack:將子視圖按“兩軸方向均對(duì)齊”布局。

功能組件:

  • NavigationView:負(fù)責(zé)App中導(dǎo)航功能的組件,類似UIKit中的UINavigationView。

  • NavigationLink:負(fù)責(zé)App頁面跳轉(zhuǎn)的組件,類似于UINavigationView中的pushpop功能。

NavigationView {
    List(0..<5){_ in
        NavigationLink.init(destination: VStack(alignment:.center){
            Image.init(systemName: "\(item+1).square.fill").foregroundColor(.green)
            Text("詳情界面\(item + 1)").font(.system(size: 16))
    }) {
          //ListRow
       }
}
.navigationBarTitle("導(dǎo)航\(item)",displayMode: .inline)
  • TabView:負(fù)責(zé)App中的標(biāo)簽頁功能的組件,類似UIKit中的UITabBarController。
TabView {
    Text("The First Tab")
        .tabItem {
            Image(systemName: "1.square.fill")
            Text("First")
        }
    Text("Another Tab")
        .tabItem {
            Image(systemName: "2.square.fill")
            Text("Second")
        }
    Text("The Last Tab")
        .tabItem {
            Image(systemName: "3.square.fill")
            Text("Third")
        }
}
.font(.headline)

三、SwiftUI快速上手實(shí)踐

下面讓我們快速實(shí)現(xiàn)一個(gè)有TabView、NavigationView、List的Demo。

SF Symbols 是從 iOS 13macOS 10.15 開始內(nèi)置于系統(tǒng)中的字符圖標(biāo)庫,它提供了上千種常見的線條圖標(biāo),而且我們可以任意地為它們?cè)O(shè)置尺寸,顏色等屬性。Apple 甚至準(zhǔn)備了專門的app:SF Symbols 來幫助你查看可用的符號(hào):

接下來就讓我們用這些Symbols制作個(gè)小Demo。

  • ContentView:
import SwiftUI

struct ContentView: View {
    
    @State var isLeftNav = false
    @State var isRightNav = false
    
    init() {
        //修改導(dǎo)航欄文字顏色
        UINavigationBar.appearance().largeTitleTextAttributes = [.foregroundColor: UIColor.systemBlue]
        UINavigationBar.appearance().titleTextAttributes = [.foregroundColor: UIColor.systemBlue]
        UINavigationBar.appearance().tintColor = .systemBlue
    }
    
    var body: some View {
        TabView {
            
            // Tab1:
            NavigationView {
                List(Symbols, id:\.self) {
                    ListRow(symbol: $0)
                }
                .navigationBarTitle(Text("SF Symbols"))
                .navigationBarItems(leading: leftNavButton, trailing: rightNavButton)
            }.tabItem {
                Image.init(systemName: "star.fill")
                Text("Tab1").font(.subheadline)
            }
            
            // Tab2:
            NavigationView {
                Text("This is the second tab.")
            }.tabItem {
                Image.init(systemName: "star.fill")
                Text("Tab2").font(.subheadline)
            }
        }
    }
    
    var leftNavButton: some View {
        Button(action: { self.isLeftNav.toggle() }) {
            Image(systemName: "person.crop.circle")
                .imageScale(.large)
                .accessibility(label: Text("Left"))
                .padding()
        }
        .sheet(isPresented: $isLeftNav) {
            VStack {
                Text("Hello, we are QiShare!").foregroundColor(.blue).font(.system(size: 32.0))

                HStack {
                    Spacer()
                    Spacer()
                    Text("an iOS Team. ").fontWeight(.black).foregroundColor(.purple)
                    Spacer()
                    Text("We are learning SwiftUI.").foregroundColor(.blue)
                    Spacer()
                }
            }
        }
    }
    
    var rightNavButton: some View {
        Button(action: { self.isRightNav.toggle() }) {
            Image(systemName: "paperplane.fill")
                .imageScale(.large)
                .accessibility(label: Text("Right"))
                .padding()
        }
        .sheet(isPresented: $isRightNav, onDismiss: {
            print("dissmiss RrightNav")
        }) {
            ZStack {
                Text("This is the Right Navi Button.")
            }
        }
    }
}
  • ListRow:List對(duì)應(yīng)的Cell
struct ListRow: View {
    var symbol: String
    var body: some View {
        NavigationLink(destination: ListDetail(symbol: symbol)) {
            
            HStack {
                //圖片
                Image(systemName: symbol)
                    .resizable()
                    .frame(width: 60, height: 60)
                    .foregroundColor(Colors.randomElement())
                //分割
                Divider()
                Spacer()
                //文字
                Text(symbol)
                Spacer()
            }
        }
    }
}
  • ListDetail:
import SwiftUI

struct ListDetail: View {
    
    var symbol: String
    
    var body: some View {
        VStack {
            
            Text("Image:").font(.headline)
            
            Spacer()
            
            Image(systemName: symbol)
                .foregroundColor(Colors.randomElement())
                .imageScale(.large)
                .scaleEffect(3)
                .padding(.bottom, 100)
            
            Divider()
            
            Text("Image Name:").font(.headline)
            Spacer()
            Text(symbol)
                .font(.largeTitle)
            Spacer()
        }
        .navigationBarTitle(symbol)
    }
}

源碼:本文Demo

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

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

  • 級(jí)別:★☆☆☆☆標(biāo)簽:「iOS 13」「SwiftUI」「Xcode 11.1」作者: 647 審校: QiSh...
    QiShare閱讀 4,783評(píng)論 0 9
  • 昨夜風(fēng)起云聚,三更幾番風(fēng)雨。 臥榻輾轉(zhuǎn)眠,薄棉難掩思緒。 歸去,歸去,門前菊葉正綠。
    鎰小新閱讀 662評(píng)論 0 0
  • #29/100天詩歌意象打卡#1106 柴門、巖扉、松徑柴門、巖扉、松徑是表現(xiàn)隱逸生活典型的意象場景。這類遠(yuǎn)離人寰...
    二小咸閱讀 640評(píng)論 0 2
  • 啰嗦現(xiàn)在的愿望就是能睡好吃好。多么簡單的生存之道,在啰嗦這里變成了觸不可及的奢侈。時(shí)空是永恒的,變的只是人。以前覺...
    天賦還沒用到閱讀 272評(píng)論 1 1
  • 小時(shí)候,沒心沒肺, 做什么都很快樂。 長大了,連吃也成了一種負(fù)擔(dān)。 不必精心計(jì)算卡路里, 每天多一點(diǎn)運(yùn)動(dòng), 不要放...
    單宇涵閱讀 635評(píng)論 0 1

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