SwiftUI 是一種很是簡單的創新方法,能夠利用 Swift 的強大能力在全部蘋果設備平臺上構建用戶界面。經過 SwiftUI,開發者僅使用一組工具和 API 就能爲全部蘋果設備構建用戶界面。SwiftUI 使用易於閱讀和編寫的聲明式 Swift 語法,可與新的 Xcode 設計工具無縫協做,使你的代碼和設計完美同步。SwiftUI 自動支持動態類型、黑暗模式、本地化和可訪問性,你的 SwiftUI 代碼將成爲你寫過的最強大的 UI 代碼。git
快速瞭解SwfitUI。github
成果:實現一個列表,點擊列表的item,跳轉到對應的詳情。json
本文根據蘋果官方教程整理代碼在這裏 swift
首先回想一下在UIKit中如何實現:app
對iOS開發來講這太簡單太熟悉不過了,但不少代碼比較繁瑣,控件的建立、佈局等。雖然簡單,但繁瑣,浪費了不少本該多花在業務上的時間。工具
在SwiftUI中怎麼實現呢?佈局
在實現以前,先看一下所須要的組件,按照用途大體分爲基礎組件、佈局組件和功能性組件,以及XCode11提供的新功能。字體
基礎組件ui
Text
用來顯示文字 相似於UIKit中的UILabel
spa
Image
用來顯示圖片 相似於UIKit中的UIImageView
Spacer
用來填充空白
佈局組件
VStack
豎直襬放的組合組件
HStack
水平擺放的組合組件
List
用來展現列表 相似於UIKit中的UITableView
功能型組件
NavigationView
展現導航欄 相似於 UINavigationBar
NavigationButton
相似於pushViewController:
方法預覽
實時看到對頁面的作出的修改
純SwiftUI時,默認靜態預覽。
點擊預覽串口的Resume按鈕。
若是沒有顯示預覽窗口則按下圖操做打開便可
點擊能夠切換時時預覽和靜態預覽
拖放
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.swift
和Landmark.swift
,這些主要是爲了組件數據和Model,不是本文討論的重點。下面會用到這些數據。
這一步在UIKit中像自定義UITableViewCell,須要再其中添加一個圖片和一個文字。
在SwiftUI中,沒有UITableViewCell的概念,須要顯示一行的時候,只須要使用HStack
組件,HStack
組件是一個組合組件,其中能夠放 Text
、Image
等組件。
建立 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
豎直組合組件,裏面包含了MapView
和CircleImage
以及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呢。