You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中为BarMark添加交叉影线(条纹)样式的实现求助

为SwiftUI Charts的BarMark添加交叉影线图案

以下是两种可行的实现方案,直接适配你现有的代码结构:

方案一:自定义交叉影线Shape + ImagePaint

通过自定义Shape绘制交叉线条,再将其转换为可重复的图案应用到BarMark上:

  1. 定义交叉影线的Shape:
struct CrossHatchPattern: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        // 绘制45度交叉斜线
        let spacing: CGFloat = 15
        // 正斜线
        for offset in stride(from: -rect.width, through: rect.width + rect.height, by: spacing) {
            path.move(to: CGPoint(x: offset, y: 0))
            path.addLine(to: CGPoint(x: offset + rect.height, y: rect.height))
        }
        // 反斜线
        for offset in stride(from: -rect.height, through: rect.width + rect.height, by: spacing) {
            path.move(to: CGPoint(x: 0, y: offset))
            path.addLine(to: CGPoint(x: rect.width, y: offset - rect.width))
        }
        return path
    }
}
  1. 修改原Chart代码,替换BarMark的前景样式:
struct ContentView: View {
    struct ChartData: Hashable {
        let date: Date
        let value: Double
    }
    
    @State private var model: [ChartData] = [
        ChartData(date: Calendar.current.date(byAdding: .month, value: -1, to: Date())!, value: 70),
        ChartData(date: Date(), value: 170),
        ChartData(date: Calendar.current.date(byAdding: .month, value: 1, to: Date())!, value: 45)
    ]
    
    private let barWidth: CGFloat = 40.0
    
    var body: some View {
        Chart {
            ForEach(model, id: \.self) { data in
                BarMark(
                    x: .value("Date", data.date),
                    yStart: .value("Start", 0),
                    yEnd: .value("End", data.value),
                    width: .fixed(barWidth)
                )
                .foregroundStyle(
                    ImagePaint(
                        image: Image(uiImage: UIGraphicsImageRenderer(size: CGSize(width: 20, height: 20)).image { context in
                            // 绘制底色+交叉线
                            Color.yellow.fill(context.cgContext)
                            CrossHatchPattern()
                                .stroke(Color.black, lineWidth: 1)
                                .fill(context.cgContext)
                        }),
                        scale: 0.1 // 调整缩放比例控制线条密度
                    )
                )
            }
        }
        .chartXAxis(.hidden)
        .chartYAxis(.hidden)
        .padding()
    }
}

方案二:使用现成图案图片

如果你有现成的交叉影线图片资源,可直接加载使用:

// 替换BarMark的foregroundStyle部分
.foregroundStyle(
    ImagePaint(image: Image("crosshatch"), scale: 0.2)
)

调整说明

  • 修改scale参数可控制交叉线密度,数值越小线条越密
  • 更改stroke的Color和lineWidth可调整交叉线的颜色与粗细
  • 若需要横竖直线交叉而非斜线,修改CrossHatchPattern中的路径绘制逻辑即可

内容的提问来源于stack exchange,提问作者Fatih Ozturk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 13:16:07