
下記のコードについて2点ほど質問があります。
現在出来ることは、予定の追加,編集,削除,予定のある日に印付ける(なぜか一度画面を消さないと、印が付かないです。),iOSカレンダーへの追加です。
文字数の関係で切った部分があり分かりにくくてすみません。
①開始時間の早い予定を前にしたいのです。現在は予定を書いた順に表示されます。
②日を跨ぐ開始時間と終了時間を設定した場合、表示された予定がその通りに表示されるようにしたいです。自分で考えると削除や編集の時に通用しなくなってしまいます。
2つの質問、そして長いコード失礼します。お力をお貸しいただければと思います。
よろしくお願いします。
Swift
1import SwiftUI 2import FSCalendar 3import CalculateCalendarLogic 4import EventKit 5 6struct CalendarPage:View{ 7 @State var show:Bool=false 8 @State var show2:Bool=false 9 @State var isSheet:Bool=false 10 @State var selectedDate=Date() 11 @State var array:[Date] 12 @State var n=0 13 @State var m1=Date() 14 @State var m2=Date() 15 @State var sortarrays:[Sortarray] 16 var body: some View{ 17 ScrollView{ 18 Calendarpage(selectedDate:$selectedDate,array:$array) 19 Text(selectedDate,style:.date).padding() 20 Button(action:{self.show=true;m1=selectedDate;m2=selectedDate}){ Text("+")}.sheet(isPresented:self.$show){SecondView(show:$show,selectedDate:$selectedDate,array:$arraynewsta,rt:$m1,newfinish:$m2,sortarrays:$sortarrays)} 21 if(array.count==0){ 22 } 23 else{ 24 ForEach(0..<array.count, id:\.self){index in 25 if(equals(array[index], selectedDate)){ 26 Text("\(sortarrays[index].arraystart,style:.time)〜\(sortarrays[index].arrayfinish,style:.time)") 27 Button(action: {isSheet=true}) {Text("削除")}.actionSheet(isPresented: $isSheet) { ActionSheet(title: Text("この予定を削除しますか?"), buttons: [.destructive(Text("削除"), action:{remove(index)}),.cancel(Text("キャンセル"), action: {})])} 28 Button(action:{self.show2 = true;n=index}){Text("編集")}.sheet(isPresented:self.$show2){HenshuView(show2:$show2,selectedDate:$selectedDate,array:$array,index:$n,newtitle:$arraytitle[index],newmemo:$arraymemo[index],newstart:$arraystart[index],newfinish:$arrayfinish[index],sortarrays:$sortarrays)} 29 Text("\(sortarrays[index].arraytitle)") 30 Text("\(sortarrays[index].arraymemo)") 31 } 32 } 33 } 34 } 35 } 36 init(){ 37 UIDatePicker.appearance().minuteInterval=5 38 let a=UserDefaults.standard.array(forKey:"key") as? [Date] ?? [] 39 let sort=UserDefaults.standard.array(forKey:"sortkey") as? [Sortarray] ?? [] 40 _array=State(initialValue:a) 41 _sortarrays=State(initialValue:sort) 42 } 43 func equals(_ date1:Date, _ date2:Date)->Bool{ 44 let calendar = Calendar.current 45 let components1=calendar.dateComponents([.year,.month,.day],from:date1) 46 let components2=calendar.dateComponents([.year,.month,.day],from:date2) 47 let result = components1 == components2 48 return result 49 } 50 func remove(_ n:Int){ 51 array.remove(at:n); 52 sortarrays.remove(at:n) 53 UserDefaults.standard.set(array,forKey:"key") 54 UserDefaults.standard.set(array,forKey:"sortkey") 55 } 56} 57struct Sortarray:Codable{ 58 var arraytitle:String 59 var arraymemo:String 60 var arraystart:Date 61 var arrayfinish:Date 62} 63struct SecondView: View{ 64 @Binding var show:Bool 65 @Binding var selectedDate:Date 66 @Binding var array:[Date] 67 @Binding var newstart:Date 68 @Binding var newfinish:Date 69 @Binding var sortarrays:[Sortarray] 70 @State var newtitle="" 71 @State var newmemo="" 72 let eventStore=EKEventStore() 73 var body: some View { 74 VStack { 75 Button(action:{addEvent();save();self.show.toggle()}){Text("保存")} 76 TextField("タイトル",text:$newtitle) 77 Text("メモ") 78 TextEditor(text:$newmemo) 79 DatePicker("開始時間",selection:$newstart) 80 DatePicker("終了時間",selection:$newfinish) 81 } 82 .onAppear(perform:self.allowAuthorization) 83 } 84 func allowAuthorization(){ 85 if getAuthorization_status(){ 86 return 87 }else{ 88 eventStore.requestAccess(to:.event,completion:{(granted, error) in 89 if granted{ 90 return 91 } 92 }) 93 } 94 } 95 func getAuthorization_status()->Bool{ 96 let status=EKEventStore.authorizationStatus(for:.event) 97 switch status { 98 case .notDetermined: 99 print("NotDetermined") 100 return false 101 case .denied: 102 print("Denied") 103 return false 104 case .authorized: 105 print("Authorized") 106 return true 107 case .restricted: 108 print("Restricted") 109 return false 110 @unknown default: 111 literalExpression() 112 fatalError("カレンダーの認証部分でエラー @unknown default") 113 } 114 } 115 func addEvent(){ 116 let defaultCalendar=eventStore.defaultCalendarForNewEvents 117 let event=EKEvent(eventStore:eventStore) 118 event.title=newtitle 119 event.notes=newmemo 120 event.startDate=newstart 121 event.endDate=newfinish 122 event.calendar=defaultCalendar 123 do{try eventStore.save(event, span:.thisEvent) 124 } catch let error{print(error)} 125 } 126 func literalExpression(){ 127 print("__FILE__",#file) 128 print("__LINE__",#line) 129 print("__COLUMN__",#column) 130 print("__FUNCTION__",#function) 131 } 132 func save(){ 133 let encoder=JSONEncoder() 134 let ej=Sortarray(arraytitle:newtitle,arraymemo:newmemo,arraystart:newstart,arrayfinish:newfinish) 135 if let encodedValue=try? encoder.encode(ej){ 136 sortarrays.append(ej) 137 UserDefaults.standard.set(encodedValue,forKey:"sortkey") 138 } 139 array.append(selectedDate); 140 UserDefaults.standard.set(array,forKey:"key") 141 } 142} 143struct HenshuView: View{ 144 @Binding var show2:Bool 145 @Binding var selectedDate:Date 146 @Binding var array:[Date] 147 @Binding var index:Int 148 @Binding var newtitle:String 149 @Binding var newmemo:String 150 @Binding var newstart:Date 151 @Binding var newfinish:Date 152 @Binding var sortarrays:[Sortarray] 153 let eventStore=EKEventStore() 154 var body: some View{ 155 Button(action:{addEvent();saveremove(index);self.show2.toggle()}){Text("保存")} 156 TextField("タイトル",text:$newtitle) 157 Text("メモ") 158 TextEditor(text:$newmemo) 159 DatePicker("開始時間",selection:$newstart) 160 DatePicker("終了時間",selection:$newfinish) 161 } 162 func saveremove(){ 163 let encoder=JSONEncoder() 164 let ej=Sortarray(arraytitle:newtitle,arraymemo:newmemo,arraystart:newstart,arrayfinish:newfinish) 165 if let encodedValue=try? encoder.encode(ej){ 166 sortarrays.append(ej) 167 UserDefaults.standard.set(encodedValue,forKey:"sortkey") 168 } 169 array.append(selectedDate); 170 array.remove(at:n); 171 sortarrays.remove(at:n) 172 UserDefaults.standard.set(array,forKey:"key") 173 UserDefaults.standard.set(array,forKey:"sortkey") 174 } 175 func addEvent(){ 176 let defaultCalendar=eventStore.defaultCalendarForNewEvents 177 let event=EKEvent(eventStore: eventStore) 178 event.title=newtitle 179 event.notes=newmemo 180 event.startDate=newstart 181 event.endDate=newfinish 182 event.calendar=defaultCalendar 183 do{try eventStore.save(event,span:.thisEvent) 184 }catch let error{print(error)} 185 } 186} 187struct Calendarpage: UIViewRepresentable{ 188 @Binding var selectedDate:Date 189 @Binding var array:[Date] 190 func makeUIView(context:Context)->UIView{ 191 typealias UIViewType=FSCalendar 192 let fsCalendar=FSCalendar() 193 fsCalendar.delegate=context.coordinator 194 fsCalendar.dataSource=context.coordinator 195 return fsCalendar 196 } 197 func updateUIView(_ uiView:UIView,context:Context){ 198 } 199 func makeCoordinator()->Coordinator{ 200 return Coordinator(self,array:$array) 201 } 202 class Coordinator: NSObject,FSCalendarDelegateAppearance, FSCalendarDataSource{ 203 @Binding var array:[Date] 204 var parent:Calendarpage 205 init(_ parent:Calendarpage,array:Binding<[Date]>){ 206 self.parent=parent 207 self._array=array 208 } 209 func calendar(_ calendar:FSCalendar,didSelect date:Date,at monthPosition:FSCalendarMonthPosition){ 210 parent.selectedDate=date 211 } 212 func calendar(_ calendar:FSCalendar,numberOfEventsFor date:Date)->Int{ 213 if array.contains(date){ 214 return 1 215 } else { 216 return 0 217 } 218 } 219 } 220}

数日の間に随分コードが進化しましたね。
> ①開始時間の早い予定を前にしたいのです。現在は予定を書いた順に表示されます。
DateやStringを個別の配列にして扱うのはちょっと大変になってきたように思います。
structにまとめて、structの配列にした方が扱いやすいと思いました。
それからstructをソートすると良いと思います。
https://developer.apple.com/documentation/swift/array/sort(by:)
②はちょっとまだ自分の理解が追いついていません・・
もうちょっとお待ちください・・
ご返答ありがとうございます!
毎回本当にxg63ex2bさんに助けられています。
今回も私の質問に真摯に向き合っていただき感謝しております。
①への解決方法ありがとうございます。
構造体配列に予定を追加することは出来たようですが、記入後は表示されるものの、一度アプリを閉じると表示がされない事態が起こりました。
解決に時間がかかるかもしれないので、現時点でのコードを質問文で記載します。
上手くいったり変化すれば、また新しく修正します。
面倒くさい問題を投げかけてしまいすみません。
いつまでも待ちますので、気にしないでください!
考えていただけるだけで感謝ですので。
回答1件