在 LazyHGrid 上预选一个项目

Preselection of an item on LazyHGrid

大家好,我正在使用 LazyHGrid 网格显示分为 2 行的 19 个单元格,它们的内容是用户可以 select.

的次数

我对 preselection 有疑问,即我希望当显示水平网格时,可以看到基于当前时间的 preselection 例如

我给你举个网格的例子


| 9:30 | - | 10:00 | - | 10:30 | - | 11:00 |


如果此时是 10:20 我希望包含文本 10:30 的单元格自动 select当用户第一次看到网格时编辑


| 9:30 | - | 10:00 | - | 10:30 | - | 11:00 |
Preselection at 10:30 if current time is 10:20


简而言之,我需要包含比当前时间提前半小时的时间的单元格的 selection

这是我目前所做的

你能帮帮我吗?

struct TimeSelectorView: View {
    
    @State private var selectedItem: Int = 0
    
    @Binding var date: Date
    
    var body: some View {
        
        VStack (alignment: .center, spacing: 20) {
            ScrollView(.horizontal, showsIndicators: false) {
                ScrollViewReader { reader in
                    LazyHGrid(rows: Array(repeating: GridItem(.adaptive(minimum: 100, maximum: .infinity), spacing: 0), count: 2), spacing: 0) {
                        ForEach(reservationTimeItems.indices) { value in
                        
                            TimeSelectorCellView(selectedItem: $selectedItem, 
                              date: $date, 
                              hours: reservationTimeItems[value].hour, 
                              minute: reservationTimeItems[value].minute, 
                              item: value)
                                
                            .frame(width: (screen.size.width - 20 ) / 4)
                            .padding([.top, .bottom], 10)
                            .id(value)
                        }
                    }
                    .onAppear { scrollTo((8, 12, 0), reader) }
                    .onChange(of: date) { _ in scrollTo((8, 12, 0), reader) }
                    .onChange(of: selectedItem) { newValue in

                    date = Calendar.current.date(bySettingHour: reservationTimeItems[newValue].hour, 
                    minute: reservationTimeItems[newValue].minute, 
                    second: 0, of: date)!
                }
                }
            }
            .frame(height: 110)
        }
    }
}

struct TimeSelectorCellView: View {
       
    @Binding var selectedItem: Int
    @Binding var date: Date
    
    private var selectionColor: Color { selected ? .greenApp : .white }
    private var selectionOpacity: CGFloat { selected ? 1 : 0 }
    
    private var selected: Bool {
        selectedItem == item
    }
    
    private var disableItem: Bool {
        // Disabilita la cella nel caso in cui la data selezionata è quella di oggi e l'orario della data corrente è inferiore a quello contenuto nella cella
        Date().checkTime(hour: hours, minute: minute) && date.isToday()
        // oppure se la data selezionata è inferiore a quella corrente
        || date.isPreviousDate()
    }
    
    var hours: Int // Ore della data
    var minute: Int // Minuti della data
    var item: Int

    var body: some View {
        
        VStack(alignment: .leading, spacing: 10) {
            
            HStack(alignment: .center, spacing: 2) {
                                
                Text(hours < 10 ? "0\(hours)" : "\(hours)")
                    .foregroundColor(disableItem ? disabledColor : selectionColor)
                    .font(.system(size: 23))
                
                // Minuti
                HStack(spacing: 3) {
                    Text(":").foregroundColor(.white)
                    Text(minute < 10 ? "0\(minute)" : "\(minute)")
                        .foregroundColor(disableItem ? disabledColor : selectionColor)
                }
                .font(.footnote)
            }
        }
        // Selezione e feedback tattile
        .onTapGesture {
            UIImpactFeedbackGenerator(style: .medium).impactOccurred()

            DispatchQueue.main.async {
                withAnimation(.easeInOut(duration: animationDuration)) {
                    // Gestisce la selezione della cella
                        selectedItem = item
                }
            }
        }
        .disabled(disableItem)
    }
}

提供的代码中没有指定reservationTimeItems的类型,所以假设reservationTimeItems的类型是[ReservationTime],其中ReservationTime的定义如下:

struct ReservationTime: Identifiable, Equatable {
    let id: UUID = UUID()
    var hour: Int
    var minute: Int
    
    static func ==(lhs: ReservationTime, rhs: ReservationTime) -> Bool {
        lhs.hour == rhs.hour && lhs.minute == rhs.minute
    }
}

我要添加此扩展程序:

extension Date {
    var hour: Int {
        Calendar.current.dateComponents([.hour], from: self).hour ?? 0
    }
    var minute: Int {
        Calendar.current.dateComponents([.minute], from: self).minute ?? 0
    }
    var nextReservationTime: ReservationTime {
        let nextHalfHour = self.minute < 30 ? self.hour : (self.hour + 1) % 24
        let nextHalfMinute = self.minute < 30 ? 30 : 0
        
        return ReservationTime(hour: nextHalfHour, minute: nextHalfMinute)
    }
}

然后,在 TimeSelectorView:

struct TimeSelectorView: View {
    @State private var selectedItem: Int = 0  

    // ...
    
    var body: some View {
        VStack(alignment: .center, spacing: 20) {
            // ...
        }.onAppear {
            selectedItem = reservationTimeItems.firstIndex(of: Date().nextReservationTime) ?? 0
        }
    }
}