기어가더라도 제대로

[SwiftUI-기초] strokeBorder() - 도형을 프레임에 딱맞게 본문

SwiftUI - 기초

[SwiftUI-기초] strokeBorder() - 도형을 프레임에 딱맞게

Damagucci-juice 2022. 11. 16. 16:35
  • .stroke: path 따라서 테두리를 색칠하는 메서드
    • 이용가능한 프레임을 넘겨버림
  • 선을 안쪽으로 그림을 그리고 싶다하면 위의 메서드를 사용해서는 안됨
  • 왜냐하면 직선을 따라서 뭉툭한 연필을 이용해 따라 그리는 상황을 상상해보면
  • 연필의 정중앙이 직선에 오도록하고 그릴 것임
  • 연필은 직선위를 지나므로 양옆으로 넘어가는 부분이 생기는데, 도형에서는 이것을 관리하기가 어려운 부분이 있다. 
  • 즉 일정한 간격으로 안쪽으로 들어가게 그리고 싶을 땐 어떻게 하면 좋을까? 
Circle().stroke(.blue, lineWidth: 40) Circle().strokeBorder(.blue, lineWidth: 40)
  • strokeBorder() 를 이용
  • 그러나 이는 우리가 커스텀하게 만들어 채택한 Shape 프로토콜엔 사용할 수가 없다. 

커스텀 도형에서도 strokeBorder 같은 효과 주기

  • InsettableShape 프로토콜을 채택
  • 이 프로토콜의 요구사항: inset(by amount) 함수 생성
  • amount 만큼 들여쓴 도형을 생성하겠다는 표시
struct Arc: InsettableShape {
    let startAngle: Angle
    var endAngle: Angle
    let clockwise: Bool = true
    var insetAmount: Double

    func path(in rect: CGRect) -> Path {
        let rotationAdjustment = Angle.degrees(90)
        let modifiedStart = startAngle - rotationAdjustment
        let modifiedEnd = endAngle - rotationAdjustment

        var path = Path()
        path.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rect.width / 2 - insetAmount, startAngle: modifiedStart, endAngle: modifiedEnd, clockwise: !clockwise)

        return path
    }

    func inset(by amount: CGFloat) -> some InsettableShape {
        var arc = self
        arc.insetAmount += amount
        return arc
    }
}

struct ContentView: View {
    var body: some View {
        Arc(startAngle: .degrees(0), endAngle: .degrees(345),  insetAmount: 20.0)
            .stroke(.red, style: StrokeStyle(lineWidth: 40, lineCap: .round, lineJoin: .round))
    }
}

Comments