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

Swift中如何为UIImageView设置单侧圆角(含锯齿波浪等特殊样式)

UIImageView单侧锯齿波浪圆角实现方案

实现核心逻辑

你要的波浪锯齿效果本质是自定义裁剪路径,无法通过系统自带的圆角API直接实现,需要自己用贝塞尔路径拼接圆弧构造波浪边,其余三个边保持直线即可完成裁剪。


实现步骤

  • 第一步:先确定要裁剪的侧边(比如示例图中的底部)、波浪圆角的半径、单段波浪的宽度
  • 第二步:遍历波浪边的总长度,循环拼接凸/凹的圆弧,组成完整的闭合裁剪路径
  • 第三步:将自定义路径赋值给CAShapeLayer,作为UIImageView的mask蒙版,即可完成效果实现

代码示例(Swift)

// 扩展UIImageView,增加单侧波浪边裁剪方法
extension UIImageView {
    func addWavyRoundedCorner(on edge: UIRectEdge, waveRadius: CGFloat, waveCount: Int? = nil) {
        layoutIfNeeded()
        let viewBounds = self.bounds
        let customPath = UIBezierPath()
        
        // 起始点移动到左上角
        customPath.move(to: CGPoint(x: 0, y: 0))
        
        // 顶部边处理
        if edge != .top {
            customPath.addLine(to: CGPoint(x: viewBounds.maxX, y: 0))
        } else {
            // 顶部为波浪边时的绘制逻辑
            let totalWidth = viewBounds.width
            let singleWaveWidth = waveCount != nil ? totalWidth / CGFloat(waveCount!) : waveRadius * 2
            var currentX: CGFloat = 0
            var isConvex = true
            while currentX < totalWidth {
                let centerY = isConvex ? -waveRadius : waveRadius
                customPath.addArc(withCenter: CGPoint(x: currentX + singleWaveWidth/2, y: centerY), radius: waveRadius, startAngle: .pi, endAngle: 0, clockwise: !isConvex)
                currentX += singleWaveWidth
                isConvex.toggle()
            }
        }
        
        // 右侧边处理
        if edge != .right {
            customPath.addLine(to: CGPoint(x: viewBounds.maxX, y: viewBounds.maxY))
        }
        
        // 底部边处理(示例图效果对应底部波浪)
        if edge != .bottom {
            customPath.addLine(to: CGPoint(x: 0, y: viewBounds.maxY))
        } else {
            let totalWidth = viewBounds.width
            let singleWaveWidth = waveCount != nil ? totalWidth / CGFloat(waveCount!) : waveRadius * 2
            var currentX: CGFloat = viewBounds.maxX
            var isConvex = true
            while currentX > 0 {
                let centerY = isConvex ? viewBounds.maxY + waveRadius : viewBounds.maxY - waveRadius
                customPath.addArc(withCenter: CGPoint(x: currentX - singleWaveWidth/2, y: centerY), radius: waveRadius, startAngle: 0, endAngle: .pi, clockwise: isConvex)
                currentX -= singleWaveWidth
                isConvex.toggle()
            }
        }
        
        // 左侧边处理
        if edge != .left {
            customPath.addLine(to: CGPoint(x: 0, y: 0))
        }
        
        customPath.close()
        // 赋值给蒙版图层
        let maskLayer = CAShapeLayer()
        maskLayer.path = customPath.cgPath
        self.layer.mask = maskLayer
    }
}

// 调用示例
let targetImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 320, height: 240))
targetImageView.image = UIImage(named: "your_image_resource")
// 给底部添加波浪圆角,半径8,共20个波浪单元
targetImageView.addWavyRoundedCorner(on: .bottom, waveRadius: 8, waveCount: 20)

如果使用Objective-C实现,逻辑完全一致,仅需将语法替换为OC对应的UIBezierPath和CAShapeLayer写法即可。

注意事项

  • 调用方法前需要确保UIImageView的frame已经计算完成,避免裁剪错位,自动布局场景可以在layoutSubviews中调用,或者调用前执行layoutIfNeeded()
  • 可以按需调整waveRadius(波浪圆角半径)和waveCount(波浪数量)参数,匹配你需要的视觉效果
  • 如果需要多个侧边同时实现波浪效果,补充对应侧边的路径绘制逻辑即可

内容的提问来源于stack exchange,提问作者Fiaz Hussain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:45:05