【问题标题】:How can I make a Generic PreferenceKey in SwiftUI?如何在 SwiftUI 中创建通用 PreferenceKey?
【发布时间】:2021-03-26 11:27:46
【问题描述】:

我想制作一个 Generic PreferenceKey,但我的代码有 2 个问题。

首先我需要为 T 定义 (),以便使用像 StringInt 这样的普通类型作为 String() 或 Int() 所以我需要 memberwise initializer for T

第二个 Xcode 抱怨我的 PreferenceKey 不符合 Equatable,而我做到了!

我该如何解决这两个问题?谢谢


struct ContentView: View {
    
    @State private var stringOfText: String = "Hello, world!"
    
    var body: some View {
        
        Text(stringOfText)
            .preference(key: CustomPreferenceKey.self, value: stringOfText)
            .onPreferenceChange(CustomPreferenceKey.self) { newValue in print(newValue) }
        
        
    }
}

struct CustomPreferenceKey<T: Equatable>: PreferenceKey {
    
    static var defaultValue: T { get { return T() } }
    
    static func reduce(value: inout T, nextValue: () -> T) { value = nextValue() }
    
}

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    这是一种可能的移动方法。经测试可与 Xcode 12.4 / iOS 14.4 配合使用

    protocol Initable {
        init()
    }
    
    extension String: Initable {
    }
    
    struct CustomPreferenceKey<T: Equatable & Initable>: PreferenceKey {
        typealias Value = T
    
        static var defaultValue: T { get { T() } }
    
        static func reduce(value: inout Value, nextValue: () -> Value) {
            value = nextValue()
        }
    }
    
    struct ContentView: View {
    
        @State private var stringOfText: String = "Hello, world!"
    
        var body: some View {
    
            Text(stringOfText)
                .preference(key: CustomPreferenceKey<String>.self, value: stringOfText)
                .onPreferenceChange(CustomPreferenceKey<String>.self) { newValue in print(newValue) }
        }
    }
    

    【讨论】:

    • 为什么我们需要 typealias Value = T?它甚至可以使用 T 而不是使用 Value
    猜你喜欢
    • 2021-05-04
    • 2020-06-30
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    相关资源
    最近更新 更多