はじめに
今回はSwiftUiで独自のTimePickerを実装する
コード
import SwiftUI
struct SelectTimeWheelView: View {
// 初期値(時間)
@State var selectedHour: Int
// 初期値(分)
@State var selectedMinute: Int
var minimumTime: DateComponents
var maximumTime: DateComponents
var cancelAction: () -> Void = {}
var completedAction: (_ hour: Int, _ minute: Int) -> Void = { _, _ in }
var body: some View {
VStack(spacing: 0) {
HStack {
Button(action: {
cancelAction()
}) {
Image(systemName: "xmark")
.foregroundStyle(Color.Black)
.frame(width: 24, height: 24)
.padding(16)
}
Spacer()
Button(action: {
completedAction(selectedHour, selectedMinute)
}) {
Text("保存")
}
}
.padding()
.frame(height: 60)
HStack {
Picker(selection: $selectedHour) {
ForEach(getAvailableHours, id: \.self) { hour in
Text(String(format: "%02d", hour))
.tag(hour)
}
} label: {}
Text(":")
Picker(selection: $selectedMinute) {
ForEach(getAvailableMinutes, id: \.self) { minute in
Text(String(format: "%02d", minute))
.tag(minute)
}
} label: {}
}
.pickerStyle(.wheel)
}
}
var getAvailableHours: [Int] {
let startHour = minimumTime.hour ?? 0
let endHour = maximumTime.hour ?? 24
return Array(startHour...endHour)
}
var getAvailableMinutes: [Int] {
let minuteRange = stride(from: 0, through: 55, by: 5).map { $0 }
var availableMinutes: [Int]
if selectedHour == minimumTime.hour && selectedHour == maximumTime.hour {
availableMinutes = minuteRange
.filter { $0 >= minimumTime.minute ?? 0 }
.filter { $0 <= maximumTime.minute ?? 0 }
} else if selectedHour == minimumTime.hour {
availableMinutes = minuteRange
.filter { $0 >= minimumTime.minute ?? 0 }
} else if selectedHour == maximumTime.hour {
availableMinutes = minuteRange
.filter { $0 <= maximumTime.minute ?? 0 }
} else {
availableMinutes = minuteRange
}
print("Available Minutes: \(availableMinutes)")
return availableMinutes
}
}
#Preview {
struct Preview: View {
var body: some View {
SelectTimeWheelView(
selectedHour: 9,
selectedMinute: 0,
minimumTime: .init(hour: 9, minute: 0),
maximumTime: .init(hour: 18, minute: 0)
)
.padding()
}
}
return Preview()
}
最後に
幅を変更したり要素を変更すれば時間以外にも使えるのでぜひ