SwiftUI - 组件设计之PreferPreferenceKey

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的使用说明到此结束。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值