SwiftUI
image-20230312113352480.png- SwiftUI 是一种基于Swift的强大能力,简单创新的构建用户界面的方法,并且可以运行在苹果所有的平台上
SwiftUI - 声明式语法
- SwiftUI采用声明式语法,因为你可以简单声明你的用户界面
- Xcode11提供了强大的设计工具,可以通过简单的拖拽用SwiftUI生成用户界面
- 只需要描述一次的布局-为你的视图声明任何状态的内容和布局,一旦状态发生改变,SwiftUI会自动更新视图的渲染
- 构建可复用的组件-将小型、独立视图组合到更大,更复杂的界面中。在任何为Apple平台所设计的应用之间,共享您的自定义视图
- 精简动画-创建平滑的动画就像调用单个方法一样简单。SwiftUI会在必要时自动计算并过渡动画
SwiftUI设计工具使用指南
创建项目
image-20230312212430872.pngStacks
image-20230312212509459.png如何使用SwiftUI构建可复用的组件
地标页例子
image-20230312214019068.pngImage组件
image-20230312214151969.png image-20230312214348729.png image-20230312214400782.png image-20230312214452467.pngstruct ContentView: View {
var body: some View {
VStack {
//设置安全距离
MapView().edgesIgnoringSafeArea(.all)
.frame(height: 300)
CircleImage().offset(y: -130).padding(.bottom, -130)
//左对齐
VStack (alignment: .leading) {
Text("圆明园").font(.title)
HStack {
Text("皇家园林").font(.subheadline)
Spacer()
Text("北京").font(.subheadline)
}
}.padding()//边界留白
Spacer()//留白
}
}
}
图片组件
struct CircleImage: View {
var body: some View {
//将图片剪切出一个圆
Image("ymy").clipShape(Circle())
//加一个边框线
.overlay(Circle().stroke(Color.black, lineWidth: 4))
.shadow(radius: 10)//阴影
}
}
地图组件
import SwiftUI
import MapKit
struct MapView; UIViewRepresentable {
//创建地图组件
func makeUIView(context: Context) -> MKMapView {
return MKMapView(frame: .zero)
}
//对地图组件进行设置
func updateUIView(_ uiView: MKMapView, context: Context) {
//圆明园的经纬度
let location = CLLocationCoordinate2D(latitude: 40.00491139888854, longitude: 116.2896180152893)
//展示范围
let span = MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
let region = MKCoordinateRegion(center: location, span: span)
uiView.setRegion(region, animated: true)
}
}
如何使用SwiftUI实现动画
SwiftUI - 动画
- 在SwiftUI中,你可以将任意的改变过程封装进一个withAnimation块中。默认,SwiftUI会对这种改变采用fade in/out 的方式进行动画
struct AnimationView: View {
//状态 当属性改变时, 会进行重写渲染
@State private var showDetail = false
var body: some View {
Button(action: {
withAnimation {
self.showDetail = !self.showDetail
}
}) {
Image(systemName: "chevron.right.circle")//使用了一张系统图片
.imageScale(.large)//尺寸
.rotationEffect(.degrees(showDetail ? 90 : 0))//旋转90度或0度
.scaleEffect(showDeatil ? 1.5 : 1)//放大倍数
.padding()
}
}
}
在这里更改显示入口
image-20230312224524873.png深入理解SwiftUI:实现原理探秘
@propertyWrapper
- 通过property Wrapper机制,对一些类似的属性的实现代码做同一封装
- 通过@propertyWrapper可以移除掉一些重复或者类似的代码
@state
- 通过@State SwiftUI 实现了值的绑定、动态查找和View的自动重现绘制
- 课后题:查看源码,了解@Binding,@ObservedObject,@EnvironmentObject等装饰器的作用
extension UserDefaults {
public enum Keys {
static let hadShownUserGuide = "hadShownUserGuide"
}
var hadShownUserGuide: Bool {
set {
set(newValue, forKey: Keys.hadShownUserGuide)
}
get {
bool(forKey: Keys.hadShownUserGuide)
}
}
}
struct PropertyWrapperView: View {
@State private var showText = UserDefaults.standard.hasShownUserGuide ? "已经展示" : "没有展示过"
var body: some View {
Button(action: {
if (!UserDefaults.standard.hasShownUserGuide) {
UserDefaults.standard.hasShownUserGuide = true
self.showText = "已经展示"
}
}) {
Text(self.showText)
}
}
}
- 使用propertyWrapper进行统一扩展
@propertyWrapper
struct UserDefaultsWrapper<T> {
var key: String
var defaultValue : T
init(_ key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T {
get {
return UserDefaults.standard.value(forKey: key) as? T ?? defaultValue
}
set {
UserDefaults.standard.set(newValue, forKey: key)
}
}
}
struct PropertyWrapperView: View {
@UserDefaultsWrapper("hadShownUserGuide", defaultValue: false)
static var hadShownUserGuide : Bool
@State private var showText = PropertyWrapperView.hasShownUserGuide ? "已经展示" : "没有展示过"
var body: some View {
Button(action: {
if (!PropertyWrapperView.hasShownUserGuide) {
PropertyWrapperView.hasShownUserGuide = true
self.showText = "已经展示"
}
}) {
Text(self.showText)
}
}
}
网友评论