SwiftUI Как заставить цикл ForEach повторяться в зависимости от того, сколько дней в выбранном месяце в Picker

Итак, я создал строку кода, которая принимает два значения, год и месяц, и в зависимости от того, какие значения вы ей дадите, она вычислит количество дней в данном месяце для данного года. Первоначально я собирался использовать переменные состояния, чтобы они просто обновлялись автоматически, но из-за того, как работают структуры, я не мог использовать переменные, которые я только что инициализировал. (как в случае "Невозможно использовать член экземпляра 'year' в инициализаторе свойства; инициализаторы свойств запускаются до того, как 'self' становится доступным" Ошибка). Причина, по которой мне нужен этот код, заключается в том, что я хочу, чтобы цикл forEach автоматически выполнялся на основе этого числа (поскольку приложение, которое я создаю, будет иметь список на каждый день в течение следующих двух лет). Вот мой код:

struct YearView: View {

@State var year = [2020, 2021, 2022]
//monthSymbols gets an array of all the months
@State var monthArray = DateFormatter().monthSymbols!
@State var yearIndex = 0
@State var monthIndex = 0
@State var month = 0
@State var daysInMonth = Calendar.current.range(of: .day, in: .month, for: Calendar.current.date(from: DateComponents(year: year, month: month + 1))!)!.count

var body: some View {
    NavigationView {
        
        
        List {
            Section {
                VStack {
                    Picker("Years", selection: $yearIndex) {
                        ForEach(0 ..< year.count) { index in
                            Text(String(self.year[index])).tag(index)
                        }
                    }
                    .pickerStyle(SegmentedPickerStyle())
                    
                    
                    Divider()
                    
                    if yearIndex == 0 {
                        Picker("Month", selection: $monthIndex) {
                            ForEach(6 ..< monthArray.count) { index in
                                Text(self.monthArray[index]).tag(index)
                            }
                        }
                        .padding(.bottom, 2)
                    } else {
                        Picker("Month", selection: $monthIndex) {
                            ForEach(0 ..< monthArray.count) { index in
                                Text(self.monthArray[index]).tag(index)
                            }
                        }
                        .padding(.bottom, 2)
                        
                    }
                }
            }
            
            Section {
                ForEach(0..<10) { i in
                    NavigationLink(destination: ContentView(day: dayData[i])) {
                        DayRow(day: dayData[i])
                    }
                }
            }
        }
        .navigationBarTitle(Text("\(monthArray[monthIndex + indexTest]) \(String(year[yearIndex]))"))
    }
    .listStyle(InsetGroupedListStyle())
}

}

Я хочу повторить цикл ForEach, который находится по ссылке навигации. Я пробовал создать функцию как таковую:

func getRange(year: Int, month: Int) -> Int {
return Calendar.current.range(of: .day, in: .month, for: Calendar.current.date(from: DateComponents(year: year, month: month + 1))!)!.count

}

Однако я не уверен, где бы я это запустил, если это вообще сработает. Я новичок в SwiftUI и GitHub, поэтому, если есть дополнительная информация, которую я могу предоставить, это поможет, просто спросите!

1 ответ

Решение

Насколько я могу судить, вы должны иметь возможность вызывать функцию getRange(year:, month:) в вашем ForEach. Переходя вyearIndex а также monthIndex.

Я написал этот небольшой пример кода, чтобы быстро проверить теорию. Сообщите мне, если это то, что вы ищете.

-Дэн

struct ContentView: View {
    @State private var year = 3
    @State private var month = 2


    var body: some View {
         List {
            ForEach(0 ..< getRange(year: year, month: month)) { i in
                Text("\(i)")
            }
        }

    }

    func getRange(year: Int, month: Int) -> Int {
        return Calendar.current.range(of: .day, in: .month, for: Calendar.current.date(from: DateComponents(year: year, month: month + 1))!)!.count
    }
}

отредактируйте, чтобы ответить на вопрос в вашем комментарии;

Чтобы правильно обновить метку Picker, попробуйте изменить свой код на этот:

Picker("Years", selection: $year) {
    ForEach(0 ..< year) { index in
        Text("\(index)")
    }
}

Посмотрите, дает ли это желаемый ответ. Дело не в том, что вы делаете, совершенно неправильно, я просто не очень понимаю, каковы ваши конечные намерения. Но поиграйте с кодом, думаю, вы на правильном пути.

Другие вопросы по тегам