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)")
}
}
Посмотрите, дает ли это желаемый ответ. Дело не в том, что вы делаете, совершенно неправильно, я просто не очень понимаю, каковы ваши конечные намерения. Но поиграйте с кодом, думаю, вы на правильном пути.