SwiftUI - 组件设计之PreferPreferenceKey
本文记录一下当我们自定义组件的时候,PreferPreferenceKey的使用方式
具体步骤如下:
PreferenceKey 主要用于组件如何更改父组件中的值
举一个例子 当我们设置navigationTitle,实际上它的对象是VStack 通过设置 PreferenceKey 来作用到父类的 navigation title
使用步骤
- 首先声明一个自定义的PerferenceKey
- 通过reduce方法赋予其defaultValue值
- 把赋值方法封装到View的拓展
- 定义Preference触发时的方法体
- 然后就可以像设置navigationTitle那样设置我们自定义的PerferenceKey
代码如下
//
// PreferenceKeyBootCamp.swift
// swiftUIPlayground
//
// Created by 凌俊杰 on 2024/4/7.
//
import SwiftUI
/// PreferenceKey 主要用于组件如何更改父组件中的值
/// 举一个例子 当我们设置navigationTitle,实际上它的对象是VStack 通过设置 PreferenceKey 来作用到父类的 navigation title
struct PreferenceKeyBootCamp: View {
@State var text = "Hello Jason"
var body: some View {
NavigationView {
VStack {
PreferenceKeyBootCamp_SecondDaryScreen(text: self.text)
/// 5. 调用该方法
.updateCustomerText(text: "Jason Gor")
}
.navigationTitle("NavigationTitle ")
/// 4. 定义Preference触发时的方法体
.onPreferenceChange(CustomerTitlePreferenceKey.self, perform: { value in
self.text = value
})
}
}
}
#Preview {
PreferenceKeyBootCamp()
}
/// 现在来介绍一下,如何设置 PreferenceKey
/// 1. 首先声明一个自定义的PerferenceKey
struct CustomerTitlePreferenceKey: PreferenceKey{
static var defaultValue: String = ""
/// 2. 通过reduce方法赋予其defaultValue值
static func reduce(value: inout String, nextValue: () -> String) {
defaultValue = nextValue()
}
}
/// 3. 把赋值方法封装到View的拓展
extension View {
func updateCustomerText(text: String) -> some View {
preference(key: CustomerTitlePreferenceKey.self, value: text)
}
}
struct PreferenceKeyBootCamp_SecondDaryScreen: View {
let text: String
@State private var newValue = ""
var body: some View{
Text(text)
.onAppear(perform: {
getDataFromDataBase()
})
.updateCustomerText(text: self.newValue)
}
func getDataFromDataBase() {
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0, execute: {
self.newValue = "new value !!!!!"
})
}
}
那么当我们在实际开发中,从接口获取数据后可以这么做
//
// PreferenceKeyBootCamp.swift
// swiftUIPlayground
//
// Created by 凌俊杰 on 2024/4/7.
//
import SwiftUI
/// PreferenceKey 主要用于组件如何更改父组件中的值
/// 举一个例子 当我们设置navigationTitle,实际上它的对象是VStack 通过设置 PreferenceKey 来作用到父类的 navigation title
struct PreferenceKeyBootCamp: View {
@State var text = "Hello Jason"
var body: some View {
NavigationView {
VStack {
PreferenceKeyBootCamp_SecondDaryScreen(text: self.text)
/// 5. 调用该方法
// .updateCustomerText(text: "Jason Gor")
}
.navigationTitle("NavigationTitle ")
/// 4. 定义Preference触发时的方法体
.onPreferenceChange(CustomerTitlePreferenceKey.self, perform: { value in
self.text = value
})
}
}
}
#Preview {
PreferenceKeyBootCamp()
}
/// 现在来介绍一下,如何设置 PreferenceKey
/// 1. 首先声明一个自定义的PerferenceKey
struct CustomerTitlePreferenceKey: PreferenceKey{
static var defaultValue: String = ""
/// 2. 通过reduce方法赋予其defaultValue值
static func reduce(value: inout String, nextValue: () -> String) {
defaultValue = nextValue()
}
}
/// 3. 把赋值方法封装到View的拓展
extension View {
func updateCustomerText(text: String) -> some View {
preference(key: CustomerTitlePreferenceKey.self, value: text)
}
}
struct PreferenceKeyBootCamp_SecondDaryScreen: View {
let text: String
@State private var newValue = ""
var body: some View{
Text(text)
.onAppear(perform: {
getDataFromDataBase()
})
.updateCustomerText(text: self.newValue)
}
func getDataFromDataBase() {
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0, execute: {
self.newValue = "getDataFromDataBase !!!!!"
})
}
}
该代码通过asyncAfter模拟了接口获取收据的等待时间,获取到数据后通过perferenceKey对创建的自定义组件PreferenceKeyBootCamp_SecondDaryScreen重新赋予了值。
PreferenceKey的使用说明到此结束。