[SwiftUI] Path 에 따라 View 움직이기
Preview
들어가기 전에
아래 UI 를 만들 일이 있다
왜인지는.. ^^..
튼 일단 Bezier path 를 이용해서 곡선 먼저 조져야할 것 같다
아래 사이트에서 대충 startPoint
, endPoint
, controlPoint
들을 어떻게 잡아야 저 형태랑 비슷하게 나올지 각을 보자
흠.. ㅇㅋㅇㅋ addCurve(to:, control1, control2)
이용해서 대충 이어 그렸다
var body: some View {
samplePath.stroke(style: StrokeStyle(lineWidth: 3))
}
오키 잘나온다
이제 이 Path 를 따라 다른 View
(여기서는 🌕) 를 얹어서 이동시키고 싶단 말이지,,?
흠냐 어케 할까?
Path 를 따라 다른 View
얹기
아래처럼 position
과 trimmedPath
, currentPoint
를 이용해봤따
이게 뭔지는 하나씩 살펴보자
position(x:y:)
position(x:y:)
modifier 를 통해 부모 뷰의 특정 좌표에 뷰의 center 를 배치할 수 있다
Positions the center of this view at the specified coordinates in its parent’s coordinate space.
코드와 결과를 보면 대충 감이 올지두?
Text("Hello, world!")
.background(.red)
.position(x: 100, y: 100)
.background(.blue)
참고로 view 를 positioning 하는 방법으로 offset()
modifier 도 있다. 얘는 underlying geometry 를 실제로 변경하지 않고, 뷰가 렌더링되어야 하는 위치를 변경한다.
Text("Hello, world!")
.background(.red)
.offset(x: 100, y: 100)
.background(.blue)
position
과 offset
에 대한 더 자세한 내용은 [SwiftUI] offset 과 position 의 layout 단계를 참고하자.
ㅇㅋ 그럼 요 안에 들어갈 x, y 좌표는 어떻게 구하냐?
이때 Path
의 trimmedPath
와 currentPoint
이용할거다
trimmedPath(from:, to:)
from
과 to
사이값에 해당하는 Path 의 일부분을 얻을 수 있다 (from
과 to
에는 0 ~ 1 사이의 값이 들어감)
아까 만든 samplePath
에서 0 ~ 0.7 까지 잘라보면 아래처럼 나온다.
samplePath
.trimmedPath(from: 0, to: 0.7)
.stroke(style: StrokeStyle(lineWidth: 3))
currentPoint
Path 의 last point 에 접근할 수 있다 (만약 path 가 points 를 포함하고 있지 않다면 nil 반환).
그래서 아래 코드는 samplePath
의 0.5 위치에 해당하는 값을 나타낸다.
samplePath
.trimmedPath(from: 0, to: 0.5)
.currentPoint
이제 앞서 설명한 position
, trimmedPath
, currentPoint
를 다 합친 코드를 다시 보면?
현재의 내가 이해했으니까 미래의 나도 여기까지 보면 이해하겠지 머 ㅋㅎ 안되면 다시 정독해라 미래의 나야
Slider 로 값을 바꿔보면서도 위치를 확인해보자
잘 된다
위에서 간단한 설명을 위해 냅다 Path
를 만들어서 사용했다. 근데 Path
는 절대 경로 안에서 좌표값에 맞춰 도형을 그린다는 사실이 맘에 안든다. 나는 상대 경로 받아서 그리고 싶은걸?
이를 위해 Shape
를 사용해야할 것 같다. Shape
는 path(in:)
에서 주어진 Rect
를 기반으로 상대 경로를 받아서 도형을 그린다 (해당 메서드 호출이 끝나야 최종적인 사이즈를 알 수 있음).
따라서 Shape
를 이용하는 방식으로 한단계만 더 나아가 잘 조지면 아래와 같이 사용할 수 있다
최종 코드
굿