SwiftUI快速入門

SwiftUI 是一種很是簡單的創新方法,能夠利用 Swift 的強大能力在全部蘋果設備平臺上構建用戶界面。經過 SwiftUI,開發者僅使用一組工具和 API 就能爲全部蘋果設備構建用戶界面。SwiftUI 使用易於閱讀和編寫的聲明式 Swift 語法,可與新的 Xcode 設計工具無縫協做,使你的代碼和設計完美同步。SwiftUI 自動支持動態類型、黑暗模式、本地化和可訪問性,你的 SwiftUI 代碼將成爲你寫過的最強大的 UI 代碼。git

目標

快速瞭解SwfitUI。github

成果:實現一個列表,點擊列表的item,跳轉到對應的詳情。json

本文根據蘋果官方教程整理代碼在這裏 swift

效果展現

首先回想一下在UIKit中如何實現:app

  1. 建立一個帶導航Navigation的controller,用來佈局和Push下一個頁面。
  2. 添加UITableView,並實現UITableView的兩個代理方法,展現列表。
  3. 建立UITableViewCell,佈局UILabel 和 UIImageView。
  4. 建立詳情頁面,佈局地圖、三個UIlabel。
  5. 在UITableViewDelegate的代理方法中Push到詳情。

對iOS開發來講這太簡單太熟悉不過了,但不少代碼比較繁瑣,控件的建立、佈局等。雖然簡單,但繁瑣,浪費了不少本該多花在業務上的時間。工具

在SwiftUI中怎麼實現呢?佈局

在實現以前,先看一下所須要的組件,按照用途大體分爲基礎組件、佈局組件和功能性組件,以及XCode11提供的新功能。字體

所需組件

基礎組件ui

  • Text 用來顯示文字 相似於UIKit中的UILabelspa

  • Image 用來顯示圖片 相似於UIKit中的UIImageView

  • Spacer用來填充空白

佈局組件

  • VStack 豎直襬放的組合組件

  • HStack 水平擺放的組合組件

  • List 用來展現列表 相似於UIKit中的UITableView

功能型組件

  • NavigationView 展現導航欄 相似於 UINavigationBar
  • NavigationButton 相似於pushViewController:方法

XCode11相關功能

預覽

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

  • 純SwiftUI時,默認靜態預覽。

    點擊預覽串口的Resume按鈕。

    若是沒有顯示預覽窗口則按下圖操做打開便可

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

點擊能夠切換時時預覽和靜態預覽

拖放

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

代碼實現

建立列表
struct LandmarkList : View {
    var body: some View {
      //自定義顯示的內容
        List(0 ..< 5) { item in
            Text("hello")
                .font(.title)
        }
    }
}
複製代碼

使用List組件能夠快速的建立滑動列表,不須要設置代理,不須要實現協議方法就達到相似於UIKit中UITableView的效果。

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

效果:

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

建立Item

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

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

建立 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將圖片和文字組合在一行裏面顯示,並配置的有默認格式。

效果:

把它帶入第一步建立的列表中,並引入數據。

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

效果:

列表已經顯示出來了。

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

建立詳情頁

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

從佈局上看最下面兩個水平的文字能夠擺放在水平組件中,再和標題文字一塊兒擺放在豎直組件中。

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

建立地圖模塊:

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協議,並實現協議方法。

建立圓角圖片:

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

建立詳情頁

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中包含了水平擺放的兩個文字組件。

效果:

實現跳轉

上面已經分別實現了列表頁和詳情頁面,下面實現跳轉。

UIKit中想要Push效果須要建立UINavigationController ,想要顯示導航欄須要設置UINavigationBar,想要跳轉須要在UITableView的代理方法中調用pushViewController:方法。

修改上面建立的列表:

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能夠直接將跳轉方法直接和列表展現綁定在一塊兒,邏輯更清晰明瞭。

總結

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

沒有了解過Flutter的同窗須要轉變一下頁面佈局思路。

SwiftUI對iOS開發同窗來是一大福音,畢竟都9012年了,還在使用UIKit中這麼原始的佈局,實在是苦不堪言。

SwiftUI須要iOS13以上的系統,但目前公司開發APP都會支持必定的老版本系統,還得使用UIKit。全面使用SwiftUI預計還有一段時間。畢竟,還有不少公司沒有使用Swift呢。

swiftUI官方教程

Xcode11 beta下載

相關文章
相關標籤/搜索