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

iOS开发:UIImageView底部绘制UIBezierPath曲线位置异常问题

Fix: Ellipse Showing in Middle Instead of Bottom of UIView

Got it, let's work through why your ellipse is landing in the middle of imgCamera instead of sticking to the bottom. The issue boils down to two key things: your bezier path is probably centered by default, and the way you're setting up the layer mask in draw(_:) isn't optimized for positioning. Here's how to fix it step by step:

1. Rewrite the Bezier Path to Anchor to the Bottom

First, we need to make sure your pathCurvedForView method generates an ellipse that sits at the bottom of the view. Replace your existing implementation with this one, which calculates the ellipse's position explicitly:

func pathCurvedForView(givenView: UIView) -> UIBezierPath {
    // Adjust these values to tweak the ellipse's size
    let ellipseWidthRatio: CGFloat = 0.8 // 80% of the view's width
    let ellipseHeightRatio: CGFloat = 0.25 // 25% of the view's height
    
    let ellipseWidth = givenView.bounds.width * ellipseWidthRatio
    let ellipseHeight = givenView.bounds.height * ellipseHeightRatio
    
    // Calculate origin to center horizontally and lock to the bottom
    let originX = (givenView.bounds.width - ellipseWidth) / 2
    let originY = givenView.bounds.height - ellipseHeight
    
    let ellipseRect = CGRect(x: originX, y: originY, width: ellipseWidth, height: ellipseHeight)
    return UIBezierPath(ovalIn: ellipseRect)
}

2. Fix the Layer Mask Setup (Avoid draw(_:))

Using draw(_:) to set up layer masks isn't the best practice—it's designed for Core Graphics immediate drawing, not layer management. Instead, use layoutSubviews (which triggers when the view's size changes) to set up your mask reliably:

override func layoutSubviews() {
    super.layoutSubviews()
    applyBottomEllipseMask()
}

private func applyBottomEllipseMask() {
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = pathCurvedForView(givenView: imgCamera).cgPath
    shapeLayer.frame = imgCamera.bounds
    
    // This will make imgCamera only show the bottom ellipse area
    imgCamera.layer.mask = shapeLayer
}

Wait—Did You Want to Draw an Ellipse On Top of the View?

If you're not trying to mask the view (i.e., you just want an ellipse shape displayed at the bottom of imgCamera), skip the mask and add the shape layer as a sublayer instead:

private func addBottomEllipseShape() {
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = pathCurvedForView(givenView: imgCamera).cgPath
    shapeLayer.frame = imgCamera.bounds
    
    // Customize the appearance as needed
    shapeLayer.fillColor = UIColor.systemBlue.cgColor
    shapeLayer.strokeColor = UIColor.black.cgColor
    shapeLayer.lineWidth = 2.0
    
    imgCamera.layer.addSublayer(shapeLayer)
}

Call this method in viewDidLoad or layoutSubviews to render the ellipse.

Why Your Original Code Didn't Work

  • Your original pathCurvedForView likely generated a centered ellipse instead of anchoring to the bottom.
  • Initializing CAShapeLayer with CAShapeLayer(layer: imgCamera.layer) is unnecessary—this constructor is for copying layer properties, not creating a new shape layer.
  • Using draw(_:) for layer mask setup can lead to unexpected behavior, as it's triggered every time the view needs to redraw (not just when layout changes).

内容的提问来源于stack exchange,提问作者Chirag Shah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:44:51