SwiftUI/SwiftUI 사용

[SwiftUI] 원하는 곳만 Corner Radius를 걸어주는 방법

hyunjuntyler 2023. 4. 23. 15:50

나의 집착..

나의 마지막 Corner Radius에 대한 집착... 아래는 위의 Rounding Corners를 만들기 위한 코드이다.

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Rounding Corners")
                .frame(width: 180, height: 70)
                .foregroundColor(Color.white)
                .background(Color.black)
                .roundingCorner(20, corners : [.topLeft, .topRight])
        }
    }
}

extension View {
    func roundingCorner(_ radius : CGFloat, corners : UIRectCorner) -> some View {
        clipShape(RoundedCorner(radius: radius, corners: corners))
    }
}

struct RoundedCorner : Shape {
    var radius : CGFloat
    var corners : UIRectCorner
    
    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        return Path(path.cgPath)
    }
}

RoundedCorner 구조체 생성

struct RoundedCorner : Shape {
    var radius : CGFloat
    var corners : UIRectCorner
    
    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        return Path(path.cgPath)
    }
}

RoundedCorner 구조체(struct)를 정의하고 Shape프로토콜을 따른다. 여기서 Shape프로토콜이라고 함은 "설계" 같은 것이다. 아래와 같은 path(in:)방법을 써서 매개변수를 받은 뒤 Path로 반환한다. 여기서는 radius로 모서리 반경을 정하고, corners로 어느 모서리에 적용할지 설정한다. UIRectCorner는 iOS에서 뷰의 모서리를 나타내는 열거형(enum)이다. 사각형의 모서리를 [.topLeft, .topRight, .bottomLeft, .bottomRight]로 받을 수 있다.

 

따라서 path를 통해 주어진 사각형인 rectUIBezierPath를 사용하여 둥근 모서리의 사각형을 return 한다! 이렇게 RoundedCorner가 어떠한 모양일지를 반환하였다. 그렇다면. clipShape를 사용하여 RoundedCorner모양으로 잘라줄 수 있다.

.clipShape(RoundedCorner(radius: 10, corners: [.topLeft, .topRight]))

roundingCorner 메서드 만들어주기

하지만 여기서 좀 더 간결하고 가독성이 좋게... roundingCorner를 만들어줄 것이다.

extension View {
    func roundingCorner(_ radius : CGFloat, corners : UIRectCorner) -> some View {
        clipShape(RoundedCorner(radius: radius, corners: corners))
    }
}

extension View를 사용하여 쓸 수 있게 만들어 주고, clipShape를 미리 해준다.

 

이렇게 되면 자유롭게 원하는 곳에만 CornerRadius를 걸어 줄 수 있다. (어디 쓸지는 모르겠지만...)