在 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
}
}
}
大家好,我正在使用 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
}
}
}