SwiftUI 如何让 ForEach 循环根据 Picker 中选定月份的天数进行迭代

Posted

技术标签:

【中文标题】SwiftUI 如何让 ForEach 循环根据 Picker 中选定月份的天数进行迭代【英文标题】:SwiftUI How to Have a ForEach loop iterate based on how many days of a selected month in a Picker is 【发布时间】:2020-07-06 19:55:19 【问题描述】:

所以我创建了一行代码,它采用两个值,一年和一个月,根据你给它的值,它会计算给定年份的给定月份的天数。最初我打算使用 State 变量,所以它会自动更新,但由于 Structs 的工作方式,我无法使用刚刚初始化的变量。 (如“不能在属性初始化程序中使用实例成员 '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】:

据我所知,您应该可以在 ForEach 中调用 getRange(year:, month:) 函数。传入yearIndexmonthIndex

我编写了这个小示例代码来快速测试理论。让我知道这是否是您正在寻找的。​​p>

-丹

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)")
    

看看这是否会给你想要的回应。这不是你在做什么是完全错误的,我只是不太清楚你的最终意图是什么。但是玩弄代码,我认为你在正确的轨道上。

【讨论】:

感谢您的回答!我不知道你可以在 for 循环中输入函数——所以我已经做到了,而且它在大多数情况下都有效!唯一的事情是,当我使用选择器更改 monthIndex / yearIndex 变量的值时,它不会更新正在显示的 forEach 循环值 - 关于如何解决这个问题的任何想法? 我更新了代码以可能在这里解决您的问题。

以上是关于SwiftUI 如何让 ForEach 循环根据 Picker 中选定月份的天数进行迭代的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 中按钮操作内的 ForEach 循环?

在 ForEach 循环中绑定时,如何阻止 SwiftUI TextField 失去焦点?

无法让 ForEach 循环在 SwiftUI 中使用嵌套的 JSON 数据运行 [关闭]

SwiftUI - 如果在 ForEach 循环内

SwiftUI:如何使用 ForEach 循环使用各种代码的各种结构?

如何在 SwiftUI 的 ForEach 循环中增加状态?