@State, @StateObject, @ObservedObject 关键字
@State 定义在使用它的 View 的最外层,当改变时,SwiftUI 刷新依赖它的视图。@State 只对当前视图和子视图可见,属性的初始化在其生命周期内只被赋值一次
@StateObject 配合 ObservableObject 对象的 @Published 属性来检测属性的改变。SwiftUI 会保证 @StateObject 属性在当前视图生命周期内只被改变一次
@ObservedObject
如果视图的输入 (参数)是 ObservableObject 对象(通常是 @StateObject),使用 @ObservedObject 接收它,不要在声明 @ObservedObject 的视图里初始化它。用法如下:
class DataModel: ObservableObject {
@Published var name = "Some Name"
@Published var isEnabled = false
}
struct MyView: View {
@StateObject private var model = DataModel()
var body: some View {
Text(model.name)
MySubView(model: model)
}
}
struct MySubView: View {
@ObservedObject var model: DataModel
init(model: DataModel) {
self.model = model // 只应该被这样用
// 不要像以下这样用,和 State,StateObject 表现不一样
// self.model = DataMoel() // 此时 model 被重新初始化
// self._model = ObservedObject(wrappedValue: DataModel()) // 此时 model 被重新初始化
}
var body: some View {
Toggle("Enabled", isOn: $model.isEnabled)
}
}
NavigationView
NavigationView {
Text("Row \(number)")
.frame(height: 50).background(
Color.blue
)
.navigationBarHidden(false)
.navigationBarTitle("123", displayMode: .inline)
.background(Color.red)
.background(NavigationConfigurator { nc in
nc.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.blue.withAlphaComponent(calculateOpacity(for: offsetY))]
})
.navigationBarItems(
leading:
Button(action: {
print("Left button tapped")
}) {
Image(systemName: "arrow.left")
}
.buttonStyle(PlainButtonStyle()),
trailing:
HStack {
Button(action: {
print("First button tapped")
}) {
Image(systemName: "plus")
}
.buttonStyle(PlainButtonStyle())
Spacer()
Button(action: {
print("Second button tapped")
}) {
Image(systemName: "plus")
}
.buttonStyle(PlainButtonStyle())
}
)
}
//设置标题颜色
struct NavigationConfigurator: UIViewControllerRepresentable {
var configure: (UINavigationController) -> Void
func makeUIViewController(context: Context) -> UIViewController {
let viewController = UIViewController()
DispatchQueue.main.async {
if let nc = viewController.navigationController {
self.configure(nc)
}
}
return viewController
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}
List 自定义高度
List {
Text("\(isOn)")
.background(Color.clear)
.listRowBackground(Color.clear)
ForEach(0..<5) { number in
HStack {
Text("Row \(number)")
.frame(height: 50).background(
Color.blue
)
Spacer()
Text("Row \(number)")
.frame(height: 50).background(
Color.blue
)
}
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
}
.background(Color.clear)
.listRowBackground(Color.clear)
}
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
.listStyle(.plain)
.navigationBarHidden(false)
.navigationBarTitle("123", displayMode: .inline)
.background(Color.red)
Toggle 开关选择器
Toggle("定位开关", isOn: $isOn).labelsHidden()
.tint(Color.blue)
.toggleStyle(SwitchToggleStyle(tint: Color.red))
.onTapGesture {
if !isOn {
print("111111111111")
} else {
print("222222222222222")
}
}
//一般不通过 onTapGesture点击来获取事件,一般通过框架combine 监听isOn 来获取事件处理
self.$isOn.sink { [weak self] isOn in
guard let self else { return }
}.store(in: &self.cancellables)
Image 加载图片
// 加载本都图片
Image("iconName")
Image("iconName", bundle: Resources.resourceBundle) // 文件路径
//网络图片
AsyncImage(url: URL(string: "https:pic35.photophoto.cn/20150511/0034034892281415_b.jpg"), content: { image in
image.resizable()
}, placeholder: {
Color.red
})