swift - 仅当有足够空间时才显示 SwiftUI View

标签 swift swiftui geometryreader

以下是我的观点内容:

HStack {
    Banner(items: items)
        .layoutPriority(100)
                
    OptionalView()
}

我只想在 Banner View 中显示项目后剩余最小宽度时显示 OptionalView

我可以使用GeometryReader,但由于它是一个推出 View ,如果不需要OptionalView,它会占用一些空间并将横幅项目推送到向左,这样它们就不会居中。

HStack {
    Banner(items: items)
        .layoutPriority(100)
                
    GeometryReader { geometry in
        if geometry.size.width >= 70 {
            OptionalView()
        }
    }
}

最佳答案

答案是使用 SwiftUI 记录稀疏的 PreferenceKey 协议(protocol)。

参见:

这是一个方便的 View 修改器,可以返回任何 View 的框架:

fileprivate struct IntrinsicFramePreferenceKey: PreferenceKey {
    static var defaultValue: CGRect = .zero
    static func reduce(value: inout CGRect, nextValue: () -> CGRect) {}
}

fileprivate struct IntrinsicFrame: ViewModifier {
    @Binding var frame: CGRect
    
    func body(content: Content) -> some View {
        content
            .background(GeometryReader { geometry in
                Color.clear
                    .preference(key: IntrinsicFramePreferenceKey.self, value: geometry.frame(in: .global))
            })
            .onPreferenceChange(IntrinsicFramePreferenceKey.self) { newFrame in
                frame = newFrame
            }
    }
}

extension View {
    func intrinsicFrame(_ frame: Binding<CGRect>) -> some View {
        self.modifier(IntrinsicFrame(frame: frame))
    }
}

用法:

struct MyView: View {
    @State private var frame = CGRect()

    var body: some View {
        Text("Hello")
            .intrinsicFrame($frame)
    }
}

关于swift - 仅当有足够空间时才显示 SwiftUI View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66179524/

相关文章:

列表内的 SWiftUI anchor 首选项

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

ios - Swift - 向 UITextfield 添加带有间距的底线

ios - 无法理解 fetchRequest.predicate

SwiftUI TextField 重置值并忽略绑定(bind)

swift - 在 SwiftUI 中突出显示文本的特定部分

SwiftUI 不同子项对齐和 GeometryReader

ios - 在 Realm 中查询具有反向关系的对象的正确方法

swift 图表 : customize X-axis composed of Date

ios - 限制 SwiftUI 中矩形边界的拖动