[SwiftUI] List와 Detail 화면 연결하기
Building Lists and Navigation
List에서 항목을 눌러도 아무 반응이 없다. 우리가 만들었던 ContentView(DetailView)로 넘어갈 수 있도록 Navigation을 연결해본다.
Set Up Navigation Between List and Detail
LandmarkDetail.swift 파일 생성
DetailView 화면을 구성하기 위해 LandmarkDetail 파일을 만든다. (SwiftUI View)
새로 만든 파일에 ContentView에 구성해두었던 Detail 화면을 복사해온다.
ContentView 파일 수정
ContentView의 DetailView 내용을 모두 Detail 파일로 옮겼으므로 ContentView 내부에는 첫화면인 List를 보여줄 수 있도록 List를 불러오는 코드를 추가한다.
NavigationView 추가하기
List의 Row를 눌렀을 때 DetailView로 넘어가기 위해 LandmarkList 파일에 NavigationView를 추가한다. List를 감싸도록 넣는다.
var body: some View {
NavigationView {
List(landmarks) { landmark in
LandmarkRow(landmark: landmark)
}
}
}
Navigation Title도 지정해준다.
NavigationLink 추가
리스트에서 Row를 뿌려주는 클로저 내부에 NavigationLink를 추가한다. Row를 클릭하면 DetailView(Destination)로 넘어가야 하기 때문에 각 Row마다 달아주도록 클로저 내부에 추가한다.
라이브 프리뷰로 확인해보기
아래 gif처럼 라이브 프리뷰를 실행해 동작을 확인할 수 있다.
Pass Data into Child Views
지금은 라이브 프리뷰로 돌려서 어떤 Row를 누르더라도 TurtleRock의 데이터가 있는 DetailView만 나온다. 이 부분을 Row를 눌렀을 때 Row의 데이터를 함께 보내 DetailView의 내용도 Row에 맞는 것이 나올 수 있도록 수정해보자.
CircleImage 파일 수정
- CircleImage에 image 프로퍼티를 추가한다. (기존에 tutleRock으로 Image를 만들던 부분도 프로퍼티 image를 사용하도록 수정한다.)
- Preview는 초기화 시 고정 값이 필요하므로 turtleRock으로 초기화해준다.
MapView 파일 수정
- MapView에서도 지역 값을 외부에서 받을 수 있도록 내부에 coordinate 프로퍼티를 설정한다
- Preview도 적절한 값으로 초기값을 넣어준다
onAppear
이라는 조건을 넣어 화면이 나타날 때 setRegion을 통해 region을 초기화하도록 수정했다.
LandmarkDetail 파일 수정
MapView 까지 파일을 수정하고 나면 아래와 같이 에러가 난다.
초기화가 필요하도록 코드를 수정했기 때문이니 LandmarkDetail 파일을 차근차근 수정해보자.
- DetailView에서 사용할 landmark를 받도록 프로퍼티를 추가
- DetailView에서 사용하는 name, coordinate, state, park, description 등등을 init때 받는 landmark의 데이터로 노출할 수 있도록 수정
LandmarkList 파일 수정
DetailView에서 landmark를 받도록 수정했으니 LandmarkList에서 DetailView로 넘어갈 때 landmark를 넘겨주도록 수정한다.
드디어 모든 에러가 잡혔다!! 라이브 프리뷰로 확인해보자!!
DetailView로 들어가면 데이터가 나오는 걸 확인할 수 있다.
근데 description이 끝까지 나오지 않는다..!! 스크롤을 넣어 수정해보자.
LandmarkDetail의 Vtack을 Scroll로 변경하기
전체 데이터를 감싸고 있던 VStack을 ScrollView로 변경한다. ScrollView로 변경되면 아래 Spacer()는 더이상 필요없게 되므로 제거한다.
아래 Description이 잘리지 않고 모두 나온다 😄
DetailView에 navigationBarTitleDisplayMode 추가하기
스크롤뷰의 괄호 마지막에 아래 코드를 추가하고 라이브 프리뷰를 실행해본다.
.navigationTitle(landmark.name)
.navigationBarTitleDisplayMode(.inline)
DetailView의 네비게이션에도 title이 생겼다.
번외
- .navigationBarTitleDisplayMode(.large)
Generate Previews Dynamically
preview를 한 번에 여러 디바이스로 확인할 수 있도록 코드를 바꿀 수 있다.
- 특정 디바이스로 변경
struct LandmarkList_Previews: PreviewProvider { static var previews: some View { LandmarkList() .previewDevice(PreviewDevice(rawValue: "iPhone SE (2nd generation)")) } }
- 여러 디바이스를 한번에 확인
struct LandmarkList_Previews: PreviewProvider { static var previews: some View { ForEach(["iPhone SE (2nd generation)", "iPhone XS Max"], id: \.self) { deviceName in LandmarkList() .previewDevice(PreviewDevice(rawValue: deviceName)) } } }
마무리
List (스토리보드의 tableView..?)를 만들고 navigating을 통해 detailView로 이동하는 것 까지 해봤다. 생각보다 간단한데 아예 생소한 느낌이라 익숙해지려면 자주 해보는 수 밖에 없는 것 같음…
Leave a comment