SwiftUI快速入門

SwiftUI 是一種非常簡單的創(chuàng)新方法,可以利用 Swift 的強大能力在所有蘋果設備平臺上構建用戶界面。通過 SwiftUI,開發(fā)者僅使用一組工具和 API 就能為所有蘋果設備構建用戶界面。SwiftUI 使用易于閱讀和編寫的聲明式 Swift 語法,可與新的 Xcode 設計工具無縫協(xié)作,使你的代碼和設計完美同步。SwiftUI 自動支持動態(tài)類型、黑暗模式、本地化和可訪問性,你的 SwiftUI 代碼將成為你寫過的最強大的 UI 代碼。

目標

快速了解SwfitUI。

成果:實現(xiàn)一個列表,點擊列表的item,跳轉(zhuǎn)到對應的詳情。

本文根據(jù)蘋果官方教程整理代碼在這里

效果展示

首先回想一下在UIKit中如何實現(xiàn):

  1. 創(chuàng)建一個帶導航Navigation的controller,用來布局和Push下一個頁面。
  2. 添加UITableView,并實現(xiàn)UITableView的兩個代理方法,展示列表。
  3. 創(chuàng)建UITableViewCell,布局UILabel 和 UIImageView。
  4. 創(chuàng)建詳情頁面,布局地圖、三個UIlabel。
  5. 在UITableViewDelegate的代理方法中Push到詳情。

對iOS開發(fā)來說這太簡單太熟悉不過了,但很多代碼比較繁瑣,控件的創(chuàng)建、布局等。雖然簡單,但繁瑣,浪費了很多本該多花在業(yè)務上的時間。

在SwiftUI中怎么實現(xiàn)呢?

在實現(xiàn)之前,先看一下所需要的組件,按照用途大致分為基礎組件、布局組件和功能性組件,以及XCode11提供的新功能。

所需組件

基礎組件

  • Text 用來顯示文字 類似于UIKit中的UILabel

  • Image 用來顯示圖片 類似于UIKit中的UIImageView

  • Spacer用來填充空白

布局組件

  • VStack 豎直擺放的組合組件

  • HStack 水平擺放的組合組件

  • List 用來展示列表 類似于UIKit中的UITableView

功能型組件

  • NavigationView 展示導航欄 類似于 UINavigationBar
  • NavigationButton 類似于pushViewController:方法

XCode11相關功能

預覽

實時看到對頁面的做出的修改

  • 純SwiftUI時,默認靜態(tài)預覽。

    點擊預覽串口的Resume按鈕。

    如果沒有顯示預覽窗口則按下圖操作打開即可

  • 預覽包含UIView子類視圖時,需要打開時時預覽

點擊可以切換時時預覽和靜態(tài)預覽

拖放

command鍵 + 鼠標點擊組件,可以方便的添加組件,設置組件屬性等。

代碼實現(xiàn)

創(chuàng)建列表
struct LandmarkList : View {
    var body: some View {
      //自定義顯示的內(nèi)容
        List(0 ..< 5) { item in
            Text("hello")
                .font(.title)
        }
    }
}

使用List組件可以快速的創(chuàng)建滑動列表,不需要設置代理,不需要實現(xiàn)協(xié)議方法就達到類似于UIKit中UITableView的效果。

Text用來展示文字,通過.font設置了字體大小。將它放入List中,它就是列表的Item。

效果:

從工程Resources文件夾中找到資源文件,引入工程,里面包含了json數(shù)據(jù)、圖片等。再引入Models文件夾中的Data.swiftLandmark.swift,這些主要是為了組件數(shù)據(jù)和Model,不是本文討論的重點。下面會用到這些數(shù)據(jù)。

創(chuàng)建Item

這一步在UIKit中像自定義UITableViewCell,需要再其中添加一個圖片和一個文字。

在SwiftUI中,沒有UITableViewCell的概念,需要顯示一行的時候,只需要使用HStack組件,HStack組件是一個組合組件,其中可以放 TextImage等組件。

創(chuàng)建 LandmarkRow

struct LandmarkRow : View {
    var landmark: Landmark
    
    var body: some View {
        HStack {
            landmark.image(forSize: 50)
            Text(landmark.name)
        }
    }
}

landmark.image(forSize: 50)這個方法返回一個指定大小的圖片

Text顯示地標名稱。

HStack將圖片和文字組合在一行里面顯示,并配置的有默認格式。

效果:

把它帶入第一步創(chuàng)建的列表中,并引入數(shù)據(jù)。

struct LandmarkList : View {
    var body: some View {        
        List(landmarkData) { landmark in
            LandmarkRow(landmark: landmark)
        }   
    }
}

效果:

列表已經(jīng)顯示出來了。

想想UIKit中的那堆代碼,是不是暗爽?

創(chuàng)建詳情頁

從效果圖中看到詳情頁有一個地圖、一個圓形圖片、幾個顯示地名、位置的文字。

從布局上看最下面兩個水平的文字可以擺放在水平組件中,再和標題文字一起擺放在豎直組件中。

地圖、圖片、水平擺放的組件再一起擺放在豎直擺放組件中。

創(chuàng)建地圖模塊:

struct MapView : UIViewRepresentable {
    
    var coordinate: CLLocationCoordinate2D
    
    func makeUIView(context: Context) -> MKMapView {
        MKMapView(frame: .zero)
    }
    
    func updateUIView(_ view: MKMapView, context: Context) {
        let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02)
        let region = MKCoordinateRegion(center: coordinate, span: span)
        view.setRegion(region, animated: true)
    }
}

要在SwiftUI中添加非SwiftUI的組件,需要遵循UIViewRepresentable協(xié)議,并實現(xiàn)協(xié)議方法。

創(chuàng)建圓角圖片:

struct CircleImage : View {
    
    var image: Image
    
    var body: some View {
        image
        .clipShape(Circle())
        .overlay(
            Circle().stroke(Color.white, lineWidth: 4)
            .shadow(radius: 10)
        )
    }
}

創(chuàng)建詳情頁

struct LandMarkDetail : View {
    var landmark : Landmark
    
    var body: some View {
        VStack {
            MapView(coordinate: landmark.locationCoordinate).frame(height: 300)
            CircleImage(image: landmark.image(forSize: 250))
                .offset(y: -130)
                .padding(.bottom, -130)
            
            //三個文字
            VStack(alignment: .leading) {
                Text(landmark.name)
                    .font(.title)
              //下面兩個文字
                HStack {
                    Text(landmark.park)
                        .font(.subheadline)
                    Spacer()
                    Text(landmark.state)
                        .font(.subheadline)
                }
                }
                .padding()
            Spacer()
        }
    }
}

VStack豎直組合組件,里面包含了MapViewCircleImage以及VStack

VStack中包含了標題文字以及HStack.

HStack中包含了水平擺放的兩個文字組件。

效果:

實現(xiàn)跳轉(zhuǎn)

上面已經(jīng)分別實現(xiàn)了列表頁和詳情頁面,下面實現(xiàn)跳轉(zhuǎn)。

UIKit中想要Push效果需要創(chuàng)建UINavigationController ,想要顯示導航欄需要設置UINavigationBar,想要跳轉(zhuǎn)需要在UITableView的代理方法中調(diào)用pushViewController:方法。

修改上面創(chuàng)建的列表:

struct LandmarkList : View {
    var body: some View {
        NavigationView {
            List(landmarkData) { landmark in
                NavigationButton(destination: LandmarkDetail(landmark: landmark)) {
                    LandmarkRow(landmark: landmark)
                 }
                }
                .navigationBarTitle(Text("Landmarks"), displayMode: .inline)
        }
    }
}

NavigationView組件類似于UINavigationBar,可以設置導航欄標題和模式。

NavigationButton可以直接將跳轉(zhuǎn)方法直接和列表展示綁定在一起,邏輯更清晰明了。

總結(jié)

了解過Flutter的同學對這個接受可能會很快。

沒有了解過Flutter的同學需要轉(zhuǎn)變一下頁面布局思路。

SwiftUI對iOS開發(fā)同學來是一大福音,畢竟都9012年了,還在使用UIKit中這么原始的布局,實在是苦不堪言。

SwiftUI需要iOS13以上的系統(tǒng),但目前公司開發(fā)APP都會支持一定的老版本系統(tǒng),還得使用UIKit。全面使用SwiftUI預計還有一段時間。畢竟,還有很多公司沒有使用Swift呢。

swiftUI官方教程

Xcode11 beta下載

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380