티스토리 뷰
Path를 사용해서 화면에 그림을 그리는 방법을 알아보자. openGL이나 window GDI를 사용하는 것과 비슷하다. 화면에서 시작점으로 이동하고 선을 그리고 채우는 등의 작업을 할 수 있다. 공식 사이트에 나와있는 육각형 그리기를 따라해보면서 어떻게 동작하는지 알아보자.
HexagonParameters
육각형을 그리기 위해 필요한 각 점들의 위치를 상대적으로 계산할 수 있는 구조체를 정의한다. 꼭지점을 그릴 때 필요한 vertex의 상대적인 위치값이지만 원리는 이 포스팅에서 중요한게 아니기 때문에 설명을 생략한다. points는 순서대로 육각형의 12시 방향 vertex부터 반시계방향으로 정의되어있다.
CGFloat이라는 자료형을 사용한다는 것만 유의하고 넘어가자.
struct HexagonParameter {
struct Segment {
let useWidth: (CGFloat, CGFloat, CGFloat)
let xFactors: (CGFloat, CGFloat, CGFloat)
let useHeight: (CGFloat, CGFloat, CGFloat)
let yFactors: (CGFloat, CGFloat, CGFloat)
}
static let adjustment: CGFloat = 0.05
static let points = [
Segment(
useWidth: (1.00, 1.00, 1.00),
xFactors: (0.60, 0.40, 0.50),
useHeight: (1.00, 1.00, 0.00),
yFactors: (0.05, 0.05, 0.00)
),
Segment(
useWidth: (1.00, 1.00, 0.00),
xFactors: (0.05, 0.00, 0.00),
useHeight: (1.00, 1.00, 1.00),
yFactors: (0.20 + adjustment, 0.30 + adjustment, 0.25 + adjustment)
),
Segment(
useWidth: (1.00, 1.00, 0.00),
xFactors: (0.00, 0.05, 0.00),
useHeight: (1.00, 1.00, 1.00),
yFactors: (0.70 - adjustment, 0.80 - adjustment, 0.75 - adjustment)
),
Segment(
useWidth: (1.00, 1.00, 1.00),
xFactors: (0.40, 0.60, 0.50),
useHeight: (1.00, 1.00, 1.00),
yFactors: (0.95, 0.95, 1.00)
),
Segment(
useWidth: (1.00, 1.00, 1.00),
xFactors: (0.95, 1.00, 1.00),
useHeight: (1.00, 1.00, 1.00),
yFactors: (0.80 - adjustment, 0.70 - adjustment, 0.75 - adjustment)
),
Segment(
useWidth: (1.00, 1.00, 1.00),
xFactors: (1.00, 0.95, 1.00),
useHeight: (1.00, 1.00, 1.00),
yFactors: (0.30 + adjustment, 0.20 + adjustment, 0.25 + adjustment)
)
]
}
Drawing Hexagon
이제 이 값을 가지고 육각형을 그려보자. 먼저 Path를 정의하고 시작점으로 이동한다.
// path.move(to:)
let pathSize: CGSize = CGSize(width: 100, height: 100)
Path {path in
let xScale: CGFloat = 0.85
let width = pathSize.width * xScale
let height = pathSize.height
let xOffset = pathSize.width * (1.0 - xScale) / 2.0
path.move(to: CGPoint(
x: xOffset + width * 0.95,
y: height * (0.2 + HexagonParameter.adjustment))
)
}
문법이 GeometryReader와 비슷한 것을 볼 수 있는데, Path도 closure로 초기화 할 수 있기 때문이다. HexagonParameter에서 12시 방향 점부터 반시계방향으로 육각형을 그리도록 정의했기 때문에 범위에서 좌상단으로 이동한다.
addLine으로 선을 먼저 그려보자. 현재 path가 위치한 지점부터 to 위치로 직선을 그릴 수 있다.
// path.addLine(to:)
HexagonParameter.points.forEach {point in
path.addLine(to: .init(
x: xOffset + width * point.useWidth.0 * point.xFactors.0,
y: height * point.useHeight.0 * point.yFactors.0)
)
}
여기까지 그리고 캔버스를 실행해보면 찌그러진 육각형이 그리진 것을 볼 수 있다. 심지어 육각형이 아니라 칠각형이다. HexagonParameter에서 육각형의 모서리를 곡선으로 그리려고 정의했기 때문에 앞서 이동한 점과 육각형의 시작점이 달라서 칠각형이 그려진것이다.
AddQuadCurve로 곡선을 더 그려보자. addLine과 비슷하게 to 위치로 선을 그리지만 control 좌표를 필요로 한다. 현재 path의 위치, control, to 로 곡선을 그린다.
// path.addQuadCurve(to:, control:)
path.addQuadCurve(
to: .init(
x: xOffset + width * point.useWidth.1 * point.xFactors.1,
y: height * point.useHeight.1 * point.yFactors.1
),
control: .init(
x: xOffset + width * point.useWidth.2 * point.xFactors.2,
y: height * point.useHeight.2 * point.yFactors.2
)
)
path를 마무리하면 검은색의 부드러운 꼭지점을 가진 육각형을 볼 수 있다. path도 다른 view를 다룰 때랑 똑같이 옵션을 추가할 수 있다.
// .fill(LinearGradiant.init(gradiant:, startPoint:, endPoint))
.fill(LinearGradient.init(
gradient: .init(colors: [Color.purple, Color.blue]),
startPoint: .init(x: 0.5, y: 0.1),
endPoint: .init(x: 0.5, y: 0.9)
))
그라데이션으로 내부 색상을 칠해보자. gradient에 CGColor 리스트를 넣고 startPoint, endPoint를 정의하면 그라데이션을 그릴 수 있다. startPoint/endPoint는 UnitPoint를 사용하기 때문에 중앙 상단부터 중앙 하단까지 그라데이션이 이루어지도록 그리려면 startPoint(x: 0.5, y: 0), endPoint(x: 0.5, y: 1.0)으로 정의하면 된다.
그리고 frame으로 적절히 크기와 정렬을 설정하면 완성할 수 있다.
결과
Path를 사용하는 방법에 대해 알아봤는데 Path의 기능만 특수하게 사용하는 어떤 view를 구성하는게 좀 애매해서 Tutorial 리스트에는 못쓸 것 같다. 앞으로 Tutorial 리스트를 채울 여러 view들을 만들 때 Path를 사용해서 좀 더 보기좋게 만들 수 있겠다.
'Programming > SwiftUI' 카테고리의 다른 글
SwiftUI Beginner | Transition and Animation (0) | 2020.11.14 |
---|---|
SwiftUI Beginner | Sticky Header (0) | 2020.10.07 |
SwiftUI Beginner | 기초문법과 Navigation List (0) | 2020.09.15 |
- Total
- Today
- Yesterday
- C/C++
- database
- ios
- SHADER
- machine learing
- Git
- 자료구조
- ue4
- C++
- rxswift
- 운영체제
- 알고리즘
- mongoDB
- C
- DesignPattern
- Java
- JSP
- Spring
- OS
- Cocos2d-x
- 국내여행
- 드라마
- scala
- SOCKET
- game
- winsock
- swift
- SwiftUI
- 데이터베이스
- 수학
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |