이 세상에서 가장 알기 쉬운 SwiftUI의 패스 그리기

이 게시물은 무엇입니까?



SwiftUI 프레임워크에서 경로를 그리는 방법을 설명합니다.
아래 그림과 같은 「파이 차트 등을 묘화하기 위해서 이용할 수 있는 부채형」의 패스를 각 코드를 써 갑니다.



실행 환경



macOS 11.4
Xcode 12.5
Swift 5.4

핸즈온



여기서 연습하는 모양은 "경로의 시작과 끝"이 닫힐 때까지 볼 수 없습니다.
호를 그리면 미리보기에서 확인할 수 있습니다.

Shape 프로토콜



경로를 그리려면 Shape 프로토콜에 적합한 구조체를 정의합니다.
일반적인 SwiftUI 뷰와 같은 View 프로토콜이 아니므로 주의하십시오.

Pie 구조체에 Shape 프로토콜을 채용
import SwiftUI

struct Pie: Shape {
    func path(in rect: CGRect) -> Path {
        // draw and return Path
    }
}

형태에 Shape 프로토콜을 채용하면(자), path(in:) 메소드의 구현이 요구됩니다.
이 메소드의 바디로, 렌더링 하고 싶은 패스를 구현합니다.

경로의 인스턴스 만들기



그려지는 선은 Path 형태의 인스턴스입니다.
먼저 경로의 인스턴스를 만들고 그대로 반환합니다.

path(in
struct Pie: Shape {
    func path(in rect: CGRect) -> Path {        
        var path = Path()
        return path
    }
}

이후, 작성한 패스의 인스턴스에 대해서, 「어떠한 도형을 묘화할까」를 지정해 갑니다.

패스의 시작을 결정



화면의 중앙이 되는 점을 취득합니다.path(in:) 메소드가 받는다 rect 파라미터는, 그 패스가 draw 되는 화면의 정보를 가지고 있습니다.

path(in
struct Pie: Shape {
    func path(in rect: CGRect) -> Path {        
        let center = CGPoint(x: rect.midX, y: rect.midY)

        var path = Path()
        return path
    }
}

화면의 중앙점을 알면, 거기를 「경로의 시작 위치」라고 합니다.

펜을 중심으로 이동
struct Pie: Shape {
    func path(in rect: CGRect) -> Path {
        let center = CGPoint(x: rect.midX, y: rect.midY)

        var path = Path()
        path.move(to: center)
        return path
    }
}
move(to:) 메서드에서 경로의 인스턴스를 이동합니다.

직선을 그리다



파이의 호가 "시작되는 지점"까지 직선을 그립니다.
파이의 반경은 "화면 폭의 절반"입니다.
또, 원호의 개시점은 「화면의 중심으로부터 X축 방향으로 반경분만큼 이동한 지점」이라고 합니다.

직선을 그리다
struct Pie: Shape {    
    func path(in rect: CGRect) -> Path {
        let center = CGPoint(x: rect.midX, y: rect.midY)
        let radius = rect.width / 2
        let startPoint = CGPoint(
            x: center.x + radius,
            y: center.y
        )

        var path = Path()
        path.move(to: center)
        path.addLine(to: startPoint)
        return path
    }
}

호를 당기다


addArc(center:radius:startAngle:endAngle:clockwise) 메서드를 사용하여 호를 그릴 수 있습니다.
5개의 파라미터에는 각각, 이하의 값을 지정합니다.
  • 호의 중심점
  • 호의 반경
  • 호의 시작 각도
  • 호의 끝 각
  • 호의 진행 방향

  • Pie
    import SwiftUI
    
    struct Pie: Shape {
        let startAngle = Angle(degrees: 0)
        let endAngle   = Angle(degrees: 90)
    
        func path(in rect: CGRect) -> Path {
            let center = CGPoint(x: rect.midX, y: rect.midY)
            let radius = rect.width / 2
            let startPoint = CGPoint(
                x: center.x + radius,
                y: center.y
            )
    
            var path = Path()
            path.move(to: center)
            path.addLine(to: startPoint)
            path.addArc(center: center,
                        radius: radius,
                        startAngle: startAngle,
                        endAngle:   endAngle,
                        clockwise: false
            )
            return path
        }
    }
    

    호의 방향을 조정하려면 전체 경로의 각도를 변경합니다.
    struct Pie: Shape {
        let startAngle = Angle(degrees: 0-90)
        let endAngle   = Angle(degrees: 90-90)
    
        func path(in rect: CGRect) -> Path {
            let center = CGPoint(x: rect.midX, y: rect.midY)
            let radius = rect.width / 2
            let startPoint = CGPoint(
                x: center.x + radius * CGFloat(cos(startAngle.radians)),
                y: center.y + radius * CGFloat(sin(startAngle.radians))
            )
    
            var path = Path()
            path.move(to: center)
            path.addLine(to: startPoint)
            path.addArc(center: center,
                        radius: radius,
                        startAngle: startAngle,
                        endAngle:   endAngle,
                        clockwise: false
            )
            return path
        }
    }
    



    삼각 함수에 대해서는 여기 참고 에서 설명합니다.

    좋은 웹페이지 즐겨찾기