Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: NavigationLink presenting a value must appear inside a NavigationStack... when having a NavigationLink inside .days #308

Open
BredBurr opened this issue May 28, 2024 · 1 comment

Comments

@BredBurr
Copy link

BredBurr commented May 28, 2024

Hi guys, thanks so much for this great calendar code!

I'm on iOS16+ and I use NavigationStack and NavigationLink(value: ) and I encounter an error if I put the NavigationLink inside .days modifier.

I have a simple app MainView -> CalendarView -> ContentView.
My .days modifier looks like this:

var body: some View {
    VStack(alignment: .center) {
        CalendarViewRepresentable(calendar: calendar,
                                  visibleDateRange: startDate...Date(),
                                  monthsLayout: .horizontal(options: HorizontalMonthsLayoutOptions(maximumFullyVisibleMonths: 1,
                                                                                                   scrollingBehavior: .paginatedScrolling(.init(restingPosition: .atLeadingEdgeOfEachMonth, restingAffinity: .atPositionsAdjacentToPrevious)))),
                                  dataDependency: selectedDayRange,
                                  proxy: calendarViewProxy)

        //HERE:
        .days { day in
            NavigationLink(value: myValue) {
                ArchiveDayView(dayNumber: day.day, value: myValue)
            }
        }
    }
}

I get this:
Errors

This code has been working FINE for the past half a year. So it must be something new in the latest Xcode. What if the links placed inside modifiers stop working...

Can you suggest the correct way to place a link inside a day?
Thanks!

@BredBurr
Copy link
Author

I've made a barebones working example, which you can copy-paste and see for yourself. Run it on the real device.

  • From the MainView go to the CalendarView and back.
import SwiftUI
import HorizonCalendar

@main
struct SwiftUICalendarNavigationApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationStack {
            NavigationLink(value: 7) {
                Text("Just go to day 7")
            }.padding()
            
            NavigationLink(value: "Calend") {
                Text("Go to Calendar view")
            }
            
            .navigationDestination(for: Int.self) { day in
                DayView(day: day)
            }
            .navigationDestination(for: String.self) { destination in
                CalendView()
            }
        }
    }
}

struct DayView: View {
    let day: Int
    
    var body: some View {
        Text("You are viewing day \(day)")
    }
}

struct CalendView: View {
    @StateObject private var calendarViewProxy = CalendarViewProxy()
    @State private var selectedDayRange: DayComponentsRange?
    
    private var calendar: Calendar
    private let startDate: Date
    private let monthDateFormatter: DateFormatter
    
    init() {
        calendar = Calendar(identifier: .gregorian)
        
        startDate = calendar.date(from: DateComponents(timeZone: TimeZone(abbreviation: "UTC")!,
                                                       year: 2024,
                                                       month: 01,
                                                       day: 01))!
        
        monthDateFormatter = DateFormatter()
        monthDateFormatter.calendar = calendar
        monthDateFormatter.dateFormat = "MMMM yyyy"
    }
    
    var body: some View {
        VStack(alignment: .center) {
            CalendarViewRepresentable(calendar: calendar,
                                      visibleDateRange: startDate...Date(),
                                      monthsLayout: .horizontal(options: HorizontalMonthsLayoutOptions(maximumFullyVisibleMonths: 1,
                                                                                                       scrollingBehavior: .paginatedScrolling(.init(restingPosition: .atLeadingEdgeOfEachMonth, restingAffinity: .atPositionsAdjacentToPrevious)))),
                                      dataDependency: selectedDayRange,
                                      proxy: calendarViewProxy)
            
            .interMonthSpacing(20)
            .verticalDayMargin(14)
            .horizontalDayMargin(14)
            
            .monthHeaders { month in
                let monthHeaderText = monthDateFormatter.string(from: calendar.date(from: month.components)!)
                Text(monthHeaderText)
                    .font(.title2)
                    .padding()
            }
            
            //Here it is:
            .days { day in
                NavigationLink(value: day.day) {
                    Text("\(day.day)")
                }
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .padding()
        .navigationBarTitleDisplayMode(.inline)
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant