用SwiftUI写程序

一:编写第一个SwiftUI程序

1,创立SwiftUI工程

image.png

-左面是代码区

-右侧是Canvas

编写代码时,右侧的Canvas可以实时显示出代码的UI预览效果

image.png

2,编写UI布局代码

经过拖拽添加UI控件


image.png

VStack:SwiftUI常用的一种布局元素,可以用来垂直地叠加视图
HStack:水平叠加视图


image.png
HStack {
VStack {
Text("Rooms")
Text("20 people")
}
}

在文字左面添加一个图片

HStack {
// `photo`是体系自带资源库中的图片
Image(systemName: "photo")
VStack {
Text("Rooms")
Text("20 people")
}
}

在Canvas中将VStack修正为左对齐


image.png

设置Text的字号


image.png
HStack {
Image(systemName: "photo")
VStack(alignment: .leading) {
Text("Rooms")
Text("20 people")
.font(.subheadline)
}
}

咱们称.font(.subheadline)为润饰器(modifier),用来自界说视图的外观或行为

设置Text的色彩为secondary

HStack {
Image(systemName: "photo")
VStack(alignment: .leading) {
Text("Rooms")
Text("20 people")
.font(.subheadline)
.foregroundColor(.secondary)
}
}

将HStack替换为List


image.png

image.png

3,设置数据源

添加Room模型

在SwiftUI中,需要让模型遵照Identifiable协议,完结id特征


image.png

在ContentView中运用Room数据来展现UI


image.png

4,丰富UI内容

设置图片圆角

经过拖拽Modifier库来完结


image.png

设置Navigation、NavigationTitle以及给每个单元格设置跳转

NavigationView {
List(rooms) { room in
NavigationLink(destination: Text(room.name)) {
Image(systemName: "photo")
.cornerRadius(8.0)
VStack(alignment: .leading) {
Text(room.name)
Text("(room.capacity) people")
.font(.subheadline)
.foregroundColor(.secondary)
}
}
}
.navigationTitle(Text("Rooms"))
}

进入实时方法,查看效果


image.png

将子视图提成一个单独的视图


image.png

创立新的页面:RoomDetail

struct RoomDetail: View {
let room: Room
var body: some View {
Image(room.imageName)
.resizable()
.aspectRatio(contentMode: .fit)
}
}
struct RoomDetail_Previews: PreviewProvider {
static var previews: some View {
RoomDetail(room: testData[0])
}
}

设置navigationBarTitle

Image(room.imageName)
.resizable()
.aspectRatio(contentMode: .fit)
.navigationBarTitle(Text(room.name))

在预览中添加NavigationView上下文

struct RoomDetail_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
RoomDetail(room: testData[0])
}
}
}

调整navigationBarTitle的展现方法


image.png

将RoomCell的跳转修正为前往RoomDetail页面

struct RoomCell: View {
let room: Room
var body: some View {
NavigationLink(destination: RoomDetail(room: room)) {
// 
}
}
}

二:Swift UI的工作方法

2.1 View

A View Defines a Piece of UI

在SwiftUI中,视图是一种遵守View协议的结构,而不是继承自根底类的类

A View Defines its Dependencies

2.2 状态特征

@State

当SwiftUI看到一个带@State状态变量的视图时,它会以视图的名义为那个变量分配存储空间。

image.png

绿色部分是APP的内存
紫色是SwiftUI所处理的内存
SwiftUI可以观察到@State变量合时被读写,一同SwiftUI知道zoom是从body中读取的,SwiftUI会在@State变量产生更改时,使用新的状态值,改写烘托。

例:完结在RoomDetail中,点击图片修正填充方法

struct RoomDetail: View {
let room: Room
@State private var zoomed = false
var body: some View {
Image(room.imageName)
.resizable()
.aspectRatio(contentMode: zoomed ? .fit : .fill) // 根据zoomed值修正填充方法
.navigationBarTitle(Text(room.name), displayMode: .inline)
.onTapGesture {
self.zoomed.toggle() // 点击修正zoomed的值
}
}
}

2.3 实际来历

在SwiftUI中,UI或许因不同的数据,处于不同的状态,咱们将这些用来绘制UI的数据称为“实际来历”,“实际来历“由状态变量和模型一同组成。

特征可以简略地分为:实际来历(Source of Truth)和衍生值(Derived Value)


image.png

zoomed变量是一个实际来历,contentMode衍生自它,当体系观察到zoomed变量产生变化时,SwiftUI结构会请求新的body,改写烘托,从头生成一个新的宽高比视图,接下来覆盖contentMode。
数据流原语(Data Flow Primitives)


image.png

SwiftUI是数据驱动,而不是事情驱动

三:完善Rooms APP

添加动画

.onTapGesture {
withAnimation {
self.zoomed.toggle()
}
}

添加一个ZStack

       ZStack(alignment: .topLeading) {
Image(room.imageName)
.resizable()
.aspectRatio(contentMode: zoomed ? .fit : .fill)
.navigationBarTitle(Text(room.name), displayMode: .inline)
.onTapGesture {
withAnimation {
self.zoomed.toggle()
}
}
Image(systemName: "video.fill")
.font(.title)
.padding(.all)
}
image.png

固定图标的方位

Image(room.imageName)
.frame(minWidth:0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
image.png

一同预览多个View

struct RoomDetail_Previews: PreviewProvider {
static var previews: some View {
Group {
NavigationView {
RoomDetail(room: testData[0])
}
NavigationView {
RoomDetail(room: testData[1])
}
}
}
}

添加动效

给视频图标添加过渡动效

if room.hasVideo && !zoomed {
Image(systemName: "video.fill")
.font(.title)
.padding(.all)
.transition(.move(edge: .leading))
}
image.png

给图片的动效延伸时刻

.onTapGesture {
withAnimation(.easeInOut(duration: 2)) {
self.zoomed.toggle()
}
}

支撑动态添加

监测数据模型的改动,实时更新UI

创立RoomStore储存Room模型

import SwiftUI
class RoomStore {
var rooms: [Room]
init(rooms: [Room] = []) {
self.rooms = rooms
}
}

遵守ObservableObject协议

class RoomStore: ObservableObject {
@Published var rooms: [Room]
// 
}

声明EnvironmentObject类型变量

@EnvironmentObject var store: RoomStore

传入EnvironmentObject类型变量

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(RoomStore(rooms: testData))
}
}

列表中添加一个按钮

List {
Button(action:{
}) {
Text("Add Room")
}
// ForEach为它的每个集结项都创立一个视图
ForEach(store.rooms)  { room in
RoomCell(room: room)
}
}
image.png
Button(action:addRoom) {
Text("Add Room")
}
func addRoom() {
store.rooms.append(Room(name: "Hall 2", capacity: 2000))
}
image.png

修正List的样式

修正listStyle

NavigationView {
List {
// 
}
.navigationBarTitle(Text("Rooms"))
.listStyle(GroupedListStyle())
}

设置分组

            List {
Section {
Button(action:addRoom) {
Text("Add Room")
}
}
Section {
ForEach(store.rooms)  { room in
RoomCell(room: room)
}
}
}

支撑动态删去

func delete(at offsets: IndexSet) {
store.rooms.remove(atOffsets: offsets)
ForEach(store.rooms)  { room in
RoomCell(room: room)
}
.onDelete(perform: delete)
image.png

设置NavigationBarItem

        NavigationView {
List {
}
.navigationBarItems(trailing: EditButton())
}

支撑列表从头排序

    func move(from source: IndexSet, to destination: Int) {
store.rooms.move(fromOffsets: source, toOffset: destination)
}
ForEach(store.rooms)  { room in
RoomCell(room: room)
}
.onDelete(perform: delete)
.onMove(perform: move)
image.png

设置预览环境

        Group {
ContentView()
.environmentObject(RoomStore(rooms: testData))
// 大字号环境
ContentView()
.environmentObject(RoomStore(rooms: testData))
.environment(.sizeCategory, .extraExtraLarge)
// 深色方法
ContentView()
.environmentObject(RoomStore(rooms: testData))
.environment(.colorScheme, .dark)
// 布局方向
ContentView()
.environmentObject(RoomStore(rooms: testData))
.environment(.layoutDirection, .rightToLeft)
.environment(.locale, Locale(identifier: "ar"))
}

总结

SwiftUI四个首要规划准则:

  • Declarative
  • Compositional
  • Automatics
  • Consistent

SwiftUI运用陈说性语法

在SwiftUI中,Xcode预览可以让咱们阅读、修正和调试APP,咱们乃至不需要工作项目工程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容