์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |
- concurrency
- IOS
- SwiftUI Tutorials
- Til
- discardableResult
- ๊ธฐ์ด๋ฌธ๋ฒ
- ๋์ ๊ณํ๋ฒ
- ํ๋ก๊ทธ๋๋จธ์ค
- binarySearch
- DynamicProgramming
- SwiftUI ํํ ๋ฆฌ์ผ
- SOPT
- Swift
- ์ด์งํ์
- HAVIT
- duno
- ๊ณ ๋์ kit
- ์ฐ์ํ์ค๋ถ๋ถ์์ด์ํฉ
- GCD
- SQL
- dfs
- BFS
- GroupBy
- SwiftUI
- ๋ค์ด๋๋ฏนํ๋ก๊ทธ๋๋ฐ
- APPJAM
- algorithm
- 0์ด๋์ด์๋๊ธธ
- URLSession
- algoritm
- Today
- Total
suvera-dev ๐ฅฆ
SwiftUI) SwiftUI Essentials - 2 Building Lists and Navigation ๋ณธ๋ฌธ
SwiftUI ํํ ๋ฆฌ์ผ Swift UI Essentials ์ฑํฐ์ 2๋ฒ์งธ ๋ด์ฉ์ ๋๋ค.
Building Lists and Navigation
- ๊ธฐ๋ณธ ๋๋๋งํฌ ์์ธ ๋ทฐ๋ฅผ ๋ง๋ค์์ผ๋ ์ ์ฒด ๋ชฉ๋ก๊ณผ ๊ทธ ๊ฐ๊ฐ์ ํญ๋ชฉ์ ๋ํ ์์ธ ์์น๋ฅผ ๋ํ๋ผ ์ ์๋๋ก ๋ง๋ค์ด์ค๊ฒ์ !
- ๋ชจ๋ ๋๋ ๋งํฌ์ ๋ํ ์ ๋ณด๋ฅผ ํ์ํ ์ ์๋ ๋ทฐ๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉ์๊ฐ ํญ ํ์ฌ ๋๋ ๋งํฌ์ ๋ํ ์ธ๋ถ ์ฌํญ ๋ทฐ๋ฅผ ๋ณผ ์ ์๋ ์คํฌ๋กค ๋ชฉ๋ก์ ๋์ ์ผ๋ก ์์ฑํฉ๋๋ค !
- UIKit์์ TableView๋ CollectionView๋ฅผ ๋ง๋๋ ๊ณผ์ ์ด๋ ์ ์ฌํ ๊ฒ ๊ฐ์์ !
1. ๋๋๋งํฌ ๋ชจ๋ธ ๋ง๋ค๊ธฐ !
- ์ด์ ํํ ๋ฆฌ์ผ์์๋ ๋ชจ๋ ์ปค์คํ ๋ทฐ์ ์ ๋ณด๋ฅผ ํ๋ ์ฝ๋ฉํด๋ณด์์ต๋๋ค.
- ์ด๋ฒ ํํ ๋ฆฌ์ผ์์๋ ๋ฐ์ดํฐ๋ฅผ ์ปค์คํ
๋ทฐ๋ก ์ ๋ฌํ์ฌ ํ์ํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ธ ๊ฒ์
๋๋ค.
- ์์ ์ฒจ๋ถ๋์ด์๋ ์คํํฐ ํ๋ก์ ํธ๋ฅผ ๋ค์ด๋ก๋ ๋ฐ์ผ์๊ณ ์ํ ๋ฐ์ดํฐ๋ฅผ ํ๋ฒ ๋๋ฌ๋ณด์ธ์.
์ฐ์ ๋ชจ๋ธ์ ๋ง๋ค์ด ๋ณผ๊ฒ์ !
1. ์์ JSON ํ์ผ์ ๋ค์ด๋ฐ์์ ๋ฃ์ด์ค๋๋ค.
2. Landmarks.Swift ํ์ผ์ ๋ง๋ค์ด์ JSON์ ํค ์ด๋ฆ๊ณผ ์ผ์นํ๋ ๋ช ๊ฐ์ ํ๋กํผํฐ๋ฅผ ์ ์ํด์ฃผ์ธ์ !
{
"name": "Turtle Rock",
"category": "Featured",
"city": "Twentynine Palms",
"state": "California",
"id": 1001,
"park": "Joshua Tree National Park",
"coordinates": {
"longitude": -116.166868,
"latitude": 34.011286
},
"imageName": "turtlerock"
}
์๊ฒ json ๋ฐ์ดํฐ ์ด๊ตฌ์.
struct Landmark: Hashable, Codable {
var id: Int
var name: String
var park: String
var state: String
var description: String
}
๋๋๋งํฌ ๋ชจ๋ธ์ id, name, park, state, description์ผ๋ก ๊ตฌ์ฑํ์ต๋๋ค.
ํ์ผ์์ Data๋ฅผ ์ฝ๊ธฐ์ํด์ Decodable ํ๋กํ ์ฝ์ ๊ตฌ์ฑ์์๋ฅผ ์ฌ์ฉํด์ผํ๊ธฐ ๋๋ฌธ์,
Codable ํ๋กํ ์ฝ์ conform ํด์คฌ์ต๋๋ค.
- ๊ทธ๋ฆฌ๊ณ ์์ Resource ํ์ผ์์ ๋๋๋งํฌ ์ด๋ฏธ์ง๋ค์ ์ ๋ถ ๋ฃ์ด์คฌ์ต๋๋ค.
- ๊ทธ๋ค์์ Landmark ๋ชจ๋ธ์ ์ด๋ฏธ์ง ๋ก๋ํ๋ ์ฐ์ฐ ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
- ์ฌ์ฉ์๋ ์ค์ง ์ด๋ฏธ์ง์๋ง ๊ด์ฌ์ด ์์ผ๋ฏ๋ก, imageName์ private๋ก ์ค์ ํด์ค๋๋ค. ( ์ด๋ฐ ๊ฒ๊น์ง ์ค๋ช ํด์ฃผ๋ค์ '.')
- ๊ทธ ๋ค์์ ์์น ์ ๋ณด ์ถ๊ฐ ! ๋ด๋ถ์ Coordinates๋ผ๋ struct๋ฅผ ํ๋ ๋ ๋ง๋ค์ด์ฃผ๊ณ latitude, longtitude ํ๋กํผํฐ๋ฅผ ์ ์ํฉ๋๋ค.
- ์ด๋ JSON ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ์ผ์นํ๋๋ก ์ค์ฒฉ๋ Coordinates ํ์ ์ ์ฌ์ฉํด์คฌ์ต๋๋ค.
- ๊ทธ ๋ค์์๋ Mapkit ํ๋ ์์ํฌ์ ์ํธ์์ฉํ๋๋ฐ ์ ์ฉํ locationCoordinate ๋ผ๋ ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํด์ค๋๋ค. ( import CoreLocation ์ ํด์ค์ผํฉ๋๋ค. )
var locationCoordinate: CLLocationCoordinate2D {
CLLocationCoordinate2D(
latitude: coordinates.latitude,
longitude: coordinates.longitude)
}
- Mapkit ์์ ์์น์ ๋ณด๋ฅผ ์ฃผ๊ณ ๋ฐ๋๋ฐ ์ฌ์ฉํ๋ struct์ธ ๊ฒ ๊ฐ์ต๋๋น !
[ ModelData.Swift ํ์ผ ๋ง๋ค๊ธฐ ]
- ๋ค์์ผ๋ก, ModelData.Swift ํ์ผ์ ๋ง๋ค์ด์ฃผ๊ณ , load(_: ) ๋ฉ์๋๋ฅผ ์์ฑํด์คฌ์ต๋๋ค.
- ์ด ๋ฉ์๋๋ main ๋ฒ๋ค์์ JSON ํ์ผ์ ๊ฐ์ ธ์ต๋๋ค !
- load ๋ฉ์๋๋ ๋ฐํ ํ์ ์ด Decodable ํ๋กํ ์ฝ์ conformํ๋ ๊ฒ์ ์์กดํ๋ค๊ณ ํฉ๋๋ค.
- ์๋ ์ฝ๋๋ฅผ ๋ณด๋ฉด, Array ํ์ ์ผ๋ก ๋๋๋งํฌ ๋ชฉ๋ก์ ๊ฐ์ ธ์ค๊ณ ์์ต๋๋ค.
var landmarks: [Landmark] = load("landmarkData.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
- ๋ง์ง๋ง์ผ๋ก ํด๋๋ง๊น์ง ์๋ฃ ~
2. ํ์ ๋ํ๋ด๋ ๋ทฐ ์์ฑ
- ์ฒซ ๋ฒ์งธ ๋ทฐ๋ ๊ฐ๊ฐ์ ๋๋๋งํฌ์ ๋ํ ์์ธ์ ๋ณด๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํ ํ(row)์ ๋๋ค.
- ์ด ํ์ ๋ํ๋ด๋ ๋ทฐ๋ ๋๋๋งํฌ์ ํ๋กํผํฐ ์ ๋ณด๋ฅผ ์ ์ฅํฉ๋๋ค.
- ๋์ค์ ์ฌ๋ฌ ํ์ ๊ฒฐํฉํ์ฌ ๋๋๋งํฌ ๋ชฉ๋ก์ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
1) LandmarkRow๋ผ๋ ์ด๋ฆ์ผ๋ก SwiftUI ๋ทฐ ํ์ผ์ ๋ง๋ค์ด์ค๋๋ค.
2) landmark๋ผ๋ ์ ์ฅ ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
-> LandmarkRow๋ฅผ ์ด๊ธฐํ ์ค์ landmark๊ฐ ํ์ํ๋ฏ๋ก landmark ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํ ๋ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๊ฐ ๋ฉ์ถฅ๋๋ค.
- preview๋ฅผ ์์ ํ๊ธฐ ์ํด preview provider๋ฅผ ์์ ํด์ผ ํฉ๋๋ค.
- LandmarkRow_Previews์ static ํ๋กํผํฐ์์ landmarkData ๋ฐฐ์ด์ ์ฒซ ๋ฒ์งธ ์์๋ฅผ ์ง์ ํ์ฌ Landmark ๋งค๊ฐ ๋ณ์๋ฅผ LandmarkRow ์ด๊ธฐํ ํ๋ก๊ทธ๋จ์ ์ถ๊ฐํ์ญ์์ค.
struct LandmarkRow_Previews: PreviewProvider {
static var previews: some View {
LandmarkRow(landmark: landmarks[0])
}
}
- ๋ค์์ผ๋ก๋ ๋ฐ๋์ HStack Embed ํด์ฃผ๊ณ , ํ ์คํธ๋ landmark.name, ์์๋ ์ด๋ฏธ์ง๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
- ์ฌ์ด์ฆ๋ 50 * 50 ์ผ๋ก ํด์ค๋๋ค.
var body: some View {
HStack {
landmark.image
.resizable()
.frame(width: 50, height: 50)
Text(landmark.name)
Spacer()
}
}
3. ํ ํ๋ฆฌ๋ทฐ ์ปค์คํฐ๋ง์ด์งํ๊ธฐ
- Xcode์ ์บ๋ฒ์ค๋ ํ์ฌ ํธ์ง๊ธฐ์์ PreviewProvideํ๋กํ ์ฝ์ ์ฑํํ๋ ํ์ ์ ๋ํด์ ์๋์ผ๋ก ์ธ์ํ๊ณ ํ์ํฉ๋๋ค.
- ๋ฏธ๋ฆฌ ๋ณด๊ธฐ ์ ๊ณต์(preview provide)๋ ํฌ๊ธฐ์ ์ฅ์น๋ฅผ ๊ตฌ์ฑํ๋ ์ต์
๊ณผ ํจ๊ป ํ๋ ์ด์์ ๋ทฐ๋ฅผ ๋ฐํํฉ๋๋ค.
- ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ ๊ณต์(preview provide)์์ ๋ฐํ๋ ์ฝํ
์ธ ๋ฅผ ์ฌ์ฉ์ ์ ์ํ์ฌ ๊ฐ์ฅ ์ ์ฉํ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ๋ ๋๋ง ํ ์ ์์ต๋๋ค.
struct LandmarkRow_Previews: PreviewProvider {
static var previews: some View {
Group {
LandmarkRow(landmark: landmarks[0])
LandmarkRow(landmark: landmarks[1])
}
.previewLayout(.fixed(width: 300, height: 70))
}
}
- previewLayout(_:) ์์ ์(modifier)๋ฅผ ์ฌ์ฉํด์ ๋ชฉ๋ก ์์ ํ์ ๊ทผ์ ํ ํฌ๊ธฐ๋ก ์ค์ ๊ฐ๋ฅ
- ๊ทธ๋ฃน์ ๋ทฐ ์ฝํ ์ธ ๋ฅผ ๊ทธ๋ฃนํํ๊ธฐ ์ํ ์ปจํ ์ด๋์ ๋๋ค.
- Xcode๋ ๊ทธ๋ฃน์ ํ์ ๋ทฐ๋ค์ ์บ๋ฒ์ค์์ ๊ฐ๊ฐ ๋ถ๋ฆฌ๋ ํํ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ก ๋ ๋๋ง ํฉ๋๋ค.
- ์ฝ๋๋ฅผ ์ข ๋ ๊ฐ๋จํ๊ฒ ๋ง๋ค๊ธฐ ์ํด previewLayout(_:)์ ํธ์ถํ๋ ์์น๋ฅผ ๊ทธ๋ฃน ์ธ๋ถ๋ก ์ฎ๊น๋๋ค.
- ๊ทธ๋ฌ๋ฉด ์ด๋ฐ์์ผ๋ก ํ๋ฆฌ๋ทฐ ์ปค์คํฐ๋ง์ด์ง์ด ๋ฉ๋๋น.
4. ๋๋๋งํฌ ๋ฆฌ์คํธ ๋ง๋ค๊ธฐ.
- SwiftUI์ ๋ฆฌ์คํธ ํ์
์ ์ฌ์ฉํ ๋ ๋ทฐ์ ํ๋ซํผ๋ณ ๋ชฉ๋ก์ ํ์ํ ์์์ต๋๋ค.
- ๋ชฉ๋ก์ ์์๋ ์ง๊ธ๊น์ง ์์ฑ ํ ์คํ์ ์์ ๋ทฐ์ ๊ฐ์ด ์ ์ ์ด๊ฑฐ๋ ๋์ ์ผ๋ก ์์ฑ ๋ ์ ์์ต๋๋ค.
- ์ ์ ๋ทฐ์ ๋์ ์ผ๋ก ์์ฑ ๋ ๋ทฐ๋ฅผ ํผํฉ ํ ์๋ ์์ต๋๋ค.
1) LandmarkList๋ผ๋ ์ด๋ฆ์ผ๋ก SwiftUI ๋ทฐ๋ฅผ ๋ง๋ค์ด์ค๋๋ค.
2) ๊ธฐ๋ณธ ํ
์คํธ๋ฅผ ๋ฆฌ์คํธ๋ก ๋ฐ๊พธ๊ณ LandmarkRow ์ธ์คํด์ค์ ๋ฆฌ์คํธ์ ํญ๋ชฉ์ผ๋ก ์ฒ์ ๋ ๊ฐ์ ๋๋ ๋งํฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
struct LandmarkList: View {
var body: some View {
List {
LandmarkRow(landmark: landmarks[0])
LandmarkRow(landmark: landmarks[1])
}
}
}
5. ๋์ ์ผ๋ก ๋ฆฌ์คํธ ๋ง๋ค๊ธฐ.
- ๋ชฉ๋ก์ ์์๋ฅผ ๊ฐ๋ณ์ ์ผ๋ก ์ง์ ํ๋ ๋์ ์ปฌ๋ ์
์์ ์ง์ ํ์ ์์ฑ ํ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ์ ์ปฌ๋ ์
๊ณผ ์ปฌ๋ ์
์ ๊ฐ ์์์ ๋ํ ๋ทฐ๋ฅผ ์ ๊ณตํ๋ ํด๋ก์ ๋ฅผ ์ ๋ฌํ์ฌ ์ปฌ๋ ์
์ ์์๋ฅผ ํ์ํ๋ ๋ชฉ๋ก์ ๋ง๋ค ์ ์์ต๋๋ค.
- ์ ๊ณต๋ ํด๋ก์ ๋ฅผ ์ฌ์ฉํ์ฌ ๋ชฉ๋ก์ ๊ฐ ์์๋ฅผ ์์๋ทฐ๋ก ๋ณํํฉ๋๋ค.
1) ์์์ ๋ง๋ 2๊ฐ์ ์ ์ ๋๋๋งํฌRow๋ฅผ ์ ๊ฑฐํ๊ณ , ๋์ LandmarkData๋ฅผ List ์ด๊ธฐํ ํ๋ก๊ทธ๋จ์ ์ ๋ฌํ์ธ์.
2) ์๋ณ ๊ฐ๋ฅํ ๋ฐ์ดํฐ์ ๋ํ ์์ ์ ๋์ดํฉ๋๋ค. ๋ ๊ฐ์ง ๋ฐฉ๋ฒ ์ค ํ๋๋ก ๋ฐ์ดํฐ๋ฅผ ์๋ณ ํ ์ ์์ต๋๋ค.
-> ๋ฐ์ดํฐ์ ํจ๊ป ๊ฐ ์์๋ฅผ ๊ณ ์ ํ๊ฒ ์๋ณํ๋ ์์ฑ์ ์ฃผ์ ๊ฒฝ๋ก๋ฅผ ์ ๋ฌํ๊ฑฐ๋ ๋ฐ์ดํฐ ์ ํ์ด Identifiable ํ๋กํ ์ฝ์ ์ค์ํ๊ฒํฉ๋๋ค.
3) ํด๋ก์ ์์ LandmarkRow๋ฅผ ๋ฐํํ์ฌ ๋์ ์ผ๋ก ์์ฑ ๋ ๋ชฉ๋ก์ ์์ฑํ์ญ์์ค.
-> ์ด๊ฒ์ landmarkData ๋ฐฐ์ด์ ๊ฐ ์์์ ๋ํด ํ๋์ LandmarkRow๋ฅผ ์์ฑํฉ๋๋ค.
struct LandmarkList: View {
var body: some View {
List(landmarkData, id: \.id) { landmark in
LandmarkRow(landmark: landmark)
}
}
}
4) Landmark ๋ชจ๋ธ์ Identifiable ํ๋กํ ์ฝ ์ฑํ์ ์ถ๊ฐํ์ธ์. + Landmark ํ์ ์๋ ์ด๋ฏธ Identifiable ํ๋กํ ์ฝ์ ํ์ํ id ์์ฑ์ด ์์ !
5) ์ด์ Landmark List์์ id ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๊ฑฐํด์ฃผ์ธ์.
struct LandmarkList: View {
var body: some View {
List(landmarks) { landmark in
LandmarkRow(landmark: landmark)
}
}
}
- ์๋ ๊ฒ ์์ฑ.
6. ๋ค๋น๊ฒ์ด์ ์ค์ ๋ฐ ์์ธ ํ์ด์ง
- ๋ชฉ๋ก์ด ์ฌ๋ฐ๋ฅด๊ฒ ๋ ๋๋ง๋์ง๋ง ๊ฐ๋ณ ๋๋ ๋งํฌ๋ฅผ ํญํ์ฌ ํด๋น ๋๋ ๋งํฌ์ ์ธ๋ถ ์ฌํญ ํ์ด์ง๋ฅผ ์์ง ๋ณผ ์๋ ์์ต๋๋ค.
- NavigationView์ ํ์ ๊ธฐ๋ฅ์ ํฌํจ์ํจ ๋ค์ NavigationLink์ ๊ฐ ํ์ ์ค์ฒฉํ์ฌ ํ์ ๊ธฐ๋ฅ์ ๋ชฉ๋ก์ ์ถ๊ฐํ์ฌ ๋์ ๋ทฐ๋ก์ ์ ํ์ ์ค์ ํด๋ณด๊ฒ ์ต๋๋ค.
1) ์์ธ๋ณด๊ธฐ ๋ทฐ๋ฅผ ๋ง๋ค๊ฑฐ์์. LandmarkDetail.Swift ํ์ผ์ ๋ง๋ค์ด์ค๋๋ค.
2) ContentView ๋ด์ฉ์ copyํด์ body์ ๋ฃ์ด์ฃผ์ธ์.
3) ๊ทธ๋ฆฌ๊ณ ContentView์ body์๋ LandmarkList()๋ฅผ ๋ฃ์ด์ฃผ์ธ์.
4) LandmarkList์์ ๋์ ์ผ๋ก ์์ฑ๋ ๋ฆฌ์คํธ๋ฅผ NavigationView๋ก ๊ฐ์ธ์ฃผ์ธ์ !
5) Navigation ํ์ดํ๋ ์ค์ ํด์ค๋๋ค
6) ๋ฆฌ์คํธ ํด๋ก์ ์์์ LandmarkDetail ๋ทฐ๋ฅผ ๋ชฉ์ ์ง๋ก ํ์ฌ ๋ฐํ ๋ ํ์ NavigationLink์ ๋ํํฉ๋๋ค.
struct LandmarkList: View {
var body: some View {
NavigationView {
List(landmarks) { landmark in
NavigationLink {
LandmarkDetail()
} label: {
LandmarkRow(landmark: landmark)
}
}
}
.navigationTitle("Landmarks")
}
}
+ ํ๋ฆฌ๋ทฐ๋ฅผ ๋ผ์ด๋ธ ๋ชจ๋๋ก ์ ํํ๋ฉด ๋ค๋น๊ฒ์ด์ ์ ํด๋ฆญํด์ ํ์ํ ์ ์๋ค๊ณ ํฉ๋๋ค. -> ๋ฐ๋ก ๋ํ ์ผ ํ์ด์ง๋ก ์ฐ๊ฒฐ์ด ๋ฉ๋๋ค.
์ฌ๊ธฐ๊น์ง ์์ฑ ~
7. ์์ ๋ทฐ์๊ฒ ๋ฐ์ดํฐ ์ ๋ฌํ๊ธฐ
- LandmarkDetail๋ทฐ๋ ์ฌ์ ํ ํ๋ ์ฝ๋ฉ๋ ์ธ๋ถ ์ ๋ณด๋ฅผ ์ฌ์ฉํ์ฌ ๋๋๋งํฌ๋ฅผ ํ์ํฉ๋๋ค.
- LandmarkRow์ ๋ง์ฐฌ๊ฐ์ง๋ก LandmarkDetail ํ์
์ผ๋ก ๊ตฌ์ฑ๋ ๋ทฐ๋ ๋ฐ์ดํฐ ์์ค๋ก landmark ํ๋กํผํฐ๊ฐ ํ์ํฉ๋๋ค.
- ์์๋ทฐ๋ถํฐ ์์ํ์ฌ CircleImage, MapView, LandmarkDetail์ ๋ณํํ์ฌ ๊ฐ ํ์ ํ๋ ์ฝ๋ฉํ๋ ๋์ ์ ๋ฌ๋ ๋ฐ์ดํฐ๋ฅผ ํ์ํฉ๋๋ค.
1) ์์์ ๋ง๋ค์๋ CircleImage.swift์์ ์ ์ฅ ์ด๋ฏธ์ง(image) ํ๋กํผํฐ๋ฅผ CircleImage์ ์ถ๊ฐํฉ๋๋ค.
2) Turtle Rock์ ์ด๋ฏธ์ง๋ฅผ ์ ๋ฌํ๋๋ก Prview provider๋ฅผ ์ ๋ฐ์ดํธํ์ธ์.
struct CircleImage: View {
var image: Image
var body: some View {
image
.clipShape(Circle())
.overlay {
Circle().stroke(.white, lineWidth: 4)
}
.shadow(radius: 7)
}
}
struct CircleImage_Previews: PreviewProvider {
static var previews: some View {
CircleImage(image: Image("turtlerock"))
}
}
3) MapView.swift์์ ์ขํ ์์ฑ์ MapView์ ์ถ๊ฐํ๊ณ Prview provider์ ๊ณ ์ ์ขํ๋ฅผ ์ ๋ฐ์ดํธ ํ์ธ์.
4) ์ขํ๊ฐ์ ๊ธฐ๋ฐ์ผ๋ก ์ง์ญ์ ์ ๋ฐ์ดํธํ๋ ๋ฉ์๋ ์ถ๊ฐ. - setRegion
5) onAppear๋ผ๋ ํ์ฌ ์ขํ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์น ๊ณ์ฐ์ ํธ๋ฆฌ๊ฑฐ ํ๋ view modifier๋ฅผ ์ถ๊ฐ.
struct MapView: View {
var coordinate: CLLocationCoordinate2D
@State private var region = MKCoordinateRegion()
var body: some View {
Map(coordinateRegion: $region)
.onAppear {
setRegion(coordinate)
}
}
private func setRegion(_ coordinate: CLLocationCoordinate2D) {
region = MKCoordinateRegion(
center: coordinate,
span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
)
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView(coordinate: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868))
}
}
6) LandmarkDetail๋ก ๊ฐ์, Landmark property๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
7) ๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ ์ ๋ฌ์ ์ํด์ LandmarkList ์ ์ฐ๊ฒฐ๋ ๋ถ๋ถ์ ํ์ฌ landmark๋ฅผ ๋ชฉ์ ์ง๋ก ์ค์ ํฉ๋๋ค !
struct LandmarkDetail: View {
var landmark: Landmark
//...
}
struct LandmarkList: View {
var body: some View {
NavigationView {
List(landmarks) { landmark in
NavigationLink {
LandmarkDetail(landmark: landmark)
} label: {
LandmarkRow(landmark: landmark)
}
}
.navigationTitle("Landmarks")
}
}
}
8) ์ด์ LandmarkDetail์์ ํ์ํ ๋ชจ๋ ๊ฐ๋ค์ ์ ๋ฌํด์ค์๋ค !
9) ๊ทธ๋ฆฌ๊ณ ์ฌ์ฉ์๊ฐ ์ค๋ช ์ ์คํฌ๋กค ํ ์ ์๋๋ก VStack์ ScrollView๋ก ๋ฐ๊ฟ์ค๋๋ค. + ํ์์๋ Spacer ์ญ์
10 ) ๋ง์ง๋ง์ผ๋ก, navigationTitle์ ๋๋๋งํฌ ์ด๋ฆ์ผ๋ก ์ค์ ํด์ฃผ๊ณ ,
navigationBarTitleDisplayMode๋ฅผ inline์ผ๋ก ์ค์ ํด์ค๋๋ค.
struct LandmarkDetail: View {
var landmark: Landmark
var body: some View {
ScrollView {
MapView(coordinate: landmark.locationCoordinate)
.ignoresSafeArea(edges: .top)
.frame(height: 300)
CircleImage(image: landmark.image)
.offset(y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
Text(landmark.name)
.font(.title)
HStack {
Text(landmark.park)
.font(.subheadline)
Spacer()
Text(landmark.state)
.font(.subheadline)
}
.font(.subheadline)
.foregroundColor(.secondary)
Divider()
Text("About \(landmark.name)")
.font(.title2)
Text(landmark.description)
}
.padding()
}
.navigationTitle(landmark.name)
.navigationBarTitleDisplayMode(.inline)
}
}
8. Previews ๋์ ์ผ๋ก ์์ฑํ๊ธฐ.
- ๋ค์์ผ๋ก LandmarkList_Previews preview provider์ ์ฝ๋๋ฅผ ์ถ๊ฐํ์ฌ ๋ค์ํ ์ฅ์น ํฌ๊ธฐ์์ ๋ชฉ๋ก๋ณด๊ธฐ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
- ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ active scheme ์์ ์ฅ์น์ ํฌ๊ธฐ๋ก ๋ ๋๋ง๋ฉ๋๋ค.
- previewDevice (_ :) modifier ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ฅ์น๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
1) ํ์ฌ ๋ชฉ๋ก ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ๋ณ๊ฒฝํ์ฌ iPhone SE ํฌ๊ธฐ๋ก ๋ ๋๋งํฉ๋๋ค. Xcode์ scheme ๋ฉ๋ด์ ํ์๋๋ ๋ชจ๋ ์ฅ์น์ ์ด๋ฆ์ ์ ๊ณต ํ ์ ์์ต๋๋ค.
struct LandmarkList_Previews: PreviewProvider {
static var previews: some View {
LandmarkList()
.previewDevice(PreviewDevice(rawValue: "iPhone SE (2nd generation)"))
}
}
2) ForEach๋ก ์ฌ๋ฌ ๊ธฐ๊ธฐ๋ฅผ ํ๊บผ๋ฒ์ ๋ณผ ์ ์์ต๋๋ค.
- ๋ชฉ๋ก ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ด์์ ์ฅ์น ์ด๋ฆ ๋ฐฐ์ด์ ๋ฐ์ดํฐ๋ก ์ฌ์ฉํ์ฌ LandmarkList๋ฅผ ForEach ์ธ์คํด์ค์ ํฌํจ์ํต๋๋ค.
ForEach๋ ๋ฆฌ์คํธ์ ๋์ผํ ๋ฐฉ์์ผ๋ก ์ปฌ๋ ์
์์ ์๋ํ๋ฏ๋ก ์คํ, ๋ชฉ๋ก, ๊ทธ๋ฃน ๋ฑ์ ํ์ ๋ทฐ๋ฅผ ์ฌ์ฉํ ์์๋ ๋ชจ๋ ์์น์์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ ์์๊ฐ ์ฌ๊ธฐ์์ ์ฌ์ฉํ๋ ๋ฌธ์์ด๊ณผ ๊ฐ์ ๊ฐ๋จํ ๊ฐ ์ ํ ์ธ ๊ฒฝ์ฐ \ .self๋ฅผ ์๋ณ์์ ํค ๊ฒฝ๋ก๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
3) previewDisplayName (_ :) ์์ ์๋ฅผ ์ฌ์ฉํ์ฌ ์ฅ์น ์ด๋ฆ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ์ ๋ ์ด๋ธ๋ก ์ถ๊ฐํ์ญ์์ค.
4) ์บ๋ฒ์ค์์ ๋ชจ๋ ์ฅ์น๋ค์ ๋น๊ตํ๊ณ ๋ ๋๋ง์ ํ์ธํ ์ ์์ต๋๋น !
struct LandmarkList_Previews: PreviewProvider {
static var previews: some View {
ForEach(["iPhone SE (3rd generation)", "iPhone 14"], id: \.self) { deviceName in
LandmarkList()
.previewDevice(PreviewDevice(rawValue: deviceName))
.previewDisplayName(deviceName)
}
}
}
์ฌ๊ธฐ๊น์ง ~ ์ด๋ฒ ์๊ฐ์๋ ๋ฆฌ์คํธ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ๋๋ฐ์.
์๊ฐ๋ณด๋ค ์ฌ๋ฐ๋ค์ ์ค์ ใ ใ ใ ใ
'iOS > SwiftUI' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
SwiftUI) Drawing and Animation 1 - Drawing Paths and Shapes (0) | 2023.04.02 |
---|---|
SwiftUI) SwiftUI Essentials 3 - Handling User Input (4) | 2023.03.31 |
SwiftUI) SwiftUI Essentials (8) | 2023.03.29 |