Starbucks Caramel Frappuccino
본문 바로가기
  • 그래 그렇게 조금씩
SwiftUI/SwiftUI(Advanced)

4. custom Shape / path

by Toughie 2023. 6. 20.

🦁custom Shape / path🦁

SwiftUI에는 기본 shape가 많다.

Circle, Rectangle, RoundedRectangle, Capsule 등..

하지만 삼각형, 다이아몬드 등 다른 형태가 필요하다면, 이걸 코드로 구현하려면 shape를 커스텀 할 수 있다.

 

만약 기본 Rectangle로 삼각형을 만든다면..

            Rectangle()
                .trim(from: 0, to : 0.5)
                .frame(width: 100, height: 100)
                .rotationEffect(Angle.degrees(-45), anchor: .center)

이렇게 자르고 돌려서 만들 수는 있다..

하지만 아예 커스텀 shape를 만드는 방법이 더 낫다고 생각한다.

좀 더 입맛에 맞게 그릴 수 있기 때문이다.

struct Triangle: Shape {
    func path(in rect: CGRect) -> Path {
        Path { path in
            path.move(to: CGPoint(x: rect.midX, y: rect.minY))
            path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
            path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
            path.addLine(to: CGPoint(x: rect.midX, y: rect.minY))
        }
    }
}

코드를 쉽게 설명하면 시작점을 찍고, 선분을 그리는 것이다. 

여기서 rect는 CGRect 타입의 파라미터로, shape를 그릴 프레임을 나타낸다.

Preview Selectable에서 눌러보면 나오는 이 푸른 영역이 프레임!

CG는 Core Graphics의 약자로, 그래픽 처리 작업을 위한 2D 그래픽 렌더링 엔진 프레임워크이다.

CGRect는 Core Graphics 프레임워크에서 사용되는 사각형의 위치와 크기를 나타내는 구조체인것.

 

path(in:)메서드는 Shape 프로토콜의 요구사항이다.

주어진 사각형 프레임 내부에서 원하는 형태를 그리는데 사용되는 경로(Path)를 반환한다.


다이아몬드를 그린다면

struct Diamond: Shape {
    func path(in rect: CGRect) -> Path {

        Path { path in
            let horizontalOffset = rect.width * 0.2
            path.move(to: CGPoint(x: rect.midX, y: rect.minY))
            path.addLine(to: CGPoint(x: rect.maxX - horizontalOffset, y: rect.midY))
            path.addLine(to: CGPoint(x: rect.midX, y: rect.maxY))
            path.addLine(to: CGPoint(x: rect.minX + horizontalOffset, y: rect.midY))
            path.addLine(to: CGPoint(x: rect.midX, y: rect.minY))
            
        }
    }
}


...

Diamond()
    .fill(LinearGradient(colors: [Color.blue, Color.white, Color.blue.opacity(0.5),Color.white, Color.blue.opacity(0.2)], startPoint: .topLeading, endPoint: .bottomLeading))
    .frame(width: 200, height: 200)

이외에도 곡선, 애니메이션을 추가해서 다양한 커스텀 shape를 그릴 수 있다.

하지만 정말 고퀄리티의 형태가 필요하다면 이미지나 일러스트, lottie등을 활용하는 방법이 효율적이지 않을까 싶다. 🤔