Your Site Title

iOS SwiftUI

支持情况

iOS13.0 + Beta
macOS10.15 + beta
tvOS 13.0+ beta
watchOS 6.0+ beta

打开SwiftUI预览, Editor > Canvas, 可以由代码和Inspector 控制 (Command-click view).

Preview

Xcode’s canvas 可以自动识别和显示当前编辑的View, 返回一个View, 可以自定义返回View

struct ContentView_Previews: PreviewProvider {
		static var previews: some View {
				ContentView()
		}
}

struct LandmarkRow_Previews: PreviewProvider {
		static var previews: some View {
				Group {
						LandmarkRow(landmark: landmarks[0])
						LandmarkRow(landmark: landmarks[1])
				}
				.previewLayout(.fixed(width: 300, height: 70))
		}
}

struct LandmarkList_Previews: PreviewProvider {
		static var previews: some View {
				ForEach(["iPhone SE (2nd generation)", "iPhone XS Max"], id: \.self) { deviceName in
						LandmarkList()
								.previewDevice(PreviewDevice(rawValue: deviceName))
								.previewDisplayName(deviceName)
				}
		}
}

Content

Content是一个泛型, 是一个类型的别名. 但是文档里没有说明到底是什么. 也有可以是ViewModifier 创建View的构造函数, 最后一个参数一般为闭包, 最后一句代码是表达式语句, 那么不用写return关键字 如果有多个返回View, 比如HStack, 内容包含多个View, 那么闭包需要使用@ViewBuilder修饰, 会把多个 View自动打包成TupleView对象.

Model

  1. Codable
    Codable = Decodable + Encodable 结构体序列化和反序列化
    
  2. Hashable

    生成默认的Hash值, 可以算定自hashValue(一般用异或)

  3. Identifiable

    List视图, 需要id属性, 如果模型实现了Identifiable, 就可以不传递id属性. 生成对象唯一标识 如果元素是简单的值类型(如: 字符串), 那么可以使用\.self表示唯一标识

State and Data Flow

State And Binding

SwiftUI中View创建出来是一个常量, 常量对象状态不可改变. 如果想改变一个对象的状态, 并且View随着状态改变而改变. 那么状态需要使用@State修饰

Binding可以把View的值和状态属性绑定起来, 当状态属性值变了后, View展示也会变 使用$引用绑定的值.

	struct Input:view {
		@Binding var text: String
		var body: some View {
			TextField(text: $text)
		}
	}

Observable Object

View监听对象状态的改变, 属于Combine

1. 监听对象实现`ObservableObject`协议
2. 需要监听的状态用`@Published `修饰
3. 创建监听对象
	* `@StateObject`初始化监听对象时使用
	* `@EnvironmentObject`修饰监听对象, SwiftUI会自动获取状态值
		(创建ContentView时需要使用`environmentObject`方法, 应用到所有视图)
	* `@ObservedObject`修饰监听对象, 可以引用监听对象

Drawing and Animation

CoreGraphics画图核心

Animations

  1. View使用equatable, SwiftUI会识别可动画的属性, 如颜色, 透明度, 旋转角度, 大小和其他属性使用animation(_:)
  2. View不使用equatable, 可以在指定的值更改时使用animation(_:value:)
  3. withAnimation: 使用相关View都有动画
  4. 默认下SwiftUI动画是淡入淡出, 使用transition(_:)修改过度动画, 传入AnyTransition
  5. AnyTransition使用asymmetric(insertion:removal:)自定义过度动画

View

List

1. 默认样式

list默认样式有圆角, 有边距

  1. 设置listStyle listStyle(GroupedListStyle()) 或者 listStyle(PlainListStyle())
  2. item设置listRowInsets(EdgeInsets() 或者listRowInsets(EdgeInsets(top: -20, leading: -20, bottom: -20, trailing: -20))

Interfacing with UIKit

  1. 创建Swift File, 实现UIViewControllerRepresentable 协议
  2. 实现makeUIViewController函数, 返回一个UIKit Controller 对象, swiftui 只会调用这方法一次, 然后管理视图生命同期 UIHostingController, A UIKit view controller that manages a SwiftUI view hierarchy.
  3. 实现updateUIViewController, 当swiftui状态更新时, 通知UIKit Controller更新
  4. 实现makeCoordinator, 创建与AppKit协调对象

Reference

Introducing SwiftUI
SwiftUI 概述 :: Learn Swift
Adding SwiftUI to Objective-C Apps