iOS 15 SwiftUI堆叠条形图实现及左侧数据显示问题
修复SwiftUI堆叠条形图并添加左侧数据显示
原代码问题分析
- 用
VStack放置分段导致条形分散,无法实现垂直堆叠效果 HStack内的Spacer使用不当,造成条形间距混乱- 未处理堆叠偏移计算,分段未按高度叠加排列
修改后的完整代码
struct StackedBarChartView: View { let dataPoints: [String] let dataSets: [[Int]] // 子数组对应单个条形的分段数据 let colors: [Color] let fixedWidth: CGFloat // 计算单个条形的总数值,用于换算高度占比 private func totalValue(for barIndex: Int) -> CGFloat { CGFloat(dataSets[barIndex].reduce(0, +)) } var body: some View { HStack(alignment: .bottom, spacing: 20) { // 左侧数据刻度标签 VStack(alignment: .trailing, spacing: 0) { let allValues = dataSets.flatMap { $0 } let maxTotal = allValues.reduce(0, +) // 按步长生成刻度,可自行调整step值 ForEach(0...maxTotal step: 10) { value in Text("\(value)") .font(.caption) .frame(height: 300 / CGFloat(maxTotal) * 10) } } // 图表主体区域 VStack(alignment: .center) { // 横向排列所有堆叠条形 HStack(alignment: .bottom, spacing: 15) { ForEach(dataSets.indices, id: \.self) { barIndex in let total = totalValue(for: barIndex) ZStack(alignment: .bottom) { // 可选:条形背景占位,显示完整高度范围 RoundedRectangle(cornerRadius: 15) .fill(Color.gray.opacity(0.1)) .frame(width: fixedWidth, height: 300) // 堆叠的分段条形 VStack(spacing: 0) { ForEach(dataSets[barIndex].indices, id: \.self) { segmentIndex in let value = dataSets[barIndex][segmentIndex] let segmentHeight = CGFloat(value) / total * 300 RoundedRectangle(cornerRadius: 15) .fill(colors[segmentIndex % colors.count]) .frame(width: fixedWidth, height: segmentHeight) .overlay( // 可选:在分段内显示数值 Text("\(value)") .font(.system(size: 10)) .foregroundColor(.white) ) } } } } } // 底部分类标签 HStack(spacing: 15) { ForEach(dataPoints, id: \.self) { point in Text(point) .font(.caption) } } .padding(.top, 8) } } .padding() .frame(height: 350) .animation(.easeInOut, value: dataSets) } } struct ContentView: View { let dataPoints = ["A", "B", "C", "D"] let dataSets = [[20, 30, 40, 10], [10, 20, 30, 40], [5, 15, 10, 30]] let colors: [Color] = [.red, .green, .blue, .orange] var body: some View { StackedBarChartView(dataPoints: dataPoints, dataSets: dataSets, colors: colors, fixedWidth: 40) } }
关键修改说明
- 堆叠逻辑修复:
- 用
VStack(spacing: 0)替代分散布局,让分段垂直紧密堆叠 - 基于条形总数值计算分段高度占比,确保所有堆叠后总高度一致
- 用
- 左侧数据显示:
- 添加左侧
VStack作为刻度标签区,按总最大值比例分配刻度高度 - 可按需调整刻度步长,或改为显示每个分段的具体数值
- 添加左侧
- 布局优化:
- 用
HStack(alignment: .bottom)确保所有条形底部对齐 - 增加背景占位条,清晰展示条形高度范围
- 调整条形宽度和间距,提升视觉舒适度
- 用
- iOS15适配:
- 将动画绑定到
dataSets,避免iOS15下动画异常 - 固定条形宽度,适配不同屏幕尺寸
- 将动画绑定到
内容的提问来源于stack exchange,提问作者Muju
相关产品推荐
相关产品推荐

