我正在尝试创建一个包含下拉菜单的切换开关,其中包含开始和停止时间范围选择器。然后堆叠 7 个开关,代表一周中的几天
I am trying to create a toggle containing a dropdown with both a start and stop time range picker. Then stack 7 toggles representing days of the week
这是问题所在
- 当重复切换超过 5 次时,代码会引发编译错误。
- 需要在不切换到关闭位置的情况下关闭选择器。
- 选择的开始和停止时间显示在切换栏中,但随后会重置
当前代码:不要笑得太厉害 ;-)
import SwiftUI
struct ContentView: View {
@State private var toggleStateM = false
@State private var toggleStateT = false
@State private var toggleStateW = false
@State private var toggleStateTH = false
@State private var toggleStateF = false
//@State private var toggleStateST = false
//@State private var toggleStateSN = false
@State private var startSentryTimeM = Date()
@State private var endSentryTimeM = Date()
@State private var startSentryTimeT = Date()
@State private var endSentryTimeT = Date()
@State private var startSentryTimeW = Date()
@State private var endSentryTimeW = Date()
@State private var startSentryTimeTH = Date()
@State private var endSentryTimeTH = Date()
@State private var startSentryTimeF = Date()
@State private var endSentryTimeF = Date()
// @State private var startSentryTimeST = Date()
// @State private var endSentryTimeST = Date()
// @State private var startSentryTimeSN = Date()
// @State private var endSentryTimeSN = Date()
var body: some View {
VStack(alignment: .center) {
//星期一************
Toggle(isOn: $toggleStateM) {
HStack{
Spacer()
Text("Monday")
Spacer()
Text(" \(startSentryTimeM.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(endSentryTimeM.formatted(date: .omitted, time: .shortened))")
Spacer()
}
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
if toggleStateM{
HStack{
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeM, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeM, displayedComponents: .hourAndMinute)
.labelsHidden()
}
}
}
//星期二******************
Toggle(isOn: $toggleStateT) {
HStack{
Spacer()
Text("Tuesday")
Spacer()
Text(" \(startSentryTimeT.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(endSentryTimeT.formatted(date: .omitted, time: .shortened))")
Spacer()
}
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
if toggleStateT{
HStack{
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeT, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeT, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.leading, 20)
}
}
//星期三***************
Toggle(isOn: $toggleStateW) {
HStack{
Spacer()
}
Text("Wedsnesday")
Spacer()
Text(" \(startSentryTimeW.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(endSentryTimeW.formatted(date: .omitted, time: .shortened))")
Spacer()
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
if toggleStateW{
HStack{
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeW, displayedComponents: .hourAndMinute)
.labelsHidden()
}.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeW, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.leading, 20)
}
}
//星期四************
Toggle(isOn: $toggleStateTH) {
HStack{
Spacer()
Text("Thursday")
Spacer()
Text(" \(startSentryTimeTH.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(endSentryTimeTH.formatted(date: .omitted, time: .shortened))")
Spacer()
}
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
if toggleStateTH{
HStack{
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeTH, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeTH, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.leading, 20)
}
}
//星期五***************
Toggle(isOn: $toggleStateF) {
HStack{
Spacer()
Text("Friday ")
Spacer()
Text(" \(startSentryTimeF.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(endSentryTimeF.formatted(date: .omitted, time: .shortened))")
Spacer()
}
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
if toggleStateF{
HStack{
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeF, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeF, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.leading, 20)
}
}
//星期六******************
/* Toggle(isOn: $toggleStateST) {
Text("Saturday" )
}
.padding(.bottom, -5)
.padding(.leading, 15)
.padding(.trailing, 20)
if toggleStateM{
HStack{
VStack{
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeST, displayedComponents: .hourAndMinute)
.labelsHidden()
}.padding(.trailing, 20)
VStack{
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeST, displayedComponents: .hourAndMinute)
.labelsHidden()
}.padding(.leading, 20)
}
*/
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我已尝试将您的代码缩减为可管理的块,我编写的代码中可能存在错误。
我已将您个人的日子改为数据驱动,这样我们就可以重复视图,但具有不同的绑定
import SwiftUI
import Combine
class Sentry: ObservableObject {
@Published var isOn: Bool = false
let day: String
@Published var startTime: Date = Date()
@Published var finishTime: Date = Date()
init(isOn: Bool, day: String, startTime: Date = Date(), finishTime: Date = Date()) {
self.isOn = isOn
self.day = day
self.startTime = startTime
self.finishTime = finishTime
}
}
extension Sentry: Hashable {
static func == (lhs: Sentry, rhs: Sentry) -> Bool {
lhs.day == rhs.day
}
func hash(into hasher: inout Hasher) {
hasher.combine(self.day)
}
}
class Manager: ObservableObject {
var cancellables = Set<AnyCancellable>()
@Published var sentries: [Sentry] = []
init(sentries: [Sentry]) {
self.sentries = sentries
self.sentries.forEach({ sentry in
sentry.objectWillChange
.receive(on: DispatchQueue.main).sink { (_) in
self.objectWillChange.send()
}
.store(in: &cancellables)
})
}
}
struct TestView: View {
@EnvironmentObject var manager: Manager
var body: some View {
VStack(alignment: .center) {
ForEach(manager.sentries, id: \.self) { sentry in
ToggleSwitch(sentry: sentry)
if sentry.isOn {
DatePickers(sentry: sentry)
}
}
}
}
}
struct ToggleSwitch: View {
@ObservedObject var sentry: Sentry
var body: some View {
Toggle(isOn: $sentry.isOn) {
HStack{
Spacer()
Text(sentry.day)
Spacer()
Text(" \(sentry.startTime.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(sentry.finishTime.formatted(date: .omitted, time: .shortened))")
Spacer()
}
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
}
}
struct DatePickers: View {
@ObservedObject var sentry: Sentry
var body: some View {
HStack {
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $sentry.startTime, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $sentry.finishTime, displayedComponents: .hourAndMinute)
.labelsHidden()
}
}
}
}
struct TestView_Previews: PreviewProvider {
static var sentryMon = Sentry(isOn: true, day: "Monday")
static var sentryTue = Sentry(isOn: false, day: "Tuesday")
static var sentryWed = Sentry(isOn: false, day: "Wednesday")
static var sentryThu = Sentry(isOn: false, day: "Thrusday")
static var sentryFri = Sentry(isOn: false, day: "Friday")
static var sentrySat = Sentry(isOn: false, day: "Saturday")
static var sentrySun = Sentry(isOn: false, day: "Sunday")
static var previews: some View {
TestView()
.environmentObject(Manager(sentries: [sentryMon, sentryTue, sentryWed, sentryThu, sentryFri, sentrySat, sentrySun]))
}
}
这是问题所在
- 当重复切换超过 5 次时,代码会引发编译错误。
- 需要在不切换到关闭位置的情况下关闭选择器。
- 选择的开始和停止时间显示在切换栏中,但随后会重置
当前代码:不要笑得太厉害 ;-)
import SwiftUI
struct ContentView: View {
@State private var toggleStateM = false
@State private var toggleStateT = false
@State private var toggleStateW = false
@State private var toggleStateTH = false
@State private var toggleStateF = false
//@State private var toggleStateST = false
//@State private var toggleStateSN = false
@State private var startSentryTimeM = Date()
@State private var endSentryTimeM = Date()
@State private var startSentryTimeT = Date()
@State private var endSentryTimeT = Date()
@State private var startSentryTimeW = Date()
@State private var endSentryTimeW = Date()
@State private var startSentryTimeTH = Date()
@State private var endSentryTimeTH = Date()
@State private var startSentryTimeF = Date()
@State private var endSentryTimeF = Date()
// @State private var startSentryTimeST = Date()
// @State private var endSentryTimeST = Date()
// @State private var startSentryTimeSN = Date()
// @State private var endSentryTimeSN = Date()
var body: some View {
VStack(alignment: .center) {
//星期一************
Toggle(isOn: $toggleStateM) {
HStack{
Spacer()
Text("Monday")
Spacer()
Text(" \(startSentryTimeM.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(endSentryTimeM.formatted(date: .omitted, time: .shortened))")
Spacer()
}
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
if toggleStateM{
HStack{
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeM, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeM, displayedComponents: .hourAndMinute)
.labelsHidden()
}
}
}
//星期二******************
Toggle(isOn: $toggleStateT) {
HStack{
Spacer()
Text("Tuesday")
Spacer()
Text(" \(startSentryTimeT.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(endSentryTimeT.formatted(date: .omitted, time: .shortened))")
Spacer()
}
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
if toggleStateT{
HStack{
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeT, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeT, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.leading, 20)
}
}
//星期三***************
Toggle(isOn: $toggleStateW) {
HStack{
Spacer()
}
Text("Wedsnesday")
Spacer()
Text(" \(startSentryTimeW.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(endSentryTimeW.formatted(date: .omitted, time: .shortened))")
Spacer()
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
if toggleStateW{
HStack{
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeW, displayedComponents: .hourAndMinute)
.labelsHidden()
}.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeW, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.leading, 20)
}
}
//星期四************
Toggle(isOn: $toggleStateTH) {
HStack{
Spacer()
Text("Thursday")
Spacer()
Text(" \(startSentryTimeTH.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(endSentryTimeTH.formatted(date: .omitted, time: .shortened))")
Spacer()
}
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
if toggleStateTH{
HStack{
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeTH, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeTH, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.leading, 20)
}
}
//星期五***************
Toggle(isOn: $toggleStateF) {
HStack{
Spacer()
Text("Friday ")
Spacer()
Text(" \(startSentryTimeF.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(endSentryTimeF.formatted(date: .omitted, time: .shortened))")
Spacer()
}
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
if toggleStateF{
HStack{
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeF, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeF, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.leading, 20)
}
}
//星期六******************
/* Toggle(isOn: $toggleStateST) {
Text("Saturday" )
}
.padding(.bottom, -5)
.padding(.leading, 15)
.padding(.trailing, 20)
if toggleStateM{
HStack{
VStack{
Text("Sentry Start Time")
DatePicker("", selection: $startSentryTimeST, displayedComponents: .hourAndMinute)
.labelsHidden()
}.padding(.trailing, 20)
VStack{
Text("Sentry End Time")
DatePicker("", selection: $endSentryTimeST, displayedComponents: .hourAndMinute)
.labelsHidden()
}.padding(.leading, 20)
}
*/
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我已尝试将您的代码缩减为可管理的块,我编写的代码中可能存在错误。
我已将您个人的日子改为数据驱动,这样我们就可以重复视图,但具有不同的绑定
import SwiftUI
import Combine
class Sentry: ObservableObject {
@Published var isOn: Bool = false
let day: String
@Published var startTime: Date = Date()
@Published var finishTime: Date = Date()
init(isOn: Bool, day: String, startTime: Date = Date(), finishTime: Date = Date()) {
self.isOn = isOn
self.day = day
self.startTime = startTime
self.finishTime = finishTime
}
}
extension Sentry: Hashable {
static func == (lhs: Sentry, rhs: Sentry) -> Bool {
lhs.day == rhs.day
}
func hash(into hasher: inout Hasher) {
hasher.combine(self.day)
}
}
class Manager: ObservableObject {
var cancellables = Set<AnyCancellable>()
@Published var sentries: [Sentry] = []
init(sentries: [Sentry]) {
self.sentries = sentries
self.sentries.forEach({ sentry in
sentry.objectWillChange
.receive(on: DispatchQueue.main).sink { (_) in
self.objectWillChange.send()
}
.store(in: &cancellables)
})
}
}
struct TestView: View {
@EnvironmentObject var manager: Manager
var body: some View {
VStack(alignment: .center) {
ForEach(manager.sentries, id: \.self) { sentry in
ToggleSwitch(sentry: sentry)
if sentry.isOn {
DatePickers(sentry: sentry)
}
}
}
}
}
struct ToggleSwitch: View {
@ObservedObject var sentry: Sentry
var body: some View {
Toggle(isOn: $sentry.isOn) {
HStack{
Spacer()
Text(sentry.day)
Spacer()
Text(" \(sentry.startTime.formatted(date: .omitted, time: .shortened))")
Text("to")
Text(" \(sentry.finishTime.formatted(date: .omitted, time: .shortened))")
Spacer()
}
}
.frame(width: 350, height: 35, alignment: .center)
.padding(.leading, 20)
}
}
struct DatePickers: View {
@ObservedObject var sentry: Sentry
var body: some View {
HStack {
VStack(alignment: .center){
Text("Sentry Start Time")
DatePicker("", selection: $sentry.startTime, displayedComponents: .hourAndMinute)
.labelsHidden()
}
.padding(.trailing, 20)
VStack(alignment: .center){
Text("Sentry End Time")
DatePicker("", selection: $sentry.finishTime, displayedComponents: .hourAndMinute)
.labelsHidden()
}
}
}
}
struct TestView_Previews: PreviewProvider {
static var sentryMon = Sentry(isOn: true, day: "Monday")
static var sentryTue = Sentry(isOn: false, day: "Tuesday")
static var sentryWed = Sentry(isOn: false, day: "Wednesday")
static var sentryThu = Sentry(isOn: false, day: "Thrusday")
static var sentryFri = Sentry(isOn: false, day: "Friday")
static var sentrySat = Sentry(isOn: false, day: "Saturday")
static var sentrySun = Sentry(isOn: false, day: "Sunday")
static var previews: some View {
TestView()
.environmentObject(Manager(sentries: [sentryMon, sentryTue, sentryWed, sentryThu, sentryFri, sentrySat, sentrySun]))
}
}