【发布时间】:2021-04-12 20:56:25
【问题描述】:
我希望两个按钮的高度相同,类似于 UIKit 中的Equal Height 约束。
- 不想指定框架,让 SwiftUI 处理,但 HStack 中的元素应该是相同的高度。
- 按钮应具有相同的宽度和高度,并适应较长的文本并增加其框架大小
- 两个按钮都应显示其完整的文本(不应使用字体缩放/适合)
示例代码
struct SampleView: View {
var body: some View {
GeometryReader { gr in
VStack {
ScrollView {
VStack {
// Fills whatever space is left
Rectangle()
.foregroundColor(.clear)
Image(systemName: "applelogo")
.resizable()
.frame(width: gr.size.width * 0.5, height: gr.size.height * 0.3, alignment: .center)
//.border(Color.blue)
.padding(.bottom, gr.size.height * 0.06)
Text("SOME TEXT SOME TEXT SOME TEXT SOME TEXT SOME TEXT SOME TEXT SOME TEXT SOME TEXT SOME TEXT SOME TEXT SOME TEXT SOME TEXT SOME")
.fontWeight(.regular)
.foregroundColor(.green)
.multilineTextAlignment(.center)
.padding(.horizontal, 40)
.layoutPriority(1)
// Fills 15 %
Rectangle()
.frame(height: gr.size.height * 0.12)
.foregroundColor(.clear)
DynamicallyScalingView()
.padding(.horizontal, 20)
.padding(.bottom, 20)
}
// Makes the content stretch to fill the whole scroll view, but won't be limited (it can grow beyond if needed)
.frame(minHeight: gr.size.height)
}
}
}
}
}
struct DynamicallyScalingView: View {
@State private var labelHeight = CGFloat.zero // << here !!
var body: some View {
HStack {
Button(action: {
}, label: {
Text("Button 1")
})
.foregroundColor(Color.white)
.padding(.vertical)
.frame(minWidth: 0, maxWidth: .infinity)
.frame(minHeight: labelHeight)
.background(Color.blue)
.cornerRadius(8)
Button(action: {
}, label: {
Text("Larger Button 2 Text Text2")
})
.foregroundColor(Color.white)
.padding(.vertical)
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.blue)
.cornerRadius(8)
.background(GeometryReader { // << set right side height
Color.clear.preference(key: ViewHeightKey.self,
value: $0.frame(in: .local).size.height)
})
}
.onPreferenceChange(ViewHeightKey.self) { // << read right side height
self.labelHeight = $0 // << here !!
}
.padding(.horizontal)
}
}
struct ViewHeightKey: PreferenceKey {
static var defaultValue: CGFloat { 0 }
static func reduce(value: inout Value, nextValue: () -> Value) {
value = value + nextValue()
}
}
struct SampleView_Previews: PreviewProvider {
static var previews: some View {
SampleView().previewDevice("iPhone SE (2nd generation)")
}
}
【问题讨论】:
-
在 SwiftUI 中,父视图不能像 UIKit 中那样“强制”子视图大小。
-
这是否回答了您的问题stackoverflow.com/a/62451599/12299030?
-
第二个按钮出现长文本怎么办,应该剪掉吗?
-
@Asperi,感谢您为我指明正确的方向。是的,它确实适用于您使用首选项键指出的方式。不幸的是,我的观点有更多的元素,让我更新问题。
标签: ios swift swiftui scrollview geometryreader