[SwiftUI] NavigationView 중첩으로 인해 발생한 문제

beeeen·2023년 3월 3일
0

iOS

목록 보기
13/15
post-thumbnail

개인 프로젝트를 진행하면서 NavigationView를 사용했다.
열심히 뚝딱뚝딱 만들고 결과를 봤는데,

오잉 ... 뒤로 버튼이랑 추가 버튼.. 얘네 사이 왜 이렇게 안좋아요 ...? 🥲
저렇게 사이 안좋은 네비게이션바는 처음 봐서 어떻게 해결해야 하는지도 당연히 모름 . .

이 문제는 프로젝트 초반에도 마주했던 문제인데, 서사가 아주 길고 복잡하다 !
나중에 또 마주할 수 있는 문제일 것 같아서 차근차근 정리를 해나가야겠다.
(iOS 15.x의 점유율이 낮아지면, 만날 일 없을지도 . . ?)

문제 원인

기존 코드

코드는 살펴봐야 하는 부분만 가져왔다.

1. First Page

import SwiftUI

struct FirstPage: View {
    var body: some View {
        NavigationView { // ❗️
            NavigationLink {
                SecondPage()
            } label: { ... }
        }
    }
}

2. Second Page

import SwiftUI

struct SecondPage: View {
    var body: some View {
        NavigationView { // ❗️
            Vstack() { ... }
            .toolbar { ... }
        }
    }
}

코드를 보면, First Page도 NavigationView가 전체를 감싸고 있고 Second Page도 NavigationView가 전체를 감싸고 있다.
이러한 상황으로 NavigationBar가 중첩되어 나타났던 것 ! !

이렇게 ..

오늘 글에서 다루고자 하는 문제의 원인은 바로 이 것이다 ! !

원인 파악은 끝났으니, 이제

  • 처음에 해결한 방법
  • 왜 이 문제를 또 마주하게 됐는지
  • 최종 해결 방법

에 대해 설명 드리겠섭니다.

23/01/16, 처음에 해결한 방법

결론 먼저 ! 처음엔 NavigationStack을 사용하여 해결했다!

날짜를 쓰니 다시 한 번 느끼는 커밋 관리의 중요성.
커밋 내역에 문제 상황을 써두진 않았지만, 첫번째 해결하고 나서 올린 커밋 내역으로 언제였는지 파악이 가능한 게 매우 좋네요 :D

  • 최소 버전 : iOS 16.x (⭐️ 중요 포인트)

최소 버전 설정 덕분에 처음 문제가 발생했을 때 해결할 수 있었고, 또 최소 버전 덕분에 동일한 문제를 또 마주할 수 있었다.

먼저 나는 최소 버전을 iOS 16.x으로 맞춰놓고 프로젝트를 시작했다.

사실 처음에 버전 설정은 .. 솔직히 아무 생각없이 했다 . .
16.x이 Default이기도 했고 버전 설정에 대한 고민조차도 안했다 ...!
중요한 문제를 놓쳐 보면서 또 하나 배워갑니다 ^^..

그리고 NavigationView를 사용해서 위에 올려둔 코드(First Page & Second Page)처럼 작성했었다.

(처음 작업을 시작할 때는 NavigationStack의 존재를 몰랐다 . . 새로 나온 기술 공부를 놓치지 않고 해야함을 또 깨닫 ㅠ.ㅠ)

그랬더니 마주한 Navigation Bar 중첩 ! 😭 😭 😭 이렇게 열심히 구글링도 했답니다 🥲

구글링 열심히 하다가 아무리 찾아도 나와 같은 문제를 겪는 사람을 찾을 수가 없었다.
그래서 혹시나 공식문서에 관련 내용이 있을까 싶어 들어가 봤더니,

아니 글쎄 NavigationView가 이제 Deprecated 되었네요.

그래서 대체되어 나온 기능을 살펴보니 NavigationStack이 있었고 제대로 살펴볼 생각도 못하고 냅다 교체해봤습니다.

그래서

첫번째 해결 코드

1. First Page

import SwiftUI

struct FirstPage: View {
    var body: some View {
        NavigationStack{ // ❗️
            NavigationLink {
                SecondPage()
            } label: { ... }
        }
    }
}

2. Second Page

import SwiftUI

struct SecondPage: View {
    var body: some View {
        NavigationStack { // ❗️
            Vstack() { ... }
            .toolbar { ... }
        }
    }
}

해결 방법은 단순히 새로 나온 기능으로 교체하기 !

NavigationView -> NavigationStack

여기서도 여전히 First Page, Second Page 모두에 NavigationStack이 적용되어 있죠?
맞아요. 문제의 근본이 해결된 것이 아니었어요.

하지만 당시의 저는 오! 원하던 View가 나왔어 !! 하면서
냅다 커밋하고 문제 해결 탕탕탕을 외쳤습니다.
바보같았죠 ㅋㅎ ㅠㅠ

23/03/02, 최종 해결 방법

그렇게 해결된 문제 중 하나로 잊혀져가고 있던 어느 날 ..

저는 iOS 최소 버전 설정에 대한 고민을 시작했습니다.

23.02.14 기준
72%의 기기가 iOS 16을, 20%의 기기가 iOS 15를 사용하고 있다고 합니다.

✔️ iOS 버전 점유율 확인은 여기서 !

지금 진행 중인 프로젝트가 출시된 어플은 아니지만, 프로젝트를 시작하기에 앞서 iOS 최소 버전에 대한 고민은 필수라고 생각합니다.

이걸 시작 전에 알았더라면 🥲

아무튼 제가 현재 사용 중인 폰은 iPhone 12(iOS 16.0), 테스트폰은 iPhone 7+(iOS 15.7.3).
프로젝트 최소버전이 16이기에, 실제 디바이스에서 테스트를 하고 싶을 땐 iPhone 12 기기에서만 가능한 상황이었습니다.
그리고 20%라는 꽤 큰 숫자가 iOS 15를 사용 중이라는 데이터를 확인하니, 최소 버전을 15로 낮춰 약 92%의 디바이스를 커버하는 것이 좋을 것이라 생각되었습니다.

첫번째 이유는 지극히 개인적인 이유긴 하지만, 2가지 이유로 저는 프로젝트의 iOS 최소 버전을 15로 낮췄습니다!

❗️ iOS 16 -> iOS 15 변경으로 발생한 문제

  1. 모듈 버전 오류
  2. 공식 기능 사용 불가능(스크롤 해서 키보드 내리기)
  3. NavigationStack 사용 불가능

최소 버전 변경으로 이와 같은 문제가 발생했고 이어서 해결 방법 쓰겠습니당 :)
(1번과 2번 오류는 따로 글 작성해서 링크 첨부하겠습니다!)

위에서도 한 번 말했지만, NavigationStack은 NavigationView가 Deprecated 되면서 나온 새로운 기능입니다.
iOS 16 이상부터 사용이 가능하구요.
하지만 저는? iOS 버전을 15로 낮췄기에 NavigationStack을 사용할 수 없게 되었습니다 😢
(버전 분기 처리로 iOS 16 이상 디바이스에서 사용할 수 있긴 합니다.)

어쨌든 저는 15.x 디바이스를 위해 다시 NavigationView를 사용해야 했고 코드 수정을 했습니다.

NavigationStack -> NavigationView

그렇게 저는 원점으로 돌아왔습니다 히히
빌드 결과 또 다시 마주한 넓은 네비게이션 바 . . . (지긋지긋해 아주 !)

과거에 문제를 제대로 해결하지 못했던 저는, 그 때와 똑같이 구글링 하고 머리 뜯는 불필요한 시간들을 보냈습니당 . .
(근본 해결의 중요성. .)

그렇게 열심히 구글링 하다가 이전에는 보지 못했던 한 블로그를 발견합니다!
[SwiftUI] Navigation bar가 계속 쌓이는 문제를 해결하자

정말 한 줄기 빛과 같은 존재 ...

이 블로그 덕분에 바로 문제 해결 했습니다 하하
이렇게 또 하나 배워가는 응애 개발자 👶🏻

최종 해결 코드 ♡

1. First Page

import SwiftUI

struct FirstPage: View {
    var body: some View {
        NavigationView{ // ❗️
            NavigationLink {
                SecondPage()
            } label: { ... }
        }
    }
}

2. Second Page

import SwiftUI

struct SecondPage: View {
    var body: some View {
        Vstack() { ... }
        .toolbar { ... }
    }
}

블로그 속 코드와 동일하게 저도 첫번째 NavigationView만 살려두고 그 이후로 있는 NavigationView는 제거했습니다.

아주 깔끔하고 제가 원했던 View가 드디어 나왔습니다 😭
감격 ! 문제 해결 했을 때 그 짜릿함은 진짜 말로 설명하기 힘들어요.
(대충 굉장히 기쁘다는 뜻)

문제 해결 과정이 엄청 길고 복잡하고 한참을 헤매다 해결한 느낌이 강하죠..? 머쓱 😅
생각보다 단순한 문제였지만, 대충 틀어막고 해결한 척 하고 있다가 결국엔 동일한 문제를 마주한게 매우 창피합니당 :(

같은 실수 반복 댓츠노노

profile
iOS developer 👩🏻‍💻

0개의 댓글