Home > AI > IOS > SwiftUI >

(navigation)customize right view

At first, we need to get default navigationBar height to bind the right view size with the height to avoid hard-coding.

Step 1: get navigationBar height

NavigationConfiguration.swift

struct NavigationConfiguration: UIViewControllerRepresentable {
    var config: (UINavigationController) -> Void = { _ in }
    func makeUIViewController(context: Context) -> some UIViewController {
        let controller = UIViewController()
        DispatchQueue.main.async {
            if let nc = controller.navigationController {
                self.config(nc)
            }
        }
        return controller
    }
    
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
        if let nc = uiViewController.navigationController {
            self.config(nc)
        }
    }
}

GetDefaultNavBarHeightView.swift

struct GetDefaultNavBarHeightView: View {
    @Binding var defaultNavHeight: CGFloat
    @State var isHidden: Bool = false
    
    
    var body: some View {
        if !isHidden {
            Text("")
                .background(
                        NavigationConfiguration(config: { (nc) in
                        self.defaultNavHeight = nc.navigationBar.frame.height
                        })
                )
        }
    }
}

Step 2: build customize right view

struct NavRightView: View {
    var defaultNavHeight: CGFloat
    
    init(defaultNavHeight: CGFloat) {
        self.defaultNavHeight = defaultNavHeight
    }
    
    var body: some View {
        HStack {
            NavigationLink(destination: Text("material")) {
                NavRightUnitView(imgName: "material", des: "资料圈", defaultNavHeight: self.defaultNavHeight)
            }
            Spacer()
            NavigationLink(destination: Text("group")) {
                NavRightUnitView(imgName: "group", des: "备考群", defaultNavHeight: self.defaultNavHeight)
            }
        }
    }
}



struct NavRightUnitView: View {
    var defaultNavHeight: CGFloat
    var imgName: String
    var des: String
    
    init(imgName: String, des: String, defaultNavHeight: CGFloat) {
        self.imgName = imgName
        self.des = des
        self.defaultNavHeight = defaultNavHeight
    }
    
    
    var body: some View {
        VStack {
            Image(imgName)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 0.55*self.defaultNavHeight, height: 0.55*self.defaultNavHeight, alignment: .center)
        
            
            Text(des)
                .font(.system(size: 0.25*self.defaultNavHeight))
                .foregroundColor(.black)
        }
    }
}

ContentView.swift

struct ContentView: View {
 
    @State var defaultNavHeight: CGFloat = 0
    
 
    var body: some View {
        NavigationView {
            ZStack {
                GetDefaultNavBarHeightView(defaultNavHeight: $defaultNavHeight)
                
                Text("good")
            }
            .navigationBarTitleDisplayMode(.inline)
            .navigationBarItems(trailing: NavRightView(defaultNavHeight: defaultNavHeight))
        }
    }
}

Leave a Reply