前提・実現したいこと
初心者から始める日めくりカレンダーアプリの作り方という動画を見ながら、アプリを作成しています。
カレンダーから今日の日付を取ってきて年月日を表示
曜日によって異なる画像を表示し、土曜日と日曜日は文字色が黒から変わる
指を上下に向かってスライドするとカレンダーがめくれる
という主な仕様をもつ日めくりカレンダーです。
発生している問題・エラーメッセージ
動画の2つ目まで実装したのですが、ViewController.swiftにおいて以下のエラーが表示され、Sumilatorでは真っ白な画面に何も表示されず、曜日に応じた画像が読み込めません。
①28行目
swift
1images = [UIImage(named:"sunday.png")!, UIImage(named:"monday.png")!, UIImage(named:"tuesday.png")!, UIImage(named:"wednesday.png")!, UIImage(named:"thursday.png")!, UIImage(named:"friday.png")!,UIImage(named:"saturday.png")!]
に対して
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
②85、86行目
swift
1 imageView.image = images[weekDay-1] as? UIImage 2 weekdayLabel.text = weekDays[weekDay-1] as? String
の2行のコードに対して、それぞれ
Value of optional type 'Int?' must be unwrapped to a value of type 'Int' Coalesce using '??' to provide a default when the optional value contains 'nil' Force-unwrap using '!' to abort execution if the optional value contains 'nil'
該当のソースコード
ViewController.swift
swift
1import UIKit 2 3class ViewController: UIViewController { 4 5 @IBOutlet var yearLabel:UILabel! 6 @IBOutlet var monthLabel:UILabel! 7 @IBOutlet var dayLabel:UILabel! 8 @IBOutlet var imageView:UIImageView! 9 @IBOutlet var weekdayLabel:UILabel! 10 11 var images: [UIImage] = [] 12 var weekDays: [String] = [] 13 14 var dayCount = 0; 15 16 override func viewDidLoad() { 17 super.viewDidLoad() 18 // Do any additional setup after loading the view, typically from a nib. 19 20 images = [UIImage(named:"sunday.png")!, UIImage(named:"monday.png")!, UIImage(named:"tuesday.png")!, UIImage(named:"wednesday.png")!, UIImage(named:"thursday.png")!, UIImage(named:"friday.png")!,UIImage(named:"saturday.png")!] 21 22 23 weekDays = ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"] 24 25 showDate() 26 27 //actions 28 let leftSwipe = UISwipeGestureRecognizer(target: self, action: Selector(("prevDay"))) 29 leftSwipe.direction = .left 30 self.view.addGestureRecognizer(leftSwipe) 31 32 let rightSwipe = UISwipeGestureRecognizer(target: self, action: Selector(("nextDay"))) 33 rightSwipe.direction = .right 34 self.view.addGestureRecognizer(rightSwipe) 35 36 let upSwipe = UISwipeGestureRecognizer(target: self, action: Selector(("nextvDay"))) 37 leftSwipe.direction = .up 38 self.view.addGestureRecognizer(upSwipe) 39 40 let downSwipe = UISwipeGestureRecognizer(target: self, action: Selector(("prevDay"))) 41 rightSwipe.direction = .down 42 self.view.addGestureRecognizer(downSwipe) 43 44 45 } 46 47 func showDate(){ 48 //count seconds to date 49 let seconds = TimeInterval(dayCount*24*60*60) 50 //date and time 51 let now = NSDate(timeIntervalSinceNow: seconds) 52 53 let dateFormatter = DateFormatter() 54 //place 55 dateFormatter.locale = NSLocale(localeIdentifier:"ja_JP") as Locale? 56 57 dateFormatter.dateFormat = "yyyy" 58 let year = dateFormatter.string(from: now as Date) 59 yearLabel.text = year 60 61 dateFormatter.dateFormat = "M" 62 let month = dateFormatter.string(from: now as Date) 63 monthLabel.text = month 64 65 dateFormatter.dateFormat = "d" 66 let day = dateFormatter.string(from: now as Date) 67 dayLabel.text = day 68 69 //aquire current calendar 70 let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)! //現在のカレンダー 71 let weekComponent = calendar.components(.weekday, from: now as Date) 72 let weekDay = weekComponent.weekday //曜日 73 74 imageView.image = images[weekDay-1] as? UIImage 75 weekdayLabel.text = weekDays[weekDay-1] as? String 76 77 /* 78 imageView.image = images[Int(day)!-1] as? UIImage 79 weekdayLabel.text = weekDays[weekDay!-1] as? String 80 */ 81 82 switch(weekDay){ 83 //日曜日は文字色赤 84 case 1: 85 dayLabel.textColor = UIColor.red 86 weekdayLabel.textColor = UIColor.red 87 //土曜日は文字色青 88 case 7: 89 dayLabel.textColor = UIColor.blue 90 weekdayLabel.textColor = UIColor.blue 91 //他は黒 92 default: 93 dayLabel.textColor = UIColor.black 94 weekdayLabel.textColor = UIColor.black 95 96 } 97 } 98 99 //back to the previous date 100 func prevDay(){ 101 dayCount -= 1 102 UIView.beginAnimations("TransitionAnimation", context: nil) 103 UIView.setAnimationTransition(UIViewAnimationTransition.curlDown, for: self.view, cache: true) 104 UIView.setAnimationDuration(1) 105 showDate() 106 UIView.commitAnimations() //how to change UI 107 } 108 109 func nextDay(){ 110 dayCount += 1 111 UIView.beginAnimations("TransitionAnimation", context: nil) 112 UIView.setAnimationTransition(UIViewAnimationTransition.curlUp, for: self.view, cache: true) 113 UIView.setAnimationDuration(1) 114 showDate() 115 UIView.commitAnimations() 116 } 117 118 override func didReceiveMemoryWarning() { 119 super.didReceiveMemoryWarning() 120 // Dispose of any resources that can be recreated. 121 } 122 123 124} 125 126
試したこと
元のプログラムは、【動作環境】Swift2.0 Xcode7.0を想定されているため、
実装でもSwift UIなどは使わない設定にしましたが
他にもXcode内で自動修正される部分がありました。
###回答を受けて追記
②について
//aquire current calendar let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)! //現在のカレンダー let weekComponent = calendar.components(.weekday, from: now as Date) let weekDay = weekComponent.weekday // 曜日 if let weekDay = weekComponent.weekday{ //if文内なら、weekDayはInt型 imageView.image = images[weekDay-1] as? UIImage weekdayLabel.text = weekDays[weekDay-1] as? String }else{ //weekComponent.weekday == nil の場合の処理 }
と変更し、フォルダ配下とAssets.xcassetsの両方に7枚の画像を置きましたが
なぜか1枚だけ見つからないとのエラーが出ました。
error: Build input file cannot be found: '/Users/username/Desktop/iPhoneApp/day_by_day_calender/saturday.png'
スクリーンショットのように、saturday.png
も置いてあり、サイズも他の画像とほとんど同じ容量です。
補足情報(FW/ツールのバージョンなど)
Xcode Version 11.1
Apple Swift version 5.1
回答3件
あなたの回答
tips
プレビュー