使用 SwiftUI,有没有办法将视图的大小限制为另一个非兄弟视图? [英] With SwiftUI, is there a way to constrain a view's size to another non-sibling view?
问题描述
我正在摆弄一个视图布局 - 一个图表 - 在那里我看到我可以在全 SwiftUI 布局中走多远.每个组成部分都很好,但组装整体并不像我想要的那样工作.我发现我可以轻松地沿单个堆栈轴限制大小 - 但不能同时限制两个轴(垂直和水平).
I'm fiddling with a view layout - a graph - where I'm seeing how far I can get within an all-SwiftUI layout. Each of the component pieces are fine, but assembling the whole isn't working quite as I'd like. What I've found is that I can easily constrain sizing along a single stack axis - but not two axis at once (both vertical and horizontal).
我开始接触 AlignmentGuides,因为我发现 您可以将非兄弟姐妹与自定义指南对齐.这将有助于我的目标,但它不能解决尺寸部分,这是这个问题的核心:
I started to reach for AlignmentGuides, as I found you can align non-siblings with a custom guide. That will help my goal, but it doesn't solve the sizing part, which is the heart of this question:
有没有办法根据另一个非同级视图来限制视图的大小?
Is there a way to constrain a view's size based on another, non-sibling, view?
结构的简化是:
HStack {
CellOneView {
}
CellTwoView {
}
}
HStack {
CellThreeView {
}
CellFourView {
}
}
映射到:
+-----+-----+
| 1 | 2 |
+-----+-----+
| 3 | 4 |
+-----+-----+
有没有办法告诉 CellFour(它与单元格的 1 和 2 不在同一个 HStack 中)我希望它约束自己(并对齐)到单元格 CellTwo 的宽度?
Is there a way to tell CellFour (which isn't in the same HStack as cell's 1 and 2) that I want it to constrain itself (and align) to the width of cell CellTwo?
这不一定是严格的网格视图(网格视图示例).在这种情况下,我真正关心的只有三个视图 - 大致映射到单元格 1、单元格 2 和单元格 4 的区域.我希望单元格 1 和单元格 2 的高度相同(使用当前的HStack
),并且单元格 2 和单元格 4 的宽度相同 - 这就是我正在努力的地方.
This does not need to strictly be a grid view (example of grid view). There are really only three views that I care about in this case - the areas that roughly map to cell 1, cell 2, and cell 4. I want the heights of Cell 1 and Cell 2 to be the same (accomplished easily with the current HStack
), and the widths of Cell 2 and Cell 4 to be the same - that's where I'm struggling.
推荐答案
1.获取尺寸
struct CellTwoView: View {
var body: some View {
Rectangle()
.background(
GeometryReader(content: { (proxy: GeometryProxy) in
Color.clear
.preference(key: MyPreferenceKey.self, value: MyPreferenceData(rect: proxy.size))
})
)
}
}
说明 - 在这里,我使用背景视图(Color.clear)获得了视图的大小,除非从 CellTwoView 本身获取大小,否则我使用了这个技巧;因为 SwiftUI-View 的大小是由视图本身决定的,如果它们有大小(父级不能像 UIKit 那样改变大小).因此,如果我将 GeometryReader
与 CellTwoView 本身一起使用,那么 GeometryReader
会占用 CellTwoView 的 父 中可用的大小.-> 原因 -> GeometryReader 取决于它们的父级大小. (实际上这是另一个主题,也是 SwiftUI 中的主要内容)
Explanation - Here I have get the size of the view from using background View ( Color.clear ) , I used this trick unless getting the size from CellTwoView itself ; 'cause of SwiftUI-View size is determined by the view itself If they have size ( parent cannot change the size like in UIKit ). so if I use GeometryReader
with CellTwoView itself , then the GeometryReader
takes as much as size available in the parent of CellTwoView. - > reason -> GeometryReader depends on their parent size. (actually this is another topic and the main thing in SwiftUI)
键 ->
struct MyPreferenceKey: PreferenceKey {
static var defaultValue: MyPreferenceData = MyPreferenceData(size: CGSize.zero)
static func reduce(value: inout MyPreferenceData, nextValue: () -> MyPreferenceData) {
value = nextValue()
}
typealias Value = MyPreferenceData
}
值(以及当偏好改变时如何处理)->
struct MyPreferenceData: Equatable {
let size: CGSize
//you can give any name to this variable as usual.
}
2.将尺寸应用到另一个视图
struct ContentView: View {
@State var widtheOfCellTwoView: CGFloat = .zero
var body: some View {
VStack {
HStack {
CellOneView()
CellTwoView ()
.onPreferenceChange(MyPreferenceKey.self) { (prefereneValue) in
self.widtheOfCellTwoView = prefereneValue.size.width
}
}
HStack {
CellThreeView ()
CellFourView ()
.frame(width: widtheOfCellTwoView)
}
}
}
}
这篇关于使用 SwiftUI,有没有办法将视图的大小限制为另一个非兄弟视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!