UIBezierPathで半円をつくる
上と下を分割して半円をくっつけて正円を作るようなUIを実現するためにUIBezierPathを使って実装してみました。
最終的に以下のようなUIを作りました
ダメな例
Viewを2つくっつけて配置して一部だけ角丸にすれば良いと考えて試してみたんですが、横幅と縦幅違うので綺麗に丸まってくれませんでした。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var topView: UIView!
@IBOutlet weak var bottomView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
topView.layer.cornerRadius = 50
topView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
bottomView.layer.cornerRadius = 50
bottomView.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
}
}
UIBezierPathを使った方法
import UIKit
import PlaygroundSupport
let view = UIView()
view.frame = CGRect(x: 0, y: 0, width: 400, height: 400)
view.backgroundColor = .white
PlaygroundPage.current.liveView = view
let topCircleLayer = CAShapeLayer()
topCircleLayer.frame = CGRect(x: 0, y: 0, width: 400, height: 400)
topCircleLayer.lineWidth = 1.0
topCircleLayer.strokeColor = UIColor.gray.cgColor
topCircleLayer.fillColor = UIColor.green.cgColor
view.layer.addSublayer(topCircleLayer)
let bottomCircleLayer = CAShapeLayer()
bottomCircleLayer.frame = CGRect(x: 0, y: 0, width: 400, height: 400)
bottomCircleLayer.lineWidth = 1.0
bottomCircleLayer.strokeColor = UIColor.gray.cgColor
bottomCircleLayer.fillColor = UIColor.cyan.cgColor
view.layer.addSublayer(bottomCircleLayer)
let center = CGPoint(x: 200, y: 200)
let radius = CGFloat(100)
let topStartAngle = CGFloat(1.0 * .pi)
let topEndAngle = CGFloat(0.0 * .pi)
let bottomStartAngle = CGFloat(0.0 * .pi)
let bottomEndAngle = CGFloat(1.0 * .pi)
let topArc = UIBezierPath(arcCenter: center,
radius: radius,
startAngle: topStartAngle,
endAngle: topEndAngle,
clockwise: true)
topCircleLayer.path = topArc.cgPath
let bottomArc = UIBezierPath(arcCenter: center,
radius: radius,
startAngle: bottomStartAngle,
endAngle: bottomEndAngle,
clockwise: true)
bottomCircleLayer.path = bottomArc.cgPath
補足
View一面にlayerを広げるように円のサイズを指定してしまうとボーダーが切れてしまうので、一面に広げる場合は円の半径を-1してボーダーが切れないようにする必要がありそうです。