質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
変数

変数は、プログラミングにおいて値や文字列などのデータを保持できる仕組みを指します。自由に名前を付けることができるため、管理しやすくなるのが特徴です。プログラムで変数の宣言を行い、値を代入して利用。保持したデータが通用する範囲でローカル変数とグローバル変数に分けられます。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1227閲覧

swift nilエラーの解消法が分かりません…

KaoruYoshida

総合スコア36

変数

変数は、プログラミングにおいて値や文字列などのデータを保持できる仕組みを指します。自由に名前を付けることができるため、管理しやすくなるのが特徴です。プログラムで変数の宣言を行い、値を代入して利用。保持したデータが通用する範囲でローカル変数とグローバル変数に分けられます。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2022/05/04 02:26

前提

Calendarを表示し、選択日と今日の日付の差を取り出すシステムを作っております。
取り出す値はdate型で、それをString型、そしてInt型に変換した後、引き算をしています。
その後、Textとして表示させるためにString型に変換しています。

Calendarには、FSCalendarというライブラリを用いています。

実現したいこと

  • 選択日をInt型で取り出せるようにしたい
  • 選択日の変数がnilにならないようにしたい

発生している問題・エラーメッセージ

選択日をdate型で取り出し、String型に変換した後、Int型に変換する際のコードで以下のようなnilエラーになってしまう。

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

おそらく、ページを読み込んだ時点ではまだ選択されていないため、選択日が存在せずnilだと認識されてしまうから起こるエラーだと思っています。

そこで疑問なのが、

func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) { //date -> string let selecteddate = dateFormatter.string(from: date) selectedDate = selecteddate } let selectedInt:Int = Int(selectedDate)!//ここでエラー let differ = selectedInt-todayInt let differString:String = String(differ)

の居場所が分からない。
struct CalendarTestViewの中なのか??
SwiftUI初心者なので、理由含め教えてくだされば幸いです。

全体のコードはこちらです↓

該当のソースコード

変数は、

今日の
date型:dt
String型:todayString
Int型:todayInt

選択日の
date型:date
String型:selectedString
Int型:selectedInt

(選択日)ー(今日)はInt型のdifferという変数で表しています。

SwiftUI

1import SwiftUI 2import FSCalendar 3import UIKit 4 5struct CalendarTestView: UIViewRepresentable { 6 7 func makeUIView(context: Context) -> UIView { 8 9 typealias UIViewType = FSCalendar 10 11 let fsCalendar = FSCalendar() 12 13 fsCalendar.delegate = context.coordinator 14 fsCalendar.dataSource = context.coordinator 15 16 return fsCalendar 17 } 18 19 func updateUIView(_ uiView: UIView, context: Context) { 20 } 21 22 func makeCoordinator() -> Coordinator{ 23 return Coordinator(self) 24 } 25 26 class Coordinator: NSObject, FSCalendarDelegate, FSCalendarDataSource { 27 var parent:CalendarTestView 28 29 init(_ parent:CalendarTestView){ 30 self.parent = parent 31 } 32 } 33} 34//残り日数の処理 35var dateFormatter: DateFormatter { 36 let dateFormatter = DateFormatter() 37 dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "D", options: 0, locale: Locale(identifier: "en_US")) 38 39 return dateFormatter 40} 41let dt = Date() 42let todayString = dateFormatter.string(from: dt) 43let todayInt:Int = Int(todayString)! 44 45var selectedDate: String = "date" 46func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) { 47 //date -> string 48 let selecteddate = dateFormatter.string(from: date) 49 print(selecteddate) 50 51 selectedDate = selecteddate 52} 53let selectedInt:Int = Int(selectedDate)!//ここでnilエラーが出てしまう 54let differ = selectedInt-todayInt 55let differString:String = String(differ) 56 57 58struct CalendarApealView: View { 59 @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode> 60 61 var body: some View { 62 VStack(){ 63 Text("When did you start this food style?") 64 .font(.title2) 65 CalendarTestView() 66 Text(differString) 67 .font(.title) 68 .padding() 69 Button(action: { 70 self.presentationMode.wrappedValue.dismiss() 71 }) { 72 Text("confirm") 73 .font(.title2) 74 .padding(15) 75 .background(Color.green) 76 .foregroundColor(Color.white) 77 .cornerRadius(10) 78 } 79 } 80 } 81} 82 83struct CalendarTestView_Previews: PreviewProvider { 84 static var previews: some View { 85 CalendarApealView() 86 } 87}

補足情報(FW/ツールのバージョンなど)

macOS バージョン12.3.1
2.6 GHz 6コアIntel Core i7
Xcodeバージョン13.3.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

の居場所が分からない。
struct CalendarTestViewの中なのか??

func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition)
このメソッドはFSCalendarDelegateプロトコルで定義されているものですので、
class Coordinatorの中に記述すると良いと思います。
デリゲートメソッドですので、カレンダーの日付を選択すると都度このメソッドを呼び出してくれます。

その他のletやvarの定義はCalendarApealViewかCalendarTestViewの適切な方に記述すると良いと思います。

選択日をInt型で取り出せるようにしたい
選択日の変数がnilにならないようにしたい

StringやIntの型のプロパティは
プロパティとして値を保持しておく必要はなさそうに感じましたので、
以下、differStringは都度計算した値を返す感じで書いてみました。
(// *****の付近が主な修正ポイントです)

swift

1import SwiftUI 2import FSCalendar 3import UIKit 4 5struct CalendarTestView: UIViewRepresentable { 6 // ***** @Bindingで呼び出し側のビューに変更を渡せるようにします 7 @Binding var selectedDate: Date 8 func makeUIView(context: Context) -> UIView { 9 10 typealias UIViewType = FSCalendar 11 12 let fsCalendar = FSCalendar() 13 14 fsCalendar.delegate = context.coordinator 15 fsCalendar.dataSource = context.coordinator 16 17 return fsCalendar 18 } 19 20 func updateUIView(_ uiView: UIView, context: Context) { 21 } 22 23 func makeCoordinator() -> Coordinator{ 24 return Coordinator(self) 25 } 26 27 class Coordinator: NSObject, FSCalendarDelegate, FSCalendarDataSource { 28 var parent:CalendarTestView 29 30 init(_ parent:CalendarTestView){ 31 self.parent = parent 32 } 33 34 func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) { 35 // ***** 選択した日付をバインディングのselectedDateへ設定します 36 parent.selectedDate = date 37 } 38 } 39} 40 41struct CalendarApealView: View { 42 @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode> 43 // ***** @StateでCalendarApealViewの中に日付を保持します 44 @State private var date: Date = Date() 45 // ***** 日付の差を計算するためのプロパティです(dateプロパティが変わると随時動きます) 46 var differString: String { 47 let calendar = Calendar.current 48 let today1 = Date() 49 let today2 = calendar.dateComponents([.year, .month, .day], from: today1) 50 let today3 = calendar.date(from: DateComponents(year: today2.year, month: today2.month, day: today2.day))! 51 let date2 = calendar.dateComponents([.year, .month, .day], from: date) 52 let date3 = calendar.date(from: DateComponents(year: date2.year, month: date2.month, day: date2.day))! 53 let result = calendar.dateComponents([.day], from: today3, to: date3) 54 return "\(result.day!)" 55 } 56 var body: some View { 57 VStack(){ 58 Text("When did you start this food style?") 59 .font(.title2) 60 // ***** $dateと記述することでCalendarTestViewの中で変更された日付をdateプロパティで受け取れます 61 CalendarTestView(selectedDate: $date) 62 Text(differString) 63 .font(.title) 64 .padding() 65 Button(action: { 66 self.presentationMode.wrappedValue.dismiss() 67 }) { 68 Text("confirm") 69 .font(.title2) 70 .padding(15) 71 .background(Color.green) 72 .foregroundColor(Color.white) 73 .cornerRadius(10) 74 } 75 } 76 } 77} 78 79struct CalendarTestView_Previews: PreviewProvider { 80 static var previews: some View { 81 CalendarApealView() 82 } 83}

SwiftUIのチュートリアルも参照してみると良いかもしれません。
https://developer.apple.com/tutorials/swiftui/creating-and-combining-views

投稿2022/05/04 07:12

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KaoruYoshida

2022/05/04 10:12

ご回答ありがとうございます!解決いたしました。 丁寧に指摘くださり、本当に助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問