我想知道 GeometryReader 是如何秘密工作的,并且我有兴趣构建一个用于学习目的的自定义 GeometryReader!
坦率地说,我认为我们在正文中使用的每个视图都是 GeometryReaderView 的一种,其区别在于它们不使用闭包来为我们发送代理,并且每个视图都会回调它的代理,这会很烦人!因此苹果决定将Geometry读取功能赋予GeometryReader!所以这只是我的想法!
因此,我正在寻找一种可能且更有可能的 SwiftUI-isch 方法来读取视图代理,或者换句话说,请参阅下面的代码:
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)
}
}
我还知道,视图的读取和报告代理不仅仅是视图的大小,还与坐标空间、框架有关......但现在为了使事情更容易解决,我只是在处理大小!所以尺寸很重要!
正如我所说,我对使用 UIKit 或 UIViewRepresentable 来读取大小不感兴趣!苹果可能会在幕后使用类似的东西,也可能不会!
我的目标是尝试用纯 SwiftUI 解决问题,或者你们中的一些人可能有一些关于 GeometryReader 源代码的良好链接,以便阅读和学习它。
好吧,SwiftUI 中有几种工具提供了对视图大小的访问(除了GeometryReader
当然)。
当然,问题是将这个大小值转移到视图构建阶段,因为只有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)
}
})
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)