[SwiftUI] Shape

Junyoung Park·2022년 8월 20일
0

SwiftUI

목록 보기
33/136
post-thumbnail
post-custom-banner

Custom Shapes in SwiftUI | Advanced Learning #5

Shape

구현 목표

  • 특정 점에서 특정 점을 이어 새로운 형태의 도형(Shape)을 그리는 방법

구현 태스크

  1. Shape 프로토콜의 path 함수를 통해 새로운 도형 그리기
  2. 특정 이미지를 특정 도형 모양으로 자르기: clipShape

핵심 코드

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))
        }
    }
}
...
Image("Polar_Bear")
                .resizable()
                .scaledToFill()
                .frame(width: 300, height: 100)
                .clipShape(Trapezoid())
  • path.move는 도형의 특정 점으로 이동
  • path.addLine은 현재 위치에서 특정 위치(상대적 위치, Rect의 x, y 포인트를 통해 파악)로 이동하는 선 추가
  • clipShape를 통해 특정 Shape 모양에 이미지를 넣을 수 있음

소스 코드

import SwiftUI

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))
        }
    }
}

struct Diamond: Shape {
    func path(in rect: CGRect) -> Path {
        Path { path in
            let horizontalOffset: CGFloat = 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))

        }
    }
}

struct Trapezoid: Shape {
    func path(in rect: CGRect) -> Path {
        Path { path in
            let horizontalOffset: CGFloat = rect.width * 0.2
            path.move(to: CGPoint(x: rect.minX + horizontalOffset, y: rect.minY))
            path.addLine(to: CGPoint(x: rect.maxX - horizontalOffset, 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.minX + horizontalOffset, y: rect.minY))


        }
    }
}

struct CustomShapesBootCamp: View {
    var body: some View {
        VStack {
            Triangle()
                .stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round, dash: [10]))
                .fill(LinearGradient(gradient: Gradient(colors: [.red, .blue]), startPoint: .leading, endPoint: .trailing))
                .frame(width: 180, height: 160)
            Image("Polar_Bear")
                .resizable()
                .scaledToFill()
                .frame(width: 300, height: 100)
                .clipShape(Trapezoid())
        }
    }
}
profile
JUST DO IT
post-custom-banner

0개의 댓글