IDE相关
1.canvas预览需要确保macOS 10.15及以上
2.创建项目 - User interface需要选择 SwiftUI
3.cmd + 左键 可以操作视图对象,进行嵌套和属性设置
4.inspector修改属性,代码上会同步更新
5.打开 live preview 进行动态预览
6.pin preview 固定当前预览,便于切换文件
UI特性
1.视图内容默认居中,视图布局使用视图属性
2.文本: Text("文本内容")
文本颜色需要设置.forgroundColor()
文字字体: .font()
3.常用容器: Stack
- VStack:子元素竖直排列
- HStack:子元素水平排列
- VStack:子元素叠加排列
4.间隔器: Spacer() 使其包含的视图使用父视图的所有空间
5.padding()修饰符: 控制视图边界
6.offset()修饰符: 视图偏移
7.frame()修饰符: 设置大小(默认父视图大小或内容自适应)
8.图片: Image("图片名")
- 设置圆角:
.clipShape() - 分层视图:
.overlay()在这个视图前面分层一个次要视图。可用于设置边框,给图片添加文本等 - 阴影:
.shadow(radius: )
9.分组容器: Group 子视图会作为单独的预览呈现在canvas
10.列表: List
- 列表使用可标识数据(identifiable data),可以遵循
Identifiable协议,也可以将数据传递到唯一标识每个元素的键路径
// 如果landmarkData遵守Identifiable协议,不需要id参数
List(landmarkData, id: \.id) { landmark in
}11.导航视图: NavigationView
标题: .navigationBarTitle()
页面跳转: NavigationLink(destiation: ) {}
12. 动态列表: ForEach - 在List或其他容器视图中加入ForEach来创建动态列表
import SwiftUI
struct LandmarkList: View {
@State var showFavoritesOnly = true
var body: some View {
NavigationView {
List {
ForEach(landmarkData) { landmark in
if !self.showFavoritesOnly || landmark.isFavorite {
NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
LandmarkRow(landmark: landmark)
} }
}
}
.navigationBarTitle(Text("Landmarks"))
}
}
}
13.按钮: Button
14.GeometryReader: 可以获取到当时子视图的大小,位置
15.绘图:Path
- path.move(to:) 起绘点
- path.addLine(to:) 绘线到
- path.addQuadCurve(to:control:) 绘制贝塞尔曲线
Path { path in
var width: CGFloat = min(geometry.size.width, geometry.size.height)
let height = width
let xScale: CGFloat = 0.832
let xOffset = (width * (1.0 - xScale)) / 2.0
width *= xScale
path.move(
to: CGPoint(
x: xOffset + width * 0.95,
y: height * (0.20 + HexagonParameters.adjustment)
)
)
HexagonParameters.points.forEach {
path.addLine(
to: .init(
x: xOffset + width * $0.useWidth.0 * $0.xFactors.0,
y: height * $0.useHeight.0 * $0.yFactors.0
)
)
path.addQuadCurve(
to: .init(
x: xOffset + width * $0.useWidth.1 * $0.xFactors.1,
y: height * $0.useHeight.1 * $0.yFactors.1
),
control: .init(
x: xOffset + width * $0.useWidth.2 * $0.xFactors.2,
y: height * $0.useHeight.2 * $0.yFactors.2
)
)
}
}16.线性渐变色:LinearGradient(gradient:startPoint:endPoint:)
17.aspectRatio(_:contentMode:):根据宽高比,内容缩放模式调整视图
状态管理
1.environmentObject(_:) 视图层级结构中,向下传递数据对象
2.@EnvironmentObject 视图层级结构中,较低位置的视图中使用此属性从较高位置的视图接收数据
3.@binding 包装一个值,使它是地址传递,而非值传递
4.@State 包装一个值,这个值改变时,所在的视图会刷新UI
5.@ObservedObject
6.Self:定义协议时使用,代指实现该协议的类型或该类型的子类;作为类方法的返回值使用
7.UIViewRepresentable:要使UIView在SwifUI中可用,需要用UIViewRepresentable对UIView进行包装,实现makeUIView创建View,实现updateUIView刷新View的状态
8.UIViewControllerRepresentable:在SwiftUI中使用UIViewController,需遵守该协议,同时实现makeUIViewController和updateUIViewController创建和管理控制器
9.Coordinator:SwiftUI和UIKit协调器
桥接UIKit的数据绑定(Delegate, Target/Action,DateSource),7/8两个协议的makeCoordinator方法,返回一个协调器
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
// 在makeUIViewController中绑定coordinator
func makeUIViewController(context: Context) -> UIPageViewController {
let pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
pageViewController.dataSource = context.coordinator
return pageViewController
}通过自定义协调器的init方法,实现交互
class Coordinator: NSObject, UIPageViewControllerDataSource {
var parent: PageViewController
init(_ pageViewController: PageViewController) {
self.parent = pageViewController
}
// 数据源方法
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { }
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { }
}10.SwiftUI in UIKit
SwiftUI中的View使用UIHostingController包装以后可以给UIKit使用
let vc = UIHostingController(rootView: ContentView())11.main方法变迁
SwiftUI1.0
// 在SceneDelegate的willConnectTosession方法中
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: CategoryHome().environmentObject(UserData()))
self.window = window
window.makeKeyAndVisible()
}SwiftUI2.0
// 苹果第一次仅使用SwiftUI来构建整个应用程序,而不是将SwiftUI嵌入UIKit
@main
Struct HelloWorld: APP {
var body: some Scene {
WindowGroup {
Text("Hello, world!").padding()
}
}
}