[SwiftUI Mater] #12 Custom Navigation View

Woozoo·2023년 3월 31일
0

[SwiftUI Review]

목록 보기
27/41
post-custom-banner


기본적인 NavView는 이런 느낌이죠~

이 네비게이션 뷰를 고대로 이용해서 커스텀하게 만들어봅시다

struct CustomNavBarView: View {
    var body: some View {
        HStack {
            Button {
                
            } label: {
                Image(systemName: "chevron.left")
            }
            Spacer()
            VStack(spacing: 4) {
                Text("Title")
                    .font(.title)
                    .fontWeight(.semibold)
                Text("Subtitle goes here")
            }
            Spacer()
            Button {
                
            } label: {
                Image(systemName: "chevron.left")
            }
            .opacity(0)
        }
        .padding()
        .tint(.white)
        .foregroundColor(.white)
        .font(.headline)
        .background(Color.blue.ignoresSafeArea(edges: .top))
    }
}

새로운 CustomNavBarView를 만들어줌


바디 깔끔하게 만들어주고
필요한 변수들 선언해줬다!

CustomNavBar를 담아줄 컨테이너 뷰도 구성해줬음!!

Spacer를 사용하기보다는 content 뷰를 받아서 .frame으로 .infinity하게 해줬다


AppNavBar로 돌아와서 만들어준 컨테이너 뷰를 작성하는데
NavigationLink를 사용하려면 NavigationView로 감싸져야함

지금같이 Custom할 땐 어떻게 해야될까?

CustomNavView로 새로 만들어주고 @ViewBuilder를 사용할 수 있게 해줬다
이렇게 하면 NavigationView로 하나 감싸져 있으니까 기본적인 NavigationView를 사용할 수 있는 이점을 가지게 되겠죠


그리고 CustomNavView로 다시 만들어주게 되면
NavigationLink를 사용할 수 있어용

NavigationLink도 커스텀해봅시다

그리고 NavigationLink를 애플이 어떻게 구현했는지 보면


요렇습니다


똑같이 참고해서 만들어줍시다




디스미스가 안되고 있어서
CustomNavBarView에서 dismiss Environment 추가해줬다

그리고 AppNavBarView로 돌아와서 방금 만든 CustomNavLink를 넣어줬다!

PreferenceKey도 만들어줍시다

import Foundation
import SwiftUI

//@State private var showBackButton: Bool = true
//@State private var title: String = "Title" //""
//@State private var subtitle: String? = "Subtitle" //nil

struct CustomNavBarTitlePreferenceKeys: PreferenceKey {
    static var defaultValue: String = ""
    
    static func reduce(value: inout String, nextValue: () -> String) {
        value = nextValue()
    }
}

struct CustomNavBarSubtitlePreferenceKeys: PreferenceKey {
    static var defaultValue: String? = nil
    
    static func reduce(value: inout String?, nextValue: () -> String?) {
        value = nextValue()
    }
}

struct CustomNavBarBackButtonHiddenPreferenceKeys: PreferenceKey {
    static var defaultValue: Bool = false
    
    static func reduce(value: inout Bool, nextValue: () -> Bool) {
        value = nextValue()
    }
}

extension View {
    
    func customNavigationTitle(_ title: String) -> some View {
        preference(key: CustomNavBarTitlePreferenceKeys.self, value: title)
    }
    
    func customNavigationSubTitle(_ subtitle: String?) -> some View {
        preference(key: CustomNavBarSubtitlePreferenceKeys.self, value: subtitle)
    }
    
    func customNavigationBarBackButtonHidden(_ hidden: Bool) -> some View {
        preference(key: CustomNavBarBackButtonHiddenPreferenceKeys.self, value: hidden)
    }
    
    func customNavBarItems(title: String = "", subtitle: String? = nil, backButtonHidden: Bool = false) -> some View {
        self
            .customNavigationTitle(title)
            .customNavigationSubTitle(subtitle)
            .customNavigationBarBackButtonHidden(backButtonHidden)
    }
    
}




스와이프 제스쳐 매뉴얼하게 구현해줘야함

profile
우주형
post-custom-banner

0개의 댓글