この記事では、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つ目の方法がおすすめです。