面试题答案
一键面试设计思路
- 日期选择器绑定:使用
@State
来绑定日期选择器选择的日期。 - 时间选择器绑定:同样使用
@State
来绑定时间选择器选择的时间。 - 业务规则函数:创建一个函数,根据传入的日期返回符合业务规则(如9:00 - 18:00)的时间数组。
- 动态更新:在日期选择器的
onChange
闭包中调用业务规则函数,更新时间选择器的可选时间。 - 性能优化:
- 缓存机制:对于相同日期多次请求时间数据的情况,使用缓存来避免重复计算。
- 批量更新:如果有大量数据更新,避免频繁的小更新,而是将更新操作合并,一次性处理。
- 异步计算:在后台线程计算符合业务规则的时间数据,避免阻塞主线程。
关键代码实现
import SwiftUI
struct ContentView: View {
@State private var selectedDate = Date()
@State private var selectedTime: Date?
private var availableTimes: [Date] = []
var body: some View {
VStack {
DatePicker("选择日期", selection: $selectedDate, displayedComponents:.date)
.onChange(of: selectedDate) { newDate in
availableTimes = getAvailableTimes(for: newDate)
if let firstTime = availableTimes.first {
selectedTime = firstTime
}
}
DatePicker("选择时间", selection: $selectedTime, in: availableTimes, displayedComponents:.hourAndMinute)
}
}
private func getAvailableTimes(for date: Date) -> [Date] {
// 这里简单示例,实际业务可能更复杂
let calendar = Calendar.current
let startComponents = DateComponents(calendar: calendar, year: calendar.component(.year, from: date), month: calendar.component(.month, from: date), day: calendar.component(.day, from: date), hour: 9, minute: 0)
let endComponents = DateComponents(calendar: calendar, year: calendar.component(.year, from: date), month: calendar.component(.month, from: date), day: calendar.component(.day, from: date), hour: 18, minute: 0)
guard let startTime = calendar.date(from: startComponents), let endTime = calendar.date(from: endComponents) else {
return []
}
var times: [Date] = []
var currentTime = startTime
while currentTime <= endTime {
times.append(currentTime)
currentTime = calendar.date(byAdding:.minute, value: 1, to: currentTime)!
}
return times
}
}
缓存机制优化
private var timeCache = [Date: [Date]]()
private func getAvailableTimes(for date: Date) -> [Date] {
if let cachedTimes = timeCache[date] {
return cachedTimes
}
// 这里简单示例,实际业务可能更复杂
let calendar = Calendar.current
let startComponents = DateComponents(calendar: calendar, year: calendar.component(.year, from: date), month: calendar.component(.month, from: date), day: calendar.component(.day, from: date), hour: 9, minute: 0)
let endComponents = DateComponents(calendar: calendar, year: calendar.component(.year, from: date), month: calendar.component(.month, from: date), day: calendar.component(.day, from: date), hour: 18, minute: 0)
guard let startTime = calendar.date(from: startComponents), let endTime = calendar.date(from: endComponents) else {
return []
}
var times: [Date] = []
var currentTime = startTime
while currentTime <= endTime {
times.append(currentTime)
currentTime = calendar.date(byAdding:.minute, value: 1, to: currentTime)!
}
timeCache[date] = times
return times
}
异步计算优化
private func getAvailableTimesAsync(for date: Date, completion: @escaping ([Date]) -> Void) {
if let cachedTimes = timeCache[date] {
completion(cachedTimes)
return
}
DispatchQueue.global(qos:.userInitiated).async {
let calendar = Calendar.current
let startComponents = DateComponents(calendar: calendar, year: calendar.component(.year, from: date), month: calendar.component(.month, from: date), day: calendar.component(.day, from: date), hour: 9, minute: 0)
let endComponents = DateComponents(calendar: calendar, year: calendar.component(.year, from: date), month: calendar.component(.month, from: date), day: calendar.component(.day, from: date), hour: 18, minute: 0)
guard let startTime = calendar.date(from: startComponents), let endTime = calendar.date(from: endComponents) else {
completion([])
return
}
var times: [Date] = []
var currentTime = startTime
while currentTime <= endTime {
times.append(currentTime)
currentTime = calendar.date(byAdding:.minute, value: 1, to: currentTime)!
}
self.timeCache[date] = times
DispatchQueue.main.async {
completion(times)
}
}
}
在onChange
中使用异步函数:
.onChange(of: selectedDate) { newDate in
getAvailableTimesAsync(for: newDate) { times in
availableTimes = times
if let firstTime = availableTimes.first {
selectedTime = firstTime
}
}
}