Skip to content

polyline custom

Hyebin (Helia) edited this page Oct 11, 2023 · 1 revision

์ด๋™๊ฒฝ๋กœ custom ํ•˜๊ธฐ

๋ชฉ์ฐจ

1. 'locations' ๋ณ€์ˆ˜ ์ƒ์„ฑ 2. Path๋กœ ์ด๋™๊ฒฝ๋กœ ๊ทธ๋ฆฌ๊ธฐ 3. Gesture ๊ตฌํ˜„ํ•˜๊ธฐ

'locations' ๋ณ€์ˆ˜ ์ƒ์„ฑ

  • CLLocationCoordinate2D ํƒ€์ž…์˜ ์ขŒํ‘œ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    let locations = [
        CLLocationCoordinate2D(latitude: 36.01719, longitude: 129.31855),
        CLLocationCoordinate2D(latitude: 36.01691, longitude: 129.3181),
        CLLocationCoordinate2D(latitude: 36.01663, longitude: 129.31851),
        CLLocationCoordinate2D(latitude: 36.0169, longitude: 129.31887),
        CLLocationCoordinate2D(latitude: 36.01719, longitude: 129.31855),
    ]

Path๋กœ ์ด๋™๊ฒฝ๋กœ ๊ทธ๋ฆฌ๊ธฐ

  • locations ๋ฐฐ์—ด์— ๋‹ด๊ธด ๋ฐ์ดํ„ฐ๋“ค์„ Path๋กœ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
  • ์œ„๋„, ๊ฒฝ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ x,y์ขŒํ‘œ๋ฅผ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.
  • ํ˜„์žฌ๋Š” scale์„ 100000 ์œผ๋กœ ์„ค์ •ํ•˜์˜€๋Š”๋ฐ, ์ด ๊ฐ’์ด ์ปค์งˆ ์ˆ˜๋ก ๊ทธ๋ ค์ง€๋Š” line์ด ์ปค์ง‘๋‹ˆ๋‹ค.
    private var drawLine: some View {
        Path { path in
            for (index, location) in locations.enumerated() {
                let point = CGPoint(
                    x: UIScreen.main.bounds.width / 2 + CGFloat(location.longitude - locations[0].longitude) * 100000,
                    y: UIScreen.main.bounds.width / 2 - CGFloat(location.latitude - locations[0].latitude) * 100000
                )
                if index == 0 {
                    path.move(to: point)
                } else {
                    path.addLine(to: point)
                }
            }
        }
        .stroke(Color.orange, lineWidth: 5)
        .aspectRatio(contentMode: .fit)
    }

Gesture ๊ตฌํ˜„ํ•˜๊ธฐ

  • path์˜ ์œ„์น˜๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ค๊ธฐ ์œ„ํ•œ DragGesture๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • path์˜ ๊ฐ๋„๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ค๊ธฐ ์œ„ํ•œ RotationGesture๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • path์˜ ํฌ๊ธฐ๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ค๊ธฐ ์œ„ํ•œ magnificationGesture๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    @State private var scale: CGFloat = 1
    @State private var lastScale: CGFloat = 0
    @State private var offset: CGSize = .zero
    @State private var lastStoredOffset: CGSize = .zero
    @State private var angle: Angle = .degrees(0)
    @State private var lastAngle: Angle = .degrees(0)

    private var dragGesture: some Gesture {
        return DragGesture()
            .onChanged { value in
                let translation = value.translation
                offset = CGSize(
                    width: translation.width+lastStoredOffset.width,
                    height: translation.height+lastStoredOffset.height
                )
            }
            .onEnded { value in
                lastStoredOffset = offset
            }
    }
    
    private var rotationGesture: some Gesture {
        return RotationGesture()
            .onChanged { value in
                angle = lastAngle+value
            }
         .onEnded { value in
             withAnimation(.spring) {
                 lastAngle = angle
             }
         }
    }
    
    private var magnificationGesture: some Gesture {
        return MagnificationGesture()
            .onChanged { value in
                let updatedScale = value + lastScale
                scale = (updatedScale < 1 ? 1 : updatedScale)
            }
            .onEnded { value in
                withAnimation(.easeInOut(duration: 0.2)) {
                    if scale < 1 {
                        scale = 1
                        lastScale = 0
                    } else {
                        lastScale = scale-1
                    }
                }
            }
    }
  • Path์— gesture๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ํฌ๊ธฐ, ์œ„์น˜, ๊ฐ๋„๊ฐ€ gesture์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • rotationGesture์™€ magnificationGesture๋ฅผ ๋™์‹œ์— ์ธ์‹ํ•  ์ˆ˜ ์žˆ๋„๋ก magnificationGesture๋Š” 'simultaneousGesture'๋กœ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
    drawLine
        .ignoresSafeArea()
        .scaleEffect(scale)
        .offset(offset)
        .rotationEffect(angle)
        .gesture(dragGesture)
        .gesture(rotationGesture)
        .simultaneousGesture(magnificationGesture)

Clone this wiki locally