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

SwiftUI中为自定义形状(如菱形)添加条纹图案的实现方法

自定义形状+无图片条纹背景实现方案

针对斯坦福CS193P作业的需求,这里提供两种纯代码实现思路,全程无需图片资源:

1. 先实现自定义菱形Shape

基于SwiftUI的Shape协议,只需要实现path(in:)方法绘制菱形路径:

struct DiamondShape: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        let center = CGPoint(x: rect.midX, y: rect.midY)
        // 定义菱形四个顶点
        let top = CGPoint(x: center.x, y: rect.minY)
        let right = CGPoint(x: rect.maxX, y: center.y)
        let bottom = CGPoint(x: center.x, y: rect.maxY)
        let left = CGPoint(x: rect.minX, y: center.y)
        
        path.move(to: top)
        path.addLine(to: right)
        path.addLine(to: bottom)
        path.addLine(to: left)
        path.closeSubpath()
        return path
    }
}

2. 条纹背景实现方案

方案一:自定义条纹填充样式(直接给Shape填充)

通过自定义ShapeStyle,用线性渐变的重复平铺实现条纹,直接作为填充样式应用到菱形:

struct StripedStyle: ShapeStyle {
    let primaryColor: Color
    let secondaryColor: Color
    let stripeWidth: CGFloat
    let isVertical: Bool // 控制横向/纵向条纹

    func resolve(in environment: EnvironmentValues) -> some ShapeStyle {
        let gradient = LinearGradient(
            colors: [primaryColor, primaryColor, secondaryColor, secondaryColor],
            startPoint: isVertical ? .leading : .top,
            endPoint: isVertical ? .trailing : .bottom
        )
        // 缩放渐变并设置重复平铺,实现条纹效果
        return gradient
            .scaleEffect(
                x: isVertical ? stripeWidth * 2 / environment.size.width : 1,
                y: isVertical ? 1 : stripeWidth * 2 / environment.size.height
            )
            .tileMode(.repeated)
    }
}

// 使用示例
DiamondShape()
    .fill(StripedStyle(
        primaryColor: .blue,
        secondaryColor: .white,
        stripeWidth: 20,
        isVertical: false
    ))
    .frame(width: 200, height: 200)

方案二:遮罩法(更灵活支持斜纹/复杂形状)

先绘制全屏条纹背景,再用自定义菱形作为遮罩,将条纹裁剪成菱形形状,适合需要斜向条纹的场景:

struct StripedBackground: View {
    let color1: Color
    let color2: Color
    let angle: Angle
    let stripeWidth: CGFloat
    
    var body: some View {
        GeometryReader { geo in
            ForEach(0..<Int(geo.size.width / stripeWidth) * 2) { index in
                Rectangle()
                    .fill(index % 2 == 0 ? color1 : color2)
                    .frame(width: stripeWidth)
                    .offset(x: CGFloat(index) * stripeWidth / 2)
            }
            .rotationEffect(angle)
            .clipped()
        }
    }
}

// 使用示例
ZStack {
    StripedBackground(
        color1: .red,
        color2: .yellow,
        angle: .degrees(45),
        stripeWidth: 30
    )
}
.mask(DiamondShape())
.frame(width: 200, height: 200)

进阶优化

可以把条纹的宽度、角度、颜色做成可绑定变量,方便添加交互控件(比如滑块)动态调整参数,示例:

struct DiamondStripesDemo: View {
    @State private var stripeWidth = 25.0
    @State private var stripeAngle = 45.0
    
    var body: some View {
        ZStack {
            StripedBackground(
                color1: .purple,
                color2: .pink,
                angle: .degrees(stripeAngle),
                stripeWidth: stripeWidth
            )
        }
        .mask(DiamondShape())
        .frame(width: 300, height: 300)
        
        Slider(value: $stripeWidth, in: 5...50)
            .padding(.horizontal)
        Slider(value: $stripeAngle, in: 0...90)
            .padding(.horizontal)
    }
}

内容的提问来源于stack exchange,提问作者Rajiv Nair

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 23:47:27