Search code examples
swiftuiuikitswiftui-navigationlinkswiftui-navigationview

Remove title when pushing EKCalendarChooser to Navigation Stack with SwiftUI


I'm working on an app where I want to push the EKCalendarChooser View Controller to the navigation stack with a navigation link. Everything works as expected apart from the fact that I can't get rid of some magic title/label.

I want to hide the title marked with the red rectangle in the image.

enter image description here

I'm using the following code to push the view:

NavigationLink(destination: CalendarChooser(eventStore: self.eventStore)
                                .edgesIgnoringSafeArea([.top,.bottom])
                                .navigationTitle("My Navigation Title")) {
                                    
                                    Text("Calendar Selection")
                            }

And this is my UIViewControllerRepresentable

import SwiftUI
import EventKitUI

struct CalendarChooser: UIViewControllerRepresentable {
    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }
    
    @Environment(\.presentationMode) var presentationMode
    
    let eventStore: EKEventStore
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<CalendarChooser>) -> UINavigationController {
        let chooser = EKCalendarChooser(selectionStyle: .multiple, displayStyle: .allCalendars, entityType: .event, eventStore: eventStore)
        chooser.selectedCalendars = Set(eventStore.selectableCalendarsFromSettings)
        chooser.delegate = context.coordinator
        chooser.showsDoneButton = false
        chooser.showsCancelButton = false

        return UINavigationController(rootViewController: chooser)
    }
    
    func updateUIViewController(_ uiViewController: UINavigationController, context: UIViewControllerRepresentableContext<CalendarChooser>) {
        
    }
    
    class Coordinator: NSObject, UINavigationControllerDelegate, EKCalendarChooserDelegate {
        var parent: CalendarChooser
        
        init(_ parent: CalendarChooser) {
            self.parent = parent
        }
        
        func calendarChooserDidFinish(_ calendarChooser: EKCalendarChooser) {
            let selectedCalendarIDs = calendarChooser.selectedCalendars.compactMap { $0.calendarIdentifier }
            UserDefaults.savedCalendarIDs = selectedCalendarIDs
            NotificationCenter.default.post(name: .calendarSelectionDidChange, object: nil)
            
            parent.presentationMode.wrappedValue.dismiss()
        }
        
        func calendarChooserDidCancel(_ calendarChooser: EKCalendarChooser) {
            parent.presentationMode.wrappedValue.dismiss()
        }
    }
}

Note that I'm not even sure that I'm on the right track here and I'm open for any solution.


Solution

  • I think I've found a solution to my own problem. With a small modification to my UIViewControllerRepresentable the view looks the way I want it to. More specifically to the updateUIViewController function:

    func updateUIViewController(_ uiViewController: UINavigationController, context: UIViewControllerRepresentableContext<CalendarChooser>) {
    
            uiViewController.setNavigationBarHidden(true, animated: false) // This line!
    
    }
    

    By doing this I keep the navigation controls and title from the navigation link, which looks like this:

    enter image description here