如何在Swift中为UIVIew制作曲线顶部?

3

enter image description here

我想让视图顶部呈曲线形状。我使用了以下代码,但它不能正常工作。请帮助我。

view.layer.cornerRadius = view.frame.width/2
view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
view.layer.masksToBounds = true

谢谢。

func roundedTop(targetView:UIView?, desiredCurve:CGFloat?){

    let offset:CGFloat =  targetView!.frame.width/desiredCurve!
    let bounds: CGRect = targetView!.bounds        
    let rectBounds: CGRect = CGRect(x: bounds.origin.x, y: bounds.origin.y+bounds.size.height / 2, width: bounds.size.width, height: bounds.size.height / 2)
    let rectPath: UIBezierPath = UIBezierPath(rect: rectBounds)
    let ovalBounds: CGRect = CGRect(x:bounds.origin.x - offset / 2,y: bounds.origin.y, width : bounds.size.width + offset, height :bounds.size.height)

    let ovalPath: UIBezierPath = UIBezierPath(ovalIn: ovalBounds)
    rectPath.append(ovalPath)

    // Create the shape layer and set its path
    let maskLayer: CAShapeLayer = CAShapeLayer()
    maskLayer.frame = bounds
    maskLayer.path = rectPath.cgPath

    [![// Set the newly created shape layer as the mask for the view's layer][1]][1]
    targetView!.layer.mask = maskLayer
}
2个回答

3

顶部曲线结果图片 底部曲线结果图片

Swift5代码

//TopRoundedCornerToView and BottomRoundedCornerToView

extension UIView {

func addTopRoundedCornerToView(targetView:UIView?, desiredCurve:CGFloat?)
{
    let offset:CGFloat =  targetView!.frame.width/desiredCurve!
    let bounds: CGRect = targetView!.bounds

    //Top side curve
    let rectBounds: CGRect = CGRect(x: bounds.origin.x, y: bounds.origin.y+bounds.size.height / 2, width: bounds.size.width, height: bounds.size.height / 2)
    
    let rectPath: UIBezierPath = UIBezierPath(rect: rectBounds)
    
    //Top side curve
    let ovalBounds: CGRect = CGRect(x: bounds.origin.x - offset / 2, y: bounds.origin.y, width: bounds.size.width + offset, height: bounds.size.height)
    
    let ovalPath: UIBezierPath = UIBezierPath(ovalIn: ovalBounds)
    rectPath.append(ovalPath)

    // Create the shape layer and set its path
    let maskLayer: CAShapeLayer = CAShapeLayer()
    maskLayer.frame = bounds
    maskLayer.path = rectPath.cgPath

    // Set the newly created shape layer as the mask for the view's layer
    targetView!.layer.mask = maskLayer
}
    
    func setTopCurve(){
           let offset = CGFloat(self.frame.size.height/4)
           let bounds = self.bounds
           let rectBounds = CGRect(x: bounds.origin.x, y: bounds.origin.y + bounds.size.height/2  , width:  bounds.size.width, height: bounds.size.height / 2)
        
           let rectPath = UIBezierPath(rect: rectBounds)
           
         let ovalBounds = CGRect(x: bounds.origin.x , y: bounds.origin.y - offset / 2, width: bounds.size.width + offset, height: bounds.size.height)
           let ovalPath = UIBezierPath(ovalIn: ovalBounds)
       rectPath.append(ovalPath)

           let maskLayer = CAShapeLayer.init()
           maskLayer.frame = bounds
           maskLayer.path = rectPath.cgPath
           self.layer.mask = maskLayer
       }
    
    func addBottomRoundedCornerToView(targetView:UIView?, desiredCurve:CGFloat?)
    {
        let offset:CGFloat =  targetView!.frame.width/desiredCurve!
        let bounds: CGRect = targetView!.bounds

        //Bottom side curve
        let rectBounds: CGRect = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.size.width, height: bounds.size.height / 2)

        let rectPath: UIBezierPath = UIBezierPath(rect: rectBounds)
        
        //Bottom side curve
        let ovalBounds: CGRect = CGRect(x: bounds.origin.x - offset / 2, y: bounds.origin.y, width: bounds.size.width + offset, height: bounds.size.height)
        
        let ovalPath: UIBezierPath = UIBezierPath(ovalIn: ovalBounds)
        rectPath.append(ovalPath)

        // Create the shape layer and set its path
        let maskLayer: CAShapeLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.path = rectPath.cgPath

        // Set the newly created shape layer as the mask for the view's layer
        targetView!.layer.mask = maskLayer
    }
        
        func setBottomCurve(){
               let offset = CGFloat(self.frame.size.height/4)
               let bounds = self.bounds
               
            let rectBounds = CGRect(x: bounds.origin.x, y: bounds.origin.y  , width:  bounds.size.width, height: bounds.size.height / 2)
               let rectPath = UIBezierPath(rect: rectBounds)
               let ovalBounds = CGRect(x: bounds.origin.x - offset / 2, y: bounds.origin.y, width: bounds.size.width + offset, height: bounds.size.height)
            
               let ovalPath = UIBezierPath(ovalIn: ovalBounds)
           rectPath.append(ovalPath)

               let maskLayer = CAShapeLayer.init()
               maskLayer.frame = bounds
               maskLayer.path = rectPath.cgPath
               self.layer.mask = maskLayer
           }
}

使用方法:

override func viewDidLoad() {
        super.viewDidLoad()
self.myTargateView.setTopCurve()
}

并且

override func viewWillLayoutSubviews() {
        self.myTargateView.addTopRoundedCornerToView(targetView: bottomView, desiredCurve: 10.0)

    }

0
问题在于你在viewDidLoad中调用了roundedTop方法过早。请等到第一次调用viewDidLayoutSubviews之后再调用。否则,你的targetView.frame以及由此产生的所有计算都是错误的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接