gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 04:42:00 26 4
gpt4 key购买 nike

我想知道 GeometryReader 是如何隐藏的,我有兴趣为学习目的构建一个自定义 GeometryReader!

坦率地说,我认为我们在 body 中使用的每个 View 都是一种 GeometryReaderView,不同之处在于它们不使用闭包来为我们发送代理,而且每个 View 都会回调它的代理会很烦人!因此apple决定给GeometryReader赋予Geometry阅读功能!所以这只是我的想法!

所以我正在寻找一种可能而且更可能是 SwiftUI 式的方法来读取 View 的代理,或者换句话说,请查看我的代码:

struct ContentView: View {

var body: some View {

CustomGeometryReaderView { proxy in

Color.red
.onAppear() {
print(proxy)
}

}

}

}

struct CustomGeometryReaderView<Content: View>: View {

@ViewBuilder let content: (CGSize) -> Content

var body: some View {

// Here I most find a way to reading the available size for CustomGeometryReaderView and reporting it back!
return Color.clear.overlay(content(CGSize(width: 100.0, height: 100.0)), alignment: .topLeading)

}

}

我还知道, View 的读取和报告代理不仅仅是 View 的大小,它还与坐标空间、框架有关……但现在为了让事情更容易解决,我只关注大小!所以大小很重要!

正如我所说,我对使用 UIKit 或 UIViewRepresentable 来读取大小不感兴趣!苹果可能会在掩护下使用类似的东西,也可能不会!我的目标是尝试使用纯 SwiftUI 解决问题,或者你们中的一些人可能有一些关于 GeometryReader 源代码的好链接以供阅读和学习。

最佳答案

好的,SwiftUI 中有多种工具可以访问 View 大小(当然 GeometryReader 除外)。

问题当然是将该尺寸值转移到 View 构建阶段,因为只有 GeometryReader 允许在同一构建周期中执行此操作。

这是使用 Shape 的可能方法的演示 - 设计的形状没有自己的大小并消耗所有可用的东西,因此覆盖所有区域,并且已提供该区域作为输入。

使用 Xcode 13/iOS 15 测试

struct CustomGeometryReaderView<Content: View>: View {

@ViewBuilder let content: (CGSize) -> Content

private struct AreaReader: Shape {
@Binding var size: CGSize

func path(in rect: CGRect) -> Path {
DispatchQueue.main.async {
size = rect.size
}
return Rectangle().path(in: rect)
}
}

@State private var size = CGSize.zero

var body: some View {
// by default shape is black so we need to clear it explicitly
AreaReader(size: $size).foregroundColor(.clear)
.overlay(Group {
if size != .zero {
content(size)
}
})
}
}

备用:相同,但使用基于回调的模式

struct CustomGeometryReaderView<Content: View>: View {

@ViewBuilder let content: (CGSize) -> Content

private struct AreaReader: Shape {
var callback: (CGSize) -> Void

func path(in rect: CGRect) -> Path {
callback(rect.size)
return Rectangle().path(in: rect)
}
}

@State private var size = CGSize.zero

var body: some View {
AreaReader { size in
if size != self.size {
DispatchQueue.main.async {
self.size = size
}
}
}
.foregroundColor(.clear)
.overlay(Group {
if size != .zero {
content(size)
}
})
}
}

关于swift - 我们如何在 SwiftUI 中制作自定义 GeometryReader?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69918942/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com