-1

I want to change rectangle proportions dynamically but preserving semicircle's proportions. Semicircle should be aligned to the bottom and centered horizontally:

enter image description here

How can I add more slicing lines to UIImage in Xcode?

I have made what I want in Nine Patch editor for android, but it isn't compatible with iOS.

enter image description here

alexburtnik
  • 7,661
  • 4
  • 32
  • 70
Igor Kasuan
  • 792
  • 2
  • 10
  • 25

1 Answers1

1

There is no way to stretch UIImage like you want, but you can do it programmatically. I've implemented a custom UIView with CAShapeLayer inside:

import UIKit

class CustomShapeView: UIView {

    private let shapeLayer = CAShapeLayer()
    var radius = CGFloat(0)
    var shadowRadius = CGFloat(5)

    override func draw(_ rect: CGRect) {
        backgroundColor = UIColor.clear

        shapeLayer.frame = self.bounds
        shapeLayer.fillColor = UIColor.white.cgColor
        shapeLayer.path = createShapePath().cgPath

        shapeLayer.shadowPath = shapeLayer.path
        shapeLayer.shadowColor = UIColor.black.cgColor
        shapeLayer.shadowOffset = .zero
        shapeLayer.shadowRadius = shadowRadius
        shapeLayer.shadowOpacity = 0.5

        layer.addSublayer(shapeLayer)
    }

    func createShapePath () -> UIBezierPath {
        let path = UIBezierPath()

        let w = self.bounds.size.width
        let h = self.bounds.size.height
        let circleLever: CGFloat = radius * 0.552

        path.move(to: CGPoint(x: w/2 - radius, y: h))
        path.addLine(to: CGPoint(x: 0, y: h))
        path.addLine(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x: w, y: 0))
        path.addLine(to: CGPoint(x: w, y: h))
        path.addLine(to: CGPoint(x: w/2 + radius, y: h))

        path.addCurve(to: CGPoint(x: w/2, y: h - radius), controlPoint1:CGPoint(x: w/2 + radius, y: h - circleLever), controlPoint2:CGPoint(x: w/2 + circleLever, y: h - radius))
        path.addCurve(to: CGPoint(x: w/2 - radius, y: h), controlPoint1:CGPoint(x: w/2 - circleLever, y: h - radius), controlPoint2:CGPoint(x: w/2 - radius, y: h - circleLever))
        path.close()
        path.move(to: CGPoint(x: w/2 - radius, y: h))

        return path
    }        
}

You can set whatever size and any radius you want, circle's center will always be on the bottom edge of the view. You also can change shadowRadius if you wish.

Setup in Interface Builder:

enter image description here

Result:

enter image description here

alexburtnik
  • 7,661
  • 4
  • 32
  • 70