未调用SwiftUI-onPreferenceChange

未调用SwiftUI-onPreferenceChange,swiftui,Swiftui,我试图理解preference和onPreferenceChange是如何工作的,所以我尝试了一些层次结构,不幸的是,我现在被困在一个不再调用onPreferenceChange的情况下。 对我来说奇怪的是,当我(在TestView结构的底部)删除行时 .modifier(边框(.column)) 或 垫片(最小长度:0) onPreferenceChange开始正常工作/按我的预期调用 我试图找到解释,但没有成功。谁能向我解释一下,我做错了什么 下面是我的根视图的代码 public struc

我试图理解preference和onPreferenceChange是如何工作的,所以我尝试了一些层次结构,不幸的是,我现在被困在一个不再调用onPreferenceChange的情况下。 对我来说奇怪的是,当我(在TestView结构的底部)删除行时

.modifier(边框(.column)) 或 垫片(最小长度:0)

onPreferenceChange开始正常工作/按我的预期调用

我试图找到解释,但没有成功。谁能向我解释一下,我做错了什么

下面是我的根视图的代码

public struct MyRootView: View {

    public var body: some View {
        TestView()
        .onPreferenceChange(ChangeInfoKey.self) { changeInfo in
            print("preference changed: \(changeInfo)")
        }
    }
}
TestView:

struct TestView: View {
    @State private var changeInfo: ChangeInfo?
    var body: some View {
        VStack {
            Group {
                Button(action: {
                    self.changeInfo = ChangeInfo(title: "Some Title \(Int.random(in: 0...10))")
                    print("Change initiated: \(self.changeInfo!.title) - \(self.changeInfo!.id)")
                }) {
                    Text("My Button")
                }
                .preference(key: ChangeInfoKey.self, value: changeInfo)
            }
            .modifier(Border(.column))
            Spacer(minLength: 0)
        }
    }
}
“边框修改器”仅在“视图”周围创建可视边框,我不确定它是否与此问题相关,但对于那些希望完整查看我的代码的所有部分或尝试此功能的用户:

struct Border: ViewModifier {

    enum BorderType: RawRepresentable {
        case section
        case emptyColumn
        case column
        case widget
        case debug

        var rawValue: (CGFloat, CGFloat, Color) {
            switch self {
            case .section: return (2, 0, Color.blue)
            case .emptyColumn: return (0.5, 4, Color(0xa7afb5))
            case .column: return (0.5, 4, Color(0xa7afb5))
            case .widget: return (0.5, 2, Color(0xa7afb5))
            case .debug: return (4, 0, Color.red)
            }
        }

        init?(rawValue: (CGFloat, CGFloat, Color)) {
            fatalError("ElementBorder.init(rawValue) - not implemented")
        }
    }

    let lineWidth: CGFloat
    let color: Color
    let dashLength: CGFloat

    init(_ borderType: BorderType) {
        self.lineWidth = borderType.rawValue.0
        self.dashLength = borderType.rawValue.1
        self.color = borderType.rawValue.2
    }

    func body(content: Content) -> some View {
        if dashLength > 0 {
            return AnyView(content
                .overlay(
                    Rectangle()
                        .strokeBorder(style: StrokeStyle(lineWidth: self.lineWidth, dash: [self.dashLength]))
                        .foregroundColor(self.color)
            ))
        } else {
            return AnyView(content
                .border(self.color, width: self.lineWidth)
            )
        }
    }
}

你可能想读这篇文章:非常感谢,我读了几遍(很多好信息)。不幸的是,它没有解释为什么在组后的VStack中添加间隔符时不调用onPreferenceChange(如果删除此间隔符,onPreferenceChange就会开始工作)。这是真的,我在SwiftUI中也遇到了许多奇怪的行为。希望苹果能尽快拿出更好的文档。。。