ios 通过SwiftUI中的视图首选项传递绑定

xhv8bpkk  于 2023-07-01  发布在  iOS
关注(0)|答案(1)|浏览(109)

我尝试将绑定的值更改传递到视图修改器中。类似于苹果内部正在使用的一些其他视图修改器,例如;

func presentationDetents(
    _ detents: Set<PresentationDetent>,
    selection: Binding<PresentationDetent>
) -> some View

但是当绑定改变时,视图修饰符永远不会被调用。每当我使用普通值时,它就起作用。
这里是一个单一的文件的例子,我试图做什么,什么工作,什么不工作标记。

import SwiftUI

extension View {
    func changeNumber(number: Int) -> some View {
        print(number) // When running changeNumber with a plain value this does get called.
        return self
    }
    
    func changeNumber(number: Binding<Int>) -> some View {
        print("Binding", number) // Does not get called
        return self
    }
}

struct DebugView: View {
    @State var number = 0
    @State var selection: SwiftUI.PresentationDetent = .large
    
    var body: some View {
        VStack {
            Button("Change Number") {
                number = Int.random(in: 0..<50)
            }
            
            Text("Hello, World!")
                .changeNumber(number: $number) // $number breaks, number works.
        }
    }
}

struct DebugView_Previews: PreviewProvider {
    static var previews: some View {
        DebugView()
    }
}
v7pvogib

v7pvogib1#

好吧,有了@lorem ipsum的一些提示,我现在知道我做错了什么。我通过使用首选项上的 Package 值并将其传递到视图链中来解决这个问题。最终代码确实工作;

import SwiftUI

public struct NumberKey: PreferenceKey {
    public static var defaultValue: Int = 0

    public static func reduce(value: inout Int, nextValue: () -> Int) {
        value = nextValue()
    }
}

extension View {
    func changeNumber(number: Int) -> some View {
        print(number)
        return self
    }
    
    func changeNumber(number: Binding<Int>) -> some View {
        print("Binding", number.wrappedValue)
        return self.preference(key: NumberKey.self, value: number.wrappedValue)
    }
}

struct DebugView: View {
    @State var number = 0
    @State var selection: SwiftUI.PresentationDetent = .large
    
    var body: some View {
        VStack {
            Button("Change Number") {
                number = Int.random(in: 0..<50)
            }
            
            Text("Hello, World!")
                .changeNumber(number: $number)
        }
        .onPreferenceChange(NumberKey.self) { value in
            print("Changed", value)
        }
    }
}

struct DebugView_Previews: PreviewProvider {
    static var previews: some View {
        DebugView()
    }
}

相关问题