iOS

[iOS-SwiftUI] TabBar > NavigationLink 닫히는 이슈

i-moo 2023. 7. 20. 16:58
반응형

 
너무 오랜만에 글을 남긴다.
노션에 정리하다보니 블로그는 멈춰있었는데
오늘 이 내용은 SwiftUI로 개발하시는 분들이 같은 이슈가 있다면 빨리 해결하시기 바라는 마음으로 작성해봤다.
나는 꽤나 헤맸기때문..🥲
 
SwiftUI로 개발된 앱을 백그라운드로 넘길 때 화면 전환 이슈가 발생했다.
앱이 죽는 건 아니었고,
백그라운드에서 포그라운드로 넘어올 때 NavigationLink로 열려있던 화면을 닫아버리는 현상이 발생했다.

FirstView가 파란글씨의 Hello, World!
SecondView가 노란배경의 Hello, World!
FirstView에서 NaivationLink로 SecondView를 호출했다.

struct FirstView: View {
    var body: some View {
        ZStack {
            NavigationLink {
                SecondView()
            } label: {
                Text("Hello, World!")
            }
        }
    }
}

Hello, World! > Hello, World!
SecondView 화면이 떠 있는 상태로 백그라운드 넘겼다가 다시 포그라운드로 넘어왔을 때,
SecondView 화면이 그대로 떠있는게 아니라 닫히면서 FirstView 화면이 보이는 이슈였다.
 
앱을 백그라운드로 보낼 때 2가지 로그가 출력되었다.
1. [Snapshotting] Snapshotting a view

that is not in a visible window requires afterScreenUpdates:YES.



2. Trying to pop to a missing destination - SwiftUI/NavigationBridge_PhoneTV.swift:213 - please file a bug report.

사실 처음 이슈를 발견했을땐,
두번째 로그가 FirstView에서 데이터를 호출하는 api 로그랑 섞여서 보이지 않았다.
그래서 SwiftUI Snapshotting 관련해서 이슈 내용들을 찾아보았는데,,,😱
관련 없는 부분들이었고 테스트를 하다보니 드디어 missing destination 문구가 눈에 보이게 된 것이다.
 
해당 관련 내용들을 찾아보니 백그라운드에서 포그라운드로 넘어올 때 떠있던 화면 위치를 찾아야하는데 찾지 못하는 현상이었다.
동일 이슈 코드 중 TabBar를 공통적으로 사용하는 것을 발견👍
 
TabBar NavigationLink관련 이슈를 찾아보니 금방 원인을 알 수 있었다.
결론부터 말하자면 NavigationLink를 사용할거면 그 상단 뷰가 NavigationView로 감싸있어야함.

// 기존 앱 구조

NavigationView {
    TabView(selection: $selectedIndex) {
        FirstView()
	        .tag(0)
    }
}
.padding()

기존 구조에서도 당연하게 FirstView는 NavigationView로 감싸져있었고,
FirstView에서 NavigationLink로 SecondView를 호출하고 있었다.
 

 

// 이슈 수정 앱 구조

TabView(selection: $selectedIndex) {
    NavigationView {
        FirstView()
    }
    .tag(0)
}
.padding()

알고보니!
NavigationView로 감싸더라도 사이에 TabView가 있으면 NavigationView가 끊긴다는 점!!!
그렇기때문에 TabView 안에 NavigationView가 존재해야하며 그 안에 FirstView를 넣어 NavigationLink를 사용하는 방식으로 진행해야 했다.
 
이부분은 SwiftUI의 개선이 되어야하는 부분인지 의도가 있는 부분인지까지는 아직 확인을 못했다.
(아시면 댓글로 알려주세요🙏)
 
 
근데 이렇게 사용할 경우,
NavigationLink를 통해 화면 이동을 하면 TabBar가 항상 보이게 된다.
TabBar가 없는 FullScreen으로 보이게 하고 싶은 경우 세가지 방법이 있어보인다.
1. 완전하게 TabBar를 커스텀해서 쓰거나
2. Event를 사용하여 TabBar를 show/hide 해주거나
3. Event를 사용하여 TabView와 같은 레벨에서 NavigationLink를 호출하거나
 
https://stackoverflow.com/questions/58444689/swiftui-hide-tabbar-in-subview

SwiftUI hide TabBar in subview

I am working with SwiftUI, and I have some issues with the TabBar. I want to hide the TabBar on a specific subview. Have tried with UITabBar.appearance().isHidden = true It only works on the di...

stackoverflow.com

https://medium.com/geekculture/full-screen-navigation-view-over-tabbar-in-swiftui-991ca2ccfefc

Full Screen Navigation View over Tabbar in SwiftUI

In this blog, you can see how you can navigate a view over the Tabbar view in SwiftUI by using the reactive programming framework called…

medium.com

 
어떤 방법이 제일 베스트일지는 좀더 지켜봐야할 것 같다.
 
 
 
git
https://github.com/gr-kim-94/NavigationTapView

GitHub - gr-kim-94/NavigationTapView

Contribute to gr-kim-94/NavigationTapView development by creating an account on GitHub.

github.com

 
참고 링크
https://stackoverflow.com/questions/64124502/swiftui-navigationview-trying-to-pop-to-missing-destination-monoceros

SwiftUI NavigationView trying to pop to missing destination (Monoceros?)

I'm using Xcode 12 with deployment for iOS 14.0. My home screen has a NavigationView Within the NavigationView there is a TabView (with 4 tabs) Within each tab are subviews that have buttons and

stackoverflow.com

https://stackoverflow.com/questions/58737567/tried-to-pop-to-a-view-controller-that-doesnt-exist-in-swiftui

Tried to pop to a view controller that doesn't exist in SwiftUI

I'm getting a strange crash from pretty normal navigation on my SwiftUI app I have a simple tab view : struct FFTabView: View { var body: some View { TabView { LibraryView...

stackoverflow.com

 

반응형