gpt4 book ai didi

swift - 在 SwiftUI 中拥抱 subview

转载 作者:搜寻专家 更新时间:2023-10-31 08:28:02 26 4
gpt4 key购买 nike

Dave Abrahams 在他关于自定义 View 的 WWDC19 演讲中解释了 SwiftUI 布局的一些机制,但他遗漏了一些内容,我无法正确调整 View 大小。

有没有办法让 View 告诉它的容器它没有任何空间需求,但它会使用它所提供的所有空间?另一种说法是容器应该拥抱它的 subview 。

具体的例子,我想要像c这样的东西:

Some Texts inside a VStack

如果你有一些 TextVStack 里面就像在 a) 中一样,VStack将采用它的宽度到最宽的 subview 。

如果你添加一个Rectangle尽管与 b) 中一样,它会尽可能地扩展,直到 VStack。填充它的容器。

这表明Text s 和 Rectangle在布局方面,s 属于不同的类别,Text具有固定大小和 Rectangle是贪婪的。 但是,如果我自己制作 View,我该如何将其传达给我的容器? ?

我其实想要达到的结果是c)。 VStack 应该在确定其大小时忽略 Rectangle(或我的自定义 View ),然后一旦完成,然后它应该告诉 Rectangle 或我的自定义 View ,它可以有多少空间。

鉴于SwiftUI似乎是自下而上布局,也许这是不可能的,但似乎应该有some。实现这一目标的方法。

最佳答案

没有修饰符 (AFAIK) 可以实现此目的,所以这是我的方法。如果这是您要经常使用的东西,那么创建您自己的修饰符可能是值得的。

另请注意,我在这里使用的是标准首选项,但 anchor 首选项更好。在这里解释是一个沉重的话题。我写了一篇文章,您可以在这里查看:https://swiftui-lab.com/communicating-with-the-view-tree-part-1/

您可以使用下面的代码来完成您要查找的内容。

import SwiftUI

struct MyRectPreference: PreferenceKey {
typealias Value = [CGRect]

static var defaultValue: [CGRect] = []

static func reduce(value: inout [CGRect], nextValue: () -> [CGRect]) {
value.append(contentsOf: nextValue())
}
}

struct ContentView : View {
@State private var widestText: CGFloat = 0

var body: some View {
VStack {
Text("Hello").background(RectGetter())
Text("Wonderful World!").background(RectGetter())
Rectangle().fill(Color.blue).frame(width: widestText, height: 30)
}.onPreferenceChange(MyRectPreference.self, perform: { prefs in
for p in prefs {
self.widestText = max(self.widestText, p.size.width)
}
})
}
}

struct RectGetter: View {

var body: some View {
GeometryReader { geometry in
Rectangle()
.fill(Color.clear)
.preference(key: MyRectPreference.self, value: [geometry.frame(in: .global)])
}
}
}

关于swift - 在 SwiftUI 中拥抱 subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56822791/

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