41: Moonshot, part 3

그루두·2024년 6월 13일
0

100 days of SwiftUI

목록 보기
49/108

100 days of swiftui: 41

MissionView 설정하기

메인 화면에서 각 미션을 클릭하면 볼 수 있는 MissionView를 만들었다.

struct MissionView: View {
    let mission: Mission
    var body: some View {
        ScrollView {
            VStack {
                Image(mission.image)
                    .resizable()
                    .scaledToFit()
                    .containerRelativeFrame(.horizontal) { width, axis in
                        width * 0.6
                    }
                VStack(alignment: .leading, spacing: 10) {
                    Text(mission.displayName)
                        .font(.largeTitle.bold())
                    Text(mission.description)
                }
                .padding()
            }
        }
        .navigationTitle(mission.displayName)
        .navigationBarTitleDisplayMode(.inline)
        .background(.darkBackground)
    }
}

이 중 짚을 점은, NavigationTitle을 뒤로 가기 버튼과 동일한 선상에 작은 글씨로 넣을 수 있다.

        .navigationBarTitleDisplayMode(.inline)

그리고 미리보기(Preview)할 때 미션을 불러와서 상수에 저장하고 이 불러온 값을 입력했다. 이때 2줄 이상의 코드를 만드므로 return을 필수로 작성해야 한다.

#Preview {
    let missions: [Mission] = Bundle.main.decode("missions.json")
    return MissionView(mission: missions[0])
        .preferredColorScheme(.dark)
}

❗️ 그렇지 않을 경우 Ambiguous use of 'init(_:traits:body)' 에러를 만나게 된다!

깃헙 링크

Mission과 Astronaut을 합친 데이터 만들기

MissionView에서는 해당 프로젝트의 참여자를 보여준다. 그리고 이 참여자의 정보를 클릭하면 참여자의 상세 정보로 넘어간다.

이를 구현하기 위해서는 Mission 모델에 참여자들을 Astronaut을 CrewMember라는 모델로 crew에 저장하면 된다. 그리고 crewMember를 설정하기 위해 MissionView의 initializer를 설정하면 된다.

❗️ 혹시라도 없거나 누락된 정보를 가리키는 일부 JSON을 프로젝트에 포함하면 안되기 때문에 fatalError로 runtime 이전에 종료되도록 설정해야 한다.

struct MissionView: View {
    struct CrewMember {
        let role: String
        let astronaut: Astronaut
    }
    let mission: Mission
    let crew: [CrewMember]
    var body: some View {
    // ...
    }
    
    init(mission: Mission, astronauts: [String: Astronaut]) {
        self.mission = mission
        self.crew = mission.crew.map { member in
            if let astronaut = astronauts[member.name] {
                return CrewMember(role: member.role, astronaut: astronaut)
            } else {
                fatalError("Missing \(member.name)")
            }
        }
    }
}

깃헙 링크

모두 연결하여 만든 결과물

profile
계속 해보자

0개의 댓글

관련 채용 정보