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呢。