swiftui - 观察 SwiftUI 中的框架变化

标签 swiftui geometryreader

我有一个可以拖放到其他 View 之上的 View (可以说是类别)。为了检测我在哪个类别 View 之上,我将它们的帧存储在一个帧数组中,这发生在它们不可见叠加层的 onAppear 中。 (这基于 Paul Hudson 在 this 教程中的实现)。

这一切都很好,除非这些 View 的位置发生变化,例如在 iPad 上调整设备方向或窗口大小。这当然不会触发 onAppear,因此帧不再匹配。

HStack() {
ForEach(categories) { category in
    ZStack {
        Circle()
        Rectangle()
            .foregroundColor(.clear)
            .overlay(
                GeometryReader { geo in
                    Color.clear
                        .onAppear {
                            categoryFrames[index(for: category)] = geo.frame(in: .global)
                        }
                }
            )
        }
    }
}

因此,欢迎了解如何更新这些实例中的帧或如何以不同方式观察它们。

最佳答案

可以使用 View 首选项在刷新期间动态读取 View 帧,因此您不必关心方向,因为每次重绘 View 时都有实际的帧。

这是一个方法草案。

为 View 偏好键引入模型:

struct ItemRec: Equatable {
    let i: Int        // item index
    let p: CGRect     // item position frame
}

struct ItemPositionsKey: PreferenceKey {
    typealias Value = [ItemRec]
    static var defaultValue = Value()
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value.append(contentsOf: nextValue())
    }
}

现在你的代码(假设@State private var categoryFrames = [Int, CGRect]())

HStack() {
ForEach(categories) { category in
    ZStack {
        Circle()
        Rectangle()
            .foregroundColor(.clear)
            .background(        // << prefer background to avoid any side effect
                GeometryReader { geo in
                    Color.clear.preference(key: ItemPositionsKey.self,
                        value: [ItemRec(i: index(for: category), p: geo.frame(in: .global))])
                }
            )
        }
    }
    .onPreferenceChange(ItemPositionsKey.self) {
        // actually you can use this listener at any this view hierarchy level
        // and possibly use directly w/o categoryFrames state
        for item in $0 {
           categoryFrames[item.i] = item.p
        }
    }

}

关于swiftui - 观察 SwiftUI 中的框架变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63220681/

相关文章:

swift - 在 SwiftUI 中创建惰性 NavigationLink 时出现遗传问题

swift - 我们如何在 SwiftUI 中制作自定义 GeometryReader?

swift - 如何在 SwiftUI 中相对于不同坐标系中的其他 View 定位 View

ios - Foreach 如果所有字段都是 "0",返回一个 View

ios - 具有相同高度的 SwiftUI HStack 元素

SwiftUI GeometryReader 造成严重破坏

swiftui - GeometryReader 计算 View 的总高度

SwiftUI 观察到的对象在发布值更改时不更新

swiftui - 在 SwiftUI 中同时流畅地动画文本随偏移量的变化

swift - 对象周围的填充