[SwiftUI] SwiftUI Tutorial 따라해보기 - 2. Building Lists and Navigation

Madeline👩🏻‍💻·2023년 3월 26일
0

iOS study

목록 보기
3/61

눈물나는 복전생의 iOS 공부 일지 👩🏻‍💻

개발자 공식 사이트의 튜토리얼부터 차근차근 따라하고 정리해보자.

이 포스트는 아래 블로그 글에서 이어지는 2번째 글입니다!

🙈

[https://velog.io/@maddie/SwiftUI-SwiftUI-Tutorial-따라해보기]

🐸 SwiftUI Essentials 🐸

앞서 만든 베이직한 랜드마크 앱을 활용한다!!!

  • 랜드마크의 전체 목록을 보고 각 위치에 대한 세부 정보를 볼 수 있게 만들어보자.
  • 랜드마크에 대한 정보를 표시할 수 있는 보기를 만들고, 사용자가 랜드마크에 대한 세부 보기를 보기 위해 누를 수 있는 스크롤 목록을 동적으로 생성해보자.
  • UI를 미세 조정하려면 Xcode의 캔버스를 사용하여 다양한 장치 크기로 여러 미리 보기를 렌더링~

2. Building Lists and Navigation

1) 랜드마크 모델 생성

앞서 만든 앱에서는 내가 정보를 뷰에 다 때려박는 식으로 하드코딩을 했다.

여기서는 모델을 생성해서 데이터를 저장할거고, 그 데이터가 뷰로 전달될거다.

튜토리얼에서 미리 만들어놓은 데이터 파일을 다운받아서 프로젝트 파일에 붙이고,
Copy items if needed 선택.

Landmark.swift 파일을 생성한다.

내용은 다음과 같이 landmarkData.json 데이터 파일에 있는 키를 담고 있는 structure을 만든다.

  • (코드화 가능한) Codable conformance를 추가하면 구조와 데이터 파일 간에 데이터를 더 쉽게 이동할 수 있습니다. 이 섹션의 뒷부분에 있는 Codable 프로토콜의 Decodable 구성 요소를 사용하여 파일에서 데이터를 읽습니다.

  • 다음은 각 랜드마크에 해당하는 이미지를 모델화할거다.

다운받은 이미지들을 Asset에 붙여넣는다.

  • Landmark.swift 파일에 swiftUI를 import하고, 랜드마크의 위치 정보를 관리해보자.

좌표 속성을 추가할거다.
JSON 데이터 구조로 저장소에 반영되는 nested Coordinates 타입을 사용해서!!!
=> private 으로! 왜냐면 다음 단계에서 public 계산 프로퍼티를 만드려고 사용할거기 때문이다.

  • 이미지이름 변수도 생성

import CoreLocation

=> MapKit와 인터랙팅하는데에 유용한 좌쵸 속성을 계산한다

ModelData.swift 새 파일 생성

-load() method를 생성한다. 얘는 JSON 데이터를 앱의 메인 번들로부터 생긴 이름이랑 fetch(갖고 온다)!

  • 이 메소드는 Codable 프로토콜의 한 구성 요소인 Decodable 프로토콜에 대한 return type의 conformance 준수에 의존합니다.

다운 받은 데이터 파일인 landmarkData.json을 initialize하는 랜드마크 배열을 만든다

파일들 연관있는거끼리 묶는 정리를 함 한다.

2. Row View 생성

  • 각 랜드마크에 대한 세부 정보를 표시하는 row view 를 생성할거다.
  • Row view는 랜드마크에 대한 정보를 property에 저장하므로, 한 View에서 모든 랜드마크를 표시할 수 있다.
  • 나중에 여러 row를 랜드마크 list로 컴바인!

🍏

새 파일 "LandmarkRow.swift" SwiftUI View를 View group에 생성한다.

var landmark: Landmark 선언
=> Landmark 속성에 저장된 데이터 저장하는 변수

  • preview 멈춘다

preview에도 똑같이 landmark 값을 넣어주면 해결된다.

이제 body에 랜드마크 데이터 중 이름을 넣는다.

이렇게 Landmark 안에 있는 키들을 볼 수 있음

하여튼 텍스트뷰에 Landmark data 넣어놓고, HStack으로 임베드

이름 위에 이미지뷰 넣어보자.

왜 이미지로 안묶어도 되는거징?? 모르겠다

3. Row Preview 커스터마이즈

https://docs-assets.developer.apple.com/published/324ff817cd158a8d223f4e8c22c9ae84/02030H@2x.png![](https://velog.velcdn.com/images/maddie/post/c127dfb5-019c-4abd-b657-bafa83f74757/image.png)

이런거 만들거다

프리뷰에 있는 랜드마크 인덱스를 바꾸면 다른 사진으로 반환되는 것을 한번 확인해주고,

프리뷰 레이아웃 값도 설정해주자.

이런식으로 두 개의 프리뷰가 보인다.

두 개의 프리뷰를 그룹으로 묶어주고,
코드를 단순하게 바꿔보자

4. 랜드마크 리스트 생성

  • 뷰 그룹에 LandmarkList.swift 생성
  • List 생성하는데, 이 리스트는 LandmarkRow 인스턴스를 자식으로 갖는다.

5. 리스트를 동적으로 만들기

리스트의 원소들을 각각 접근하기 보다는, 컬렉션으로부터 rows를 직접 만들 수 있다.

데이터 컬렉션과 closure(컬렉션의 각 요소에 대한 뷰를 제공)을 전달하여 컬렉션의 원소를 표시하는 리스트를 만들 수 있습니다.
리스트는 supplied closure를 사용하여 컬렉션의 각 원소를 하위 뷰로 변환합니다.

뭔말인지 모르겠으니까 일단 해보자

🦁

LandmarkList 에 있는 두 개의 정적인 static landmark rows를 지우고,
리스트의 initializera에 모델 데이터 landmarks를 전달해준다.

그니까 데이터 하나씩 때려 박는게 아니라, 데이터 파일에서 동적으로 하나씩 전달하는 거다!

Landmark.swift 로 이동해서 Identifiable protocol을 추가한다.

LandmarkList.swift로 다시 이동해서 id 파라미터를 지운다.

무슨 말이냐면, Landmark 데이터에 이미 id 속성이 있기 때문에, 데이터 읽을 때만 속성을 추가하면 된다.

6. 내비게이션 설정 (리스트, 디테일 뷰)

리스트가 올바르게 렌더링되지만, 각각의 랜드마크를 눌러서 해당 랜드마크의 세부정보 디테일 페이지를 볼 수 는 없다.
리스트를 NavigationView에 임베드 한 다음, NavigationLink에 각 row를 중첩해서(nesting) 목적지 뷰로 전환할 수 있다.

🐢

뷰 파일 LandmarkDetail.swift를 생성한다.

ContentView에 body 프로퍼티에 있는 내용을 복붙한다!!

그리고 ContentView는 LandmarkList로 바꾼다.

LandmarkList.swift 에 있는 동적 리스트를 NavigationView 안으로 임베드 한다.

Navigation bar의 타이틀도 만들어준다!
.navigationTitle("Landmarks")

리스트 안에 LandmarkRow를 리턴하는 NavigationLink을 연결해준다.
destination은 LandmarkDetail.

7. 자식 View 로 데이터 전달

Landmark Detail 뷰는 여전히 하드 코딩된 세부 정보를 사용하여 랜드마크를 표시합니다.
LandmarkRow와 마찬가지로 LandmarkDetailtype 및 이를 구성하는 뷰는 랜드마크 특성을 데이터 소스로 사용해야 합니다.
하위 뷰부터 시작하여 CircleImage, MapView 및 LandmarkDetail을 변환하여 각 행을 하드 코딩하는 대신 전달된 데이터를 표시합니다.

  • CircleImage.swift에서 이미지 속성을 추가하고, 프리뷰에도 추가!

프리뷰 로직을 수정했지만, 미리보기가 업데이트되지 않고 에러가 날거다.
원 이미지를 인스턴스화하는 상세 뷰에도 입력 매개 변수가 필요합니다.

MapView.Swift에서 좌표 속성을 추가한다. + Preview도 업데이트

지역을 설정하는 함수 메소드를 만들거다.

맵에 onAppear 뷰 모디파이어(수정)을 추가한다. => @State
이거는 현재 좌표에 기반해서 지역을 계산해준다.

LandmarkDetail.swift 에 Landmark 프로퍼티를 추가한다.

LandmarkList.swift 에서 현재 랜드마크를 LandmarkDetail 의 목적지로 전달해준다

LandmarkDetail 파일에서 요청된 데이터를 타입에 맞게 전달한다.

=> 같은 파일에서 VStack을 ScrollView 로 바꾼다. Spacer도 이제 필요없어서 지운다.

악 왜자꾸 에러가 뜨나 했더니 Landmark 데이터 파일에 저 속성을 추가 안함
다시 해주고,

다시 돌려보면 제대로 들어가있음

마지막으로, LandmarkDetail에서 내비게이션 타이틀 수정한다.

8. Preview 도 동적으로 수정하자

지금까지는 프리뷰에 [0] 인덱스 0 번째 데이터만 보이게 했는데, 얘도 동적으로 만들어보자.

우선 프리뷰 사이즈부터 바꿔보자. 아이폰 SE

.previewDevice(PreviewDevice(rawValue: "iPhone SE (2nd generation)"))
    }

그리고 ForEach 인스턴스를 LandmarkList 안에 넣는다.

여기서 .self 는 키 와 같은 역할을 한다.

짠 프리뷰가 두 개가 생김 아이폰 두 개

** 더 공부해야 할 것들

  • 인스턴스, 프로퍼티 차이? 개념 공부
  • .self 의미
profile
🍎 Apple Developer Academy@POSTECH 2기, 🍀 SeSAC iOS 4기

0개의 댓글