如何在LazyGrid SwiftUI中更改特定数量的项目?

4uqofj5v  于 2022-12-22  发布在  Swift
关注(0)|答案(2)|浏览(151)

我希望能够在网格中选择多个项目(例如,前20个)并更改元素的颜色。

import SwiftUI

struct ContentView: View {
    @State var showView = false
    @State private var birthDate = Date.now
    struct Day: Identifiable {
        let id = UUID()
        let value: Int
    }
    
    struct Month {
        let name: String
        let numberOfDays: Int
        var days: [Day]

        init(name: String, numberOfDays: Int) {
            self.name = name
            self.numberOfDays = numberOfDays
            self.days = []

            for n in 1...numberOfDays {
                self.days.append(Day(value: n))
            }

        }
    }
    
    let year = [
        Month(name: "Youth", numberOfDays: 12),
        Month(name: "Teenager", numberOfDays: 7),
        Month(name: "20s - 30s", numberOfDays: 20),
        Month(name: "Middle ages", numberOfDays: 26),
        Month(name: "Retirement", numberOfDays: 35),
    ]
    let layout = [
            GridItem(.flexible(minimum: 40)),
            GridItem(.flexible(minimum: 40)),
            GridItem(.flexible(minimum: 40)),
            GridItem(.flexible(minimum: 40)),
            GridItem(.flexible(minimum: 40)),
        ]
    
    var body: some View {
        VStack {
                   DatePicker(selection: $birthDate, in: ...Date.now, displayedComponents: .date) {
                   }

                   Text("Your Birthdate is \(birthDate.formatted(date: .long, time: .omitted))")
               
            ScrollView {
                
                LazyVGrid(columns: layout, pinnedViews: [.sectionHeaders]) {
                    ForEach(year, id: \.name){ month in
                        Section(header: Text(verbatim: month.name).font(.headline)) {
                            ForEach(month.days) { day in
                                Capsule()
                            }
                       }
                    }
                }.padding(5)
            }  
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

看起来是这样的。
screenshot of the app currently
这就是我想要发生的-我会整合日期,但需要一种方法来更改特定数量的日期(在本例中,其中7个日期已更改:
same screenshot with 7 elements selected and changed colour from blue to black
我已经尝试了ForEach,但似乎不能得到它的工作,任何帮助将不胜感激。

hfsqlsce

hfsqlsce1#

希望这能有所帮助):

import SwiftUI

struct ContentView: View {
    @State var showView = false
    @State private var birthDate = Date.now
    struct Day: Identifiable {
        let id = UUID()
        let value: Int
    }

    struct Month {
        let name: String
        let numberOfDays: Int
        var days: [Day]

        init(name: String, numberOfDays: Int) {
            self.name = name
            self.numberOfDays = numberOfDays
            days = []

            for n in 1 ... numberOfDays {
                days.append(Day(value: n))
            }
        }
    }

    let year = [
        Month(name: "Youth", numberOfDays: 12),
        Month(name: "Teenager", numberOfDays: 7),
        Month(name: "20s - 30s", numberOfDays: 20),
        Month(name: "Middle ages", numberOfDays: 26),
        Month(name: "Retirement", numberOfDays: 35),
    ]
    let layout = [
        GridItem(.flexible(minimum: 40)),
        GridItem(.flexible(minimum: 40)),
        GridItem(.flexible(minimum: 40)),
        GridItem(.flexible(minimum: 40)),
        GridItem(.flexible(minimum: 40)),
    ]
    @State private var selected: Set<Day.ID> = []
    init() {
        guard let selectedDays = year.first?.days else { return }
        _selected = .init(initialValue: .init(selectedDays.map { $0.id }))
    }

    var body: some View {
        VStack {
            DatePicker(selection: $birthDate, in: ...Date.now, displayedComponents: .date) {}

            Text("Your Birthdate is \(birthDate.formatted(date: .long, time: .omitted))")

            ScrollView {
                LazyVGrid(columns: layout, pinnedViews: [.sectionHeaders]) {
                    ForEach(year, id: \.name) { month in
                        Section(header: Text(verbatim: month.name).font(.headline)) {
                            ForEach(month.days) { day in
                                Capsule()
                                    .fill(isSelected(id: day.id) ? .gray : .cyan)
                            }
                        }
                    }
                }.padding(5)
            }
        }
    }

    private func isSelected(id: Day.ID) -> Bool {
        return selected.contains(id)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
monwx1rj

monwx1rj2#

1.你需要在你的Day结构体中添加一个新的属性来跟踪选择,我称之为selected
1.必须将year声明为@State变量-因此它是视图的真实来源,并且可以修改。
1.要使day在视图中可变,必须使用ForEach的$初始化器向下传递年、月和日。
(通过为基本数据使用ObservableObject类,可以更好地求解2.和3.)
1.根据day.selected变更胶囊颜色。
1.点击手势切换day.selected

struct ContentView: View {
    
    @State var showView = false
    @State private var birthDate = Date.now
    
    
    struct Day: Identifiable {
        let id = UUID()
        let value: Int
        var selected: Bool = false // new property here
    }
    
    struct Month {
        let name: String
        let numberOfDays: Int
        var days: [Day]

        init(name: String, numberOfDays: Int) {
            self.name = name
            self.numberOfDays = numberOfDays
            self.days = []

            for n in 1...numberOfDays {
                self.days.append(Day(value: n))
            }

        }
    }
    
    @State var year = [   // define year as State to make it changeable
        Month(name: "Youth", numberOfDays: 12),
        Month(name: "Teenager", numberOfDays: 7),
        Month(name: "20s - 30s", numberOfDays: 20),
        Month(name: "Middle ages", numberOfDays: 26),
        Month(name: "Retirement", numberOfDays: 35),
    ]
    
    let layout = [
            GridItem(.flexible(minimum: 40)),
            GridItem(.flexible(minimum: 40)),
            GridItem(.flexible(minimum: 40)),
            GridItem(.flexible(minimum: 40)),
            GridItem(.flexible(minimum: 40)),
        ]
    
    var body: some View {
        VStack {
            DatePicker(selection: $birthDate, in: ...Date.now, displayedComponents: .date) {
            }
            
            Text("Your Birthdate is \(birthDate.formatted(date: .long, time: .omitted))")
            
            ScrollView {
                
                LazyVGrid(columns: layout, pinnedViews: [.sectionHeaders]) {
                    ForEach($year, id: \.name){ $month in  // binding init
                        Section(header: Text(verbatim: month.name).font(.headline)) {
                            ForEach($month.days) { $day in // binding init
                                Capsule()
                                    .frame(height: 20)
                                    .foregroundColor(day.selected ? .red : .cyan) // different colors based on selected
                                    .onTapGesture {
                                        day.selected.toggle() // on Tap toggle selected
                                    }
                            }
                        }
                    }
                }.padding(5)
            }
        }
    }
}

相关问题