この記事では、Viewの一角だけ角丸にする方法紹介します。
やりたいこと

こんな感じです。
現時点のSwiftUIでは、一角だけ角丸にするというのは簡単にはできません。。
探してみたら一応角丸にする方法がありましたので、この記事で共有していきたいと思います。
Qiitaの記事から2つの方法が見つかりました。
実装方法
1つ目の記事の方法
参考 【SwiftUI】 CornerRadiusを一部にのみ適用するQiitaシンプルに書けます。
以下のStructをどこかに貼り付けてください。
struct RoundedCorners: View {
var color: Color = .clear
var tl: CGFloat = 0.0
var tr: CGFloat = 0.0
var bl: CGFloat = 0.0
var br: CGFloat = 0.0
var body: some View {
GeometryReader { geometry in
Path { path in
let w = geometry.size.width
let h = geometry.size.height
let tr = min(min(tr, h/2), w/2)
let tl = min(min(tl, h/2), w/2)
let bl = min(min(bl, h/2), w/2)
let br = min(min(br, h/2), w/2)
path.move(to: CGPoint(x: w/2.0, y: 0))
path.addLine(to: CGPoint(x: w-tr, y: 0))
path.addArc(center: CGPoint(x: w-tr, y: tr), radius: tr, startAngle: Angle(degrees: -90), endAngle: Angle(degrees: 0), clockwise: false)
path.addLine(to: CGPoint(x: w, y: h-br))
path.addArc(center: CGPoint(x: w-br, y: h-br), radius: br, startAngle: Angle(degrees: 0), endAngle: Angle(degrees: 90), clockwise: false)
path.addLine(to: CGPoint(x: bl, y: h))
path.addArc(center: CGPoint(x: bl, y: h-bl), radius: bl, startAngle: Angle(degrees: 90), endAngle: Angle(degrees: 180), clockwise: false)
path.addLine(to: CGPoint(x: 0, y: tl))
path.addArc(center: CGPoint(x: tl, y: tl), radius: tl, startAngle: Angle(degrees: 180), endAngle: Angle(degrees: 270), clockwise: false)
}
.fill(color)
}
}
}
その後に、以下のように書くと一部の角を丸くできます。
VStack {
Text("Hello, world!")
.padding()
Text("Hello, world!")
.padding()
Text("Hello, world!")
.padding()
}
.background(RoundedCorners(color: .green, tl: 30, tr: 0, bl: 0, br: 30))
colorは背景色、tl(top leftの略)は左上、tr(top right)は右上、bl(bottom leftの略)は左下、br(bottom right)は右下です。
2つ目の記事の方法
参考 「一部だけ角丸にする」をSwiftUIで実現するQiita以下のコードをどこかに貼り付けてください。
struct PartlyRoundedCornerView: UIViewRepresentable {
let cornerRadius: CGFloat
let maskedCorners: CACornerMask
func makeUIView(context: UIViewRepresentableContext<PartlyRoundedCornerView>) -> UIView {
let uiView = UIView()
uiView.layer.cornerRadius = cornerRadius
uiView.layer.maskedCorners = maskedCorners
uiView.backgroundColor = .white
return uiView
}
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PartlyRoundedCornerView>) {
}
}
struct PartlyRoundedCornerModifier: ViewModifier {
let cornerRadius: CGFloat
let maskedCorners: CACornerMask
func body(content: Content) -> some View {
content.mask(PartlyRoundedCornerView(cornerRadius: self.cornerRadius, maskedCorners: self.maskedCorners))
}
}
extension View {
func cornerRadius(_ radius: CGFloat, maskedCorners: CACornerMask) -> some View {
self.modifier(PartlyRoundedCornerModifier(cornerRadius: radius, maskedCorners: maskedCorners))
}
}
その後で、以下のように書くと一部の角を丸くすることができます。
VStack {
Text("Hello, world!")
.padding()
Text("Hello, world!")
.padding()
Text("Hello, world!")
.padding()
}
.background(.green)
.cornerRadius(30, maskedCorners: [.layerMinXMinYCorner, .layerMaxXMaxYCorner])
丸みの大きさを決めて、maskedCorners:の中で丸くする場所を決めます。
.layerMinXMinYCornerが左上.layerMaxXMinYCornerが右上.layerMinXMaxYCornerが左下.layerMaxXMaxYCornerが右下
です。
まとめ
二つ目の方法はスマートですが、角の大きさを個別に変えることができません。ですので、角の大きさを個別に変えたいとなると、1つ目の方法がおすすめです。
