如何让SwiftUI矩形固定在基准线上绘制?
问题
我想要创建一个音频平衡控件,用两个矩形分别表示左右声道的声像(pan)值,目前通过滑块输入数值。但无论调整Geometry、基线和对齐方式,矩形始终悬浮无法固定在底部,希望调整高度时从底部向上变化而非从中部扩展。
相关代码如下:
import Foundation import SwiftUI struct PanView: View { @Binding var value: Double var body: some View { HStack(spacing: 10) { leftBar rightBar } } private var leftBar: some View { Rectangle() .fill(Color(.green)) .frame(width: barWidth, height: abs(value - 50), alignment: .bottom) } private var rightBar: some View { Rectangle() .fill(Color(.red)) .frame(width: barWidth, height: abs(value + 50), alignment: .bottom) } private var barWidth: CGFloat { return 50 // Adjust the width as per your preference } } struct PanView_Used: View { @State private var barValue:Double = 0.0 var body: some View { VStack { Text("Bar Graph at \(Int(barValue))") .font(.title) PanView(value: $barValue) Slider(value: $barValue, in: -50...50, step:Double.Stride(1), onEditingChanged: {e in}) } } } struct PV_Previews: PreviewProvider { static var previews: some View { PanView_Used() } }
当前效果不佳:

解决方案
核心问题是未给PanView设置固定高度基准,且单个条形未锚定到底部容器。修改后的实现如下:
import Foundation import SwiftUI struct PanView: View { @Binding var value: Double // 定义条形最大高度,可按需调整 private let maxBarHeight: CGFloat = 200 var body: some View { HStack(spacing: 10) { leftBar rightBar } // 给整个控件设置固定高度,作为布局基准 .frame(height: maxBarHeight) } private var leftBar: some View { Rectangle() .fill(Color(.green)) .frame(width: barWidth) // 计算高度:value=-50时左条满高,value=50时左条高度为0 .frame(height: CGFloat((50 - value) / 100 * maxBarHeight)) // 锚定底部,高度变化时向上扩展 .frame(maxHeight: .infinity, alignment: .bottom) } private var rightBar: some View { Rectangle() .fill(Color(.red)) .frame(width: barWidth) // 计算高度:value=50时右条满高,value=-50时右条高度为0 .frame(height: CGFloat((50 + value) / 100 * maxBarHeight)) // 锚定底部,高度变化时向上扩展 .frame(maxHeight: .infinity, alignment: .bottom) } private var barWidth: CGFloat { return 50 // 按需调整宽度 } } struct PanView_Used: View { @State private var barValue: Double = 0.0 var body: some View { VStack(spacing: 20) { Text("Bar Graph at \(Int(barValue))") .font(.title) PanView(value: $barValue) Slider(value: $barValue, in: -50...50, step: 1) } .padding() } } struct PV_Previews: PreviewProvider { static var previews: some View { PanView_Used() } }
关键改动说明:
- 新增
maxBarHeight常量,统一控制条形高度上限,明确布局基准; - 给
PanView的HStack设置固定高度,确保控件有稳定的布局范围; - 调整高度计算逻辑,通过线性映射实现滑块值与条形高度的对应关系;
- 给每个条形添加
.frame(maxHeight: .infinity, alignment: .bottom),让条形锚定底部,高度变化时从底部向上扩展。
内容的提问来源于stack exchange,提问作者Hoshi
相关产品推荐
相关产品推荐

