I want to change rectangle proportions dynamically but preserving semicircle's proportions. Semicircle should be aligned to the bottom and centered horizontally:
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.
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:
Result: