SwiftUI를 사용하여 앱을 개발할 때, NavigationView를 활용한 내비게이션을 사용하다 문제가 생겼다. 뒤로 가기 버튼이 중첩된다는 것... 분명 숨겼는데 왜 계속 중첩되나 찾아보고 멍청(...) 한 나 자신을 위해 여기 정리해보고자 한다.
문제의 원인
GithubLinkView와 같은 특정 뷰에서 두 개의 뒤로 가기 버튼이 나타나는 이유는 다음과 같다.
중첩된 NavigationView: GithubLinkView가 이미 다른 NavigationView 안에 포함되어 있을 때, 새로운 NavigationView를 추가하면 두 개의 내비게이션 바가 생성됨
기본 뒤로 가기 버튼 숨기기 실패: 기본적으로 제공되는 뒤로 가기 버튼을 숨기지 않으면, 사용자 정의 버튼과 함께 표시됨
나 같은 경우 첫번째가 원인이었다.
해결 방법
앱의 구조를 점검하여 모든 뷰가 단일 NavigationView 내에 포함되도록 한다. 예를 들어, ContentView에서 GithubLinkView를 호출할 때, NavigationView가 중첩되지 않도록 하면 된다.
struct ContentView: View {
@StateObject private var viewModel = AppleSignInViewModel()
var body: some View {
NavigationView {
ZStack {
// 주요 콘텐츠
Group {
if viewModel.isSignedIn {
HomeView()
} else {
VStack {
// 콘텐츠 뷰 구성 요소
NavigationLink(
destination: GithubLinkView(viewModel: viewModel),
isActive: $viewModel.showGitHubSignIn
) {
EmptyView()
}
.hidden() // 프로그래밍적으로 내비게이션 트리거
}
}
}
}
.navigationBarHidden(true) // 내비게이션 바 숨기기
}
}
}
GithubLinkView에서 NavigationView 제거
GithubLinkView가 다른 NavigationView 안에서 사용되고 있다면, 내부의 NavigationView 래퍼를 제거해야 한다. 이렇게 하면 중복된 내비게이션 바가 생성되지 않는다.
// 수정 전
import SwiftUI
struct GithubLinkView: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var viewModel: AppleSignInViewModel
var body: some View {
NavigationView {
VStack(spacing: 104) {
Spacer()
VStack(spacing: 34) {
// 생략
}
}
.padding(.bottom, 110)
.background(Color.white)
.edgesIgnoringSafeArea(.all)
.navigationBarBackButtonHidden(true) // 기본 뒤로 가기 버튼 숨기기
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
HStack {
Image(systemName: "chevron.left")
.foregroundColor(.blue) // 색상 사용자화
Text("뒤로")
.foregroundColor(.blue) // 색상 사용자화
}
}
}
}
}
}
}
// 수정 후
import SwiftUI
struct GithubLinkView: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var viewModel: AppleSignInViewModel
var body: some View {
VStack(spacing: 104) {
Spacer()
VStack(spacing: 34) {
// 생략
}
}
.padding(.bottom, 110)
.background(Color.white)
.edgesIgnoringSafeArea(.all)
.navigationBarBackButtonHidden(true) // 기본 뒤로 가기 버튼 숨기기
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
HStack {
Image(systemName: "chevron.left")
.foregroundColor(.blue) // 색상 사용자화
Text("뒤로")
.foregroundColor(.blue) // 색상 사용자화
}
}
}
}
}
}
뒤로 가기 버튼 색상 변경
한 가지 더 알아보자면, 뒤로 가기 버튼의 색상과 스타일을 변경하려면. toolbar를 사용하여 버튼의 색상을 설정할 수 있다.
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
HStack {
Image(systemName: "chevron.left")
.foregroundColor(.blue) // 색상 사용자화
Text("뒤로")
.foregroundColor(.blue) // 색상 사용자화
}
}
}
}
요약
단일 NavigationView 사용: 모든 레벨에서 단일 NavigationView만 사용하기
중첩된 NavigationView 제거: GithubLinkView 내부의 불필요한 NavigationView 래퍼를 제거하기
뒤로 가기 버튼 사용자화: .toolbar를 사용하여 뒤로 가기 버튼의 색상과 스타일을 변경할 수 있음
'걔 (개발)로그 > SwiftUI' 카테고리의 다른 글
| SwiftUI | 상태 관리: 속성 래퍼 정리 (0) | 2024.08.05 |
|---|---|
| SwiftUI | Firebase Github Login (0) | 2024.07.26 |
| SwiftUI | Luanch Screen(Splash Image) 구현 (0) | 2024.07.23 |