SwiftUI中如何裁剪图片及边框的单个右上角?(iOS 15)
iOS 15 实现单个右上角裁剪(含边框)的方案
不管是SwiftUI还是UIKit,都能实现只裁剪右上角且边框同步适配的效果,具体实现代码如下:
SwiftUI 实现方式
自定义一个仅包含右上角圆角的Shape,用它完成视图裁剪后,直接添加边框即可让边框自动适配裁剪形状:
// 自定义裁剪形状 struct TopRightRoundedShape: Shape { let cornerRadius: CGFloat func path(in rect: CGRect) -> Path { var path = Path() let topRightCenter = CGPoint(x: rect.maxX, y: rect.minY) // 按顺序绘制路径,仅保留右上角圆角 path.move(to: .init(x: rect.minX, y: rect.minY)) path.addLine(to: .init(x: rect.minX, y: rect.maxY)) path.addLine(to: .init(x: rect.maxX, y: rect.maxY)) path.addLine(to: .init(x: rect.maxX, y: rect.minY + cornerRadius)) // 绘制右上角圆角弧 path.addArc(center: topRightCenter, radius: cornerRadius, startAngle: .degrees(270), endAngle: .degrees(180), clockwise: true) path.closeSubpath() return path } } // 使用示例 Image("你的图片名称") .resizable() .frame(width: 300, height: 200) .clipShape(TopRightRoundedShape(cornerRadius: 20)) // 执行右上角裁剪 .border(Color.blue, width: 2) // 边框自动适配裁剪后的形状
UIKit 实现方式
UIKit无法通过layer.cornerRadius单独指定单个角,需要通过遮罩裁剪图片,再自定义边框路径实现同步适配:
class TopRightClippedImageView: UIImageView { var clipRadius: CGFloat = 20 { didSet { updateClipEffect() } } override func layoutSubviews() { super.layoutSubviews() updateClipEffect() } private func updateClipEffect() { let rect = bounds let topRightCenter = CGPoint(x: rect.maxX, y: rect.minY) // 创建裁剪路径 let clipPath = UIBezierPath() clipPath.move(to: .init(x: rect.minX, y: rect.minY)) clipPath.addLine(to: .init(x: rect.minX, y: rect.maxY)) clipPath.addLine(to: .init(x: rect.maxX, y: rect.maxY)) clipPath.addLine(to: .init(x: rect.maxX, y: rect.minY + clipRadius)) clipPath.addArc(withCenter: topRightCenter, radius: clipRadius, startAngle: .pi * 3/2, endAngle: .pi, clockwise: true) clipPath.close() // 设置视图遮罩,完成图片裁剪 let maskLayer = CAShapeLayer() maskLayer.path = clipPath.cgPath layer.mask = maskLayer // 添加适配裁剪形状的边框 let borderLayer = CAShapeLayer() borderLayer.path = clipPath.cgPath borderLayer.strokeColor = UIColor.blue.cgColor borderLayer.fillColor = UIColor.clear.cgColor borderLayer.lineWidth = 2 layer.addSublayer(borderLayer) } } // 使用示例 let imageView = TopRightClippedImageView(frame: CGRect(x: 50, y: 50, width: 300, height: 200)) imageView.image = UIImage(named: "你的图片名称") imageView.clipRadius = 20 view.addSubview(imageView)
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

