ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • NavigationView, NavigationLink
    스유를 써봐유! 2021. 9. 26. 02:38
    728x90
    반응형

     

     

     

     

     

     

    안녕하세요. iOS 개발자 에이든입니다!👦🏻

     

     

     

    이번 스유를 써봐유 시간은~

    iOS App을 보면 TabBar와 함께 자주 쓰이는 NavigaionView!

    그리고 NavigationView의 이동을 위해 사용되는 NavigationLink에 대해 알아보겠습니다.

     

     

     

    NavigationView의 Bar에 대한 설명은 워낙 커스텀 방법이 많고 다양해서 따로 다뤄보도록 할게요!

    그럼 일단 이 둘을 먼저 파헤쳐봅시다!

     


     

    먼저 NavigationView의 정의를 살펴볼게요~

    Apple Deverloper 사이트에서는

    탐색 계층 구조에서 보이는 경로를 나타내는 View의 Stack을 표시하기 위한 View

    라고 정의를 내리고 있습니다.

     

    쉬운 예시로 기본 App인 Setting을 보시게 되면 

    어떤 요소를 터치하면 옆으로 쓱~ 다른 View가 나오면서 다른 정보들을 보여주죠?

     

    이것이 바로 NavigationView이고,

    최상단에 Setting이라고 적혀있는 Bar가 NavigationBar입니다

    그리고 View의 이동을 하게 해 주는 것이 바로 NavigationLink죠!

     

    그럼 NavigationView, NavigationLink를 구현하는 방법을 알아봅시다!

     

     


    NavigationView

    예전에 ViewController로 구현할 때에는 UINavagationController를 활용했어요. SwiftUI는 NavigationView를 활용해서 훨씬 간단하게 구현할 수 있습니다!

     

    먼저 간단하게 Model을 만들어 주겠습니다!

    ModelIdentifiable을 채택하도록 구현했는데, 이는 고유한 id를 부여한다고 보시면 됩니다.

    struct Model: Identifiable {
        var id: Int
        var name: String
        var age: Int
        
        init(id: Int, name: String, age: Int) {
            self.id = id
            self.name = name
            self.age = age
        }
    }

     

    자 Model은 만들었고 이를 바탕으로 App에 들어갈 Data를 만들어 줄게요

    let models: [Model] = [ Model(id: 1, name: "토니", age: 25), Model(id: 2, name: "스티븐", age: 27), Model(id: 0, name: "제이미", age: 21)]

     

    이제 이를 바탕으로 NavigationView를 만들어 보겠습니다!

    struct ContentView: View {
        var body: some View {
            NavigationView {
                List(models) { model in
                    Text(model.name)
                }
                .navigationBarTitle("명단")
            }
        }
    }

     

    어떤가요? 엄청 간단하게 구현되었죠?

    주의하실 점!!

    NavigationTitle은 꼭 NavigationView의 안쪽에 넣어줘야 합니당! 

     

     

    그럼 이제 다른 View도 만들어서 서로 이동되게 해볼까요?

     

     


    NavigationLink

    NavigationView 내부의 다른 View로 이동하게 해주는 View입니다.

    바로 예시를 볼까요?

     

    일단 이동할 View를 먼저 만들어 주겠습니다.

    이때 이 View는 NavigationView 안에 있는 것이니 해당 View에서 Title을 바꿔줄 수 있어요.

    struct DetailView: View {
        var model: Model
        
        var body: some View {
            VStack {
                Image(systemName: "person.circle")
                    .resizable()
                    .frame(width: 100, height: 100, alignment: .center)
                Text(model.name)
                    .font(.system(size: 60))
                Text("\(model.age)세")
                    .font(.system(size: 40))
            }
            .navigationTitle("상세내역")
            // NavigationBar에 보이는 Title의 크기를 작게 보이게 설정!
            .navigationBarTitleDisplayMode(.inline)
        }
    }

     

    그리고 앞서 보여드렸던 NavigationView 예제 코드에 NavigationLink를 넣어볼게요!

    destination에는 보여줄 View를 넣고, label에는 터치할 View를 만들어 넣어주면 된답니다.

    struct ContentView: View {    
        var body: some View {
            NavigationView {
                List(models) { model in
                    NavigationLink(destination: DetailView(model: model), label: {
                        Text(model.name)
                    })
                }
                .navigationBarTitle("명단")
            }
        }
    }

     

    ✨짜자잔✨

    어때요 무지 간단하죠?

    이렇게 NavigaionLink를 활용해서 View 간의 이동을 만들 수 있습니다!

     

     

     

    ❗️여기서 주의할 점

    방금 코드는 List 외에 ForEach도 가능한데요

    struct ContentView: View {    
        var body: some View {
            NavigationView {
                VStack {
                    ForEach(models, id: \.id) { model in
                        NavigationLink(destination: DetailView(model: model), isActive: $isActive, label: {
                            Text(model.name)
                        })
                    }
                }
                .navigationBarTitle("NavigationLink")
            }
        }
    }

     

     

    NavigationLink가 하나의 View에 여러개가 있게되죠? 그렇게 되면~

     

     

     

     

    읔!!!!!

     

     

     

    SwiftUI encountered an issue when pushing aNavigationLink. Please file a bug.

     

    라는 디버깅 메시지와 함께 저런 식으로 다른 순번이 튀어나옵니다....

    이러한 에러가 나오는 이유는 잘 모르겠지만 해결방법은 있답니다!

     

    바로 ForEach 마다 NavigationLink를 각각 생성하지 않고

    하나로 그 Index만 받아서 NavigationLink를 하는 방법이죠!

    (꼭 하나의 View에는 하나의 NavigationLink만 넣어주세요!)

    struct ContentView: View {
        
        @State private var isActive: Bool = false
        @State private var selectedModel: Model = Model(id: 0, name: "", age: 0)
        
        var body: some View {
            NavigationView {
                VStack {
                    NavigationLink(destination: DetailView(model: selectedModel), isActive: $isActive, label: { EmptyView() })
                    
                    ForEach(models, id: \.id) { model in
                        Spacer().frame(height: 13)
                        Text(model.name)
                            .onTapGesture {
                                selectedModel = model
                                isActive = true
                            }
                    }
                }
                .navigationBarTitle("NavigationLink")
            }
        }
    }

     

     

     

    그럼 아래와 같이 해결이 된답니다~👏🏻👏🏻👏🏻

     

     

     


     

    이번 시간에는 NavigationView와 NavigationLink에 대해 알아보았습니다.

    이전에 소게 드렸던 TabBar와 NavigationView를 활용하면

    거의 App의 큰 틀은 다 만든 거라고 봐도 무방할 정도입니다ㅎㅎ

     

    추후에는 좀 더 이들을 세밀하게 커스텀하는 방법들도 올려드릴게요!

    혹시라도 부족하거나 잘못된 부분 그리고 질문 있으시면 언제든 댓글 부탁드려요! 감사합니다!👦🏻👋🏻

    728x90
    반응형

    '스유를 써봐유!' 카테고리의 다른 글

    @AppStorage와 UserDefaults  (0) 2021.10.17
    Text Attributed  (1) 2021.09.13
    @State, @Binding, @ObservedObject, @EnvironmentObject  (0) 2021.09.05
    Custom TabBar  (0) 2021.08.15
    Prologue  (1) 2021.08.01

    댓글

Designed by Tistory.