Swift中如何在UIImageView底部中间添加标记式三角形
在UIImageView底部中间添加三角形的实现方案
你可以通过两种常见方式实现这个需求:使用CAShapeLayer绘制三角形(适合快速添加)或者自定义UIImageView子类(适配AutoLayout更友好)。结合你现有的代码,我给你具体的实现示例:
方法一:使用CAShapeLayer直接添加三角形
这种方法不需要修改现有UIImageView的类型,直接给它的layer添加子layer即可:
let img_view: UIImageView! img_view = UIImageView(frame: CGRect(x: 0, y: 0, width: 30, height: 30)) let url_img = URL(string: Constants.img_url+"\(img)")! img_view.af_setImage(withURL: url_img) img_view.layer.cornerRadius = img_view.frame.size.height/2 img_view.layer.borderWidth = 1 img_view.layer.borderColor = UIColor.rgb(red: 229, green: 57, blue: 53, alpha: 1).cgColor img_view.clipsToBounds = false // 关键:如果三角形在UIImageView外部,需要关闭裁剪 // 1. 创建三角形的ShapeLayer let triangleLayer = CAShapeLayer() triangleLayer.fillColor = UIColor.rgb(red: 229, green: 57, blue: 53, alpha: 1).cgColor // 和边框同色,或者自定义 // 2. 绘制三角形路径(底部中间向外的三角形,可调整顶点坐标改变形状) let trianglePath = UIBezierPath() let centerX = img_view.bounds.midX let bottomY = img_view.bounds.maxY // 三个顶点:底部中心、左上方、右上方(向下的小三角形) trianglePath.move(to: CGPoint(x: centerX, y: bottomY)) trianglePath.addLine(to: CGPoint(x: centerX - 6, y: bottomY - 8)) trianglePath.addLine(to: CGPoint(x: centerX + 6, y: bottomY - 8)) trianglePath.close() triangleLayer.path = trianglePath.cgPath // 3. 添加到UIImageView的layer上 img_view.layer.addSublayer(triangleLayer)
注意点:
- 如果三角形需要显示在UIImageView外部,必须设置
img_view.clipsToBounds = false,否则会被圆形裁剪掉。 - 调整顶点坐标可以改变三角形的大小和方向:比如想让三角形向内(圆形内部底部),可以把
bottomY改成img_view.bounds.maxY - 4,另外两个点的y坐标再往上偏移。
方法二:自定义UIImageView子类(适配AutoLayout)
如果你的UIImageView是用AutoLayout布局的(非固定frame),自定义子类会更灵活,能自动适配尺寸变化:
class BadgeImageView: UIImageView { // 三角形颜色,默认和边框同色 var triangleColor: UIColor = UIColor.rgb(red: 229, green: 57, blue: 53, alpha: 1) { didSet { setNeedsDisplay() } } override func draw(_ rect: CGRect) { super.draw(rect) // 绘制三角形 let trianglePath = UIBezierPath() let centerX = rect.midX let bottomY = rect.maxY trianglePath.move(to: CGPoint(x: centerX, y: bottomY)) trianglePath.addLine(to: CGPoint(x: centerX - 6, y: bottomY - 8)) trianglePath.addLine(to: CGPoint(x: centerX + 6, y: bottomY - 8)) trianglePath.close() triangleColor.setFill() trianglePath.fill() } override func layoutSubviews() { super.layoutSubviews() // 确保圆角始终为圆形 layer.cornerRadius = bounds.height / 2 layer.borderWidth = 1 layer.borderColor = triangleColor.cgColor } }
替换使用这个子类:
let img_view = BadgeImageView(frame: CGRect(x: 0, y: 0, width: 30, height: 30)) let url_img = URL(string: Constants.img_url+"\(img)")! img_view.af_setImage(withURL: url_img) img_view.clipsToBounds = false // 三角形在外部时需关闭裁剪 // 可自定义三角形颜色:img_view.triangleColor = .yellow
额外优化建议:
- 如果需要三角形带边框,可以给
triangleLayer设置borderWidth和borderColor,或者在绘制路径时添加描边操作。 - 若UIImageView会有尺寸变化(比如旋转屏幕),方法二的自定义子类会自动重新绘制三角形,而方法一需要在
layoutSubviews中更新三角形路径。
内容的提问来源于stack exchange,提问作者Dimoreno
相关产品推荐
相关产品推荐

