Search code examples
swiftuiipadosios16swiftui-navigationsplitview

UICalendarView vs SwiftUI DatePicker wrong size in NavigationSplitView sidebar


Because i need to add badges to certain dates, i need to use a UICalendarView representable, however when using this in the NavigationSplitView sidebar, the width of the UICalendarView is incorrect... in contrast the graphical DatePicker which should be the same component, is layout correctly

In the detail pane the layout the same, the problem arises with less horizontal space

How to fix this?

enter image description here

struct CalendarUI: UIViewRepresentable {
    
    let interval: DateInterval
    
    func makeUIView(context: Context) -> UICalendarView {
        let view = UICalendarView()
        view.calendar = Calendar.current
        view.availableDateRange = interval
        return view
    }
    
    func updateUIView(_ uiView: UICalendarView, context: Context) {
        
    }
    
}

struct SidebarUI: View {
    
    @State private var date = Date()
    
    var body: some View {
        VStack {
            CalendarUI(interval: DateInterval(start: .distantPast, end: .distantFuture))
                .fixedSize(horizontal: true, vertical: true)
            DatePicker(
                "Start Date",
                selection: $date,
                displayedComponents: [.date]
            )
            .datePickerStyle(.graphical)
        }.padding()
    }
}

Solution

  • I had the same issue as you: UICalendarView when wrapped in a UIViewRepresentable for use in SwiftUI is not resizing itself as expected and tries to take the full width.

    The following solution works for me: In func makeUIView(context: Context) -> UICalendarView add the lines below:

    // Make sure our calendar view adapts nicely to size constraints.
    view.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
    view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
    

    Further I have changed the .fixedSize modifier to not apply to the horizontal axis!

    CalendarUI(interval: DateInterval(start: .distantPast, end: .distantFuture))
        .fixedSize(horizontal: false, vertical: true)