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
相关产品推荐
相关产品推荐

