MapViewを使い、現在地で撮った写真をPinの画像にするフォトアルバムを作ろうとしています。
pickerViewで写真を撮った後に画像の配列に写真を入れて、それをPinの画像にしようとしています。
コードは以下のようにしました。
PickerViewを起動し、写真を撮るまではOKなのですが、撮り終わった後に
fatal error: Index out of range
というエラーメッセージで落ちてしまいます。
おそらく画像をUIimageの配列に入れる処理が悪いのだと思うのですが
解決方法が分かりません。
修正するヒントなどありましたら教えていただければと思います。
MapViewController.swift
1import UIKit 2import CoreLocation 3import MapKit 4 5class MapViewController: UIViewController { 6 7 @IBOutlet weak var mapView: MKMapView! 8 @IBOutlet weak var locationLabel: UILabel! 9 10 var locationManager = CLLocationManager() 11 var locationData:CLLocation? 12 var imageArray: Array<UIImage> = Array<UIImage>() 13 14 override func viewDidLoad() { 15 super.viewDidLoad() 16 17 //ロケーションの状態表示を使用不可にしておく 18 disableLocationLabel() 19 20 locationManager.desiredAccuracy = kCLLocationAccuracyBest 21 locationManager.distanceFilter = 1.0 22 mapView.setUserTrackingMode(.follow, animated: true) 23 24 locationManager.delegate = self 25 mapView.delegate = self 26 mapView.showsScale=true 27 } 28 29 override func didReceiveMemoryWarning() { 30 super.didReceiveMemoryWarning() 31 } 32 33 //画面呼び出し後のメソッド 34 override func viewDidAppear(_ animated: Bool) { 35 36 if(CLLocationManager.locationServicesEnabled() == true){ 37 switch CLLocationManager.authorizationStatus() { 38 39 //未設定の場合 40 case CLAuthorizationStatus.notDetermined: 41 locationManager.requestWhenInUseAuthorization() 42 43 //機能制限されている場合 44 case CLAuthorizationStatus.restricted: 45 alertMessage(message: "位置情報サービスの利用が制限されている利用できません。「設定」⇒「一般」⇒「機能制限」") 46 47 //「許可しない」に設定されている場合 48 case CLAuthorizationStatus.denied: 49 alertMessage(message: "位置情報の利用が許可されていないため利用できません。「設定」⇒「プライバシー」⇒「位置情報サービス」⇒「アプリ名」") 50 51 //「このAppの使用中のみ許可」に設定されている場合 52 case CLAuthorizationStatus.authorizedWhenInUse: 53 //位置情報の取得を開始する。 54 locationManager.startUpdatingLocation() 55 56 //「常に許可」に設定されている場合 57 case CLAuthorizationStatus.authorizedAlways: 58 //位置情報の取得を開始する。 59 locationManager.startUpdatingLocation() 60 } 61 62 } else { 63 //位置情報サービスがOFFの場合 64 alertMessage(message: "位置情報サービスがONになっていないため利用できません。「設定」⇒「プライバシー」⇒「位置情報サービス」") 65 } 66 } 67 68 //表示を使用不可に変更 69 func disableLocationLabel(){ 70 locationLabel.text = "GPSが使用許可になっていません" 71 } 72 73 //警告アラートを表示 74 func alertMessage(message:String) { 75 let aleartController = UIAlertController(title: "注意", message: message, preferredStyle: .alert) 76 let defaultAction = UIAlertAction(title:"OK", style: .default, handler:nil) 77 aleartController.addAction(defaultAction) 78 79 present(aleartController, animated:true, completion:nil) 80 } 81 82 //写真ボタンを押した時 83 @IBAction func takePhoto(_ sender: UIButton) { 84 85 //カメラが使えるか確認する 86 if UIImagePickerController.isSourceTypeAvailable(.camera){ 87 //ImagePickerを表示する 88 let cameraPicker = UIImagePickerController() 89 cameraPicker.sourceType = UIImagePickerControllerSourceType.camera 90 cameraPicker.delegate = self 91 self.present(cameraPicker, animated: true, completion: nil) 92 } 93 } 94 95 //戻るボタンを押した時 96 @IBAction func backButton(_ sender: UIButton) { 97 self.dismiss(animated: true, completion: nil) 98 } 99} 100 101//MARK: CLLocationManagerDelegate 102extension MapViewController:CLLocationManagerDelegate{ 103 104 //位置情報が更新された時に呼ばれる 105 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 106 107 //Locationの最後の値を取り出す 108 locationData = locations.last 109 110 //緯度 111 if var ido = locationData?.coordinate.latitude{ 112 ido = round(ido * 1000000)/1000000 113 } 114 //経度 115 if var keido = locationData?.coordinate.longitude{ 116 keido = round(keido * 1000000)/1000000 117 } 118 //標高 119 if var hyoukou = locationData?.altitude{ 120 hyoukou = round(hyoukou*100)/100 121 } 122 123 //MAP中央の座標 124 let center = CLLocationCoordinate2D(latitude: (locationData?.coordinate.latitude)!, longitude: (locationData?.coordinate.longitude)!) 125 126 //地図のセンターに設定する 127 mapView.setCenter(center, animated: true) 128 129 //ロケーション表示(デバッグ用) 130 locationLabel.text = "GPS:\(center.latitude) \(center.longitude)" 131 132 //500m四方を表示する 133 let myRegion : MKCoordinateRegion = MKCoordinateRegionMakeWithDistance(center, 500, 500) 134 mapView.setRegion(myRegion, animated: true) 135 136 } 137 138 //位置情報のステータスが変わった時 139 func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { 140 141 switch status{ 142 //利用許可に変更された 143 case .authorizedAlways,.authorizedWhenInUse: 144 locationManager.startUpdatingLocation() 145 //利用不可に変更された 146 case .denied: 147 locationManager.stopUpdatingLocation() 148 disableLocationLabel() 149 150 default://制限されているか、ユーザーが決定していない、その他 151 //ロケーションの更新を停止する 152 locationManager.stopUpdatingLocation() 153 154 //トラッキングモードをnoneにする 155 mapView.setUserTrackingMode(.none, animated: true) 156 disableLocationLabel() 157 } 158 } 159} 160 161//MapViewのDelegate 162extension MapViewController:MKMapViewDelegate{ 163 164 //ピンを表示する時の処理 165 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 166 167 // 現在地は外す 168 if annotation is MKUserLocation { 169 return nil 170 } 171 172 let pinID = "PIN" 173 var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: pinID) as? MKPinAnnotationView 174 //Annotationが見つからなかった場合は新しく作成 175 if annotationView == nil { 176 annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: pinID) 177 178 let size: CGSize = CGSize(width: 42, height: 42) 179 180 //写真を描画する 181 UIGraphicsBeginImageContext(size) 182 183 imageArray[Int(annotation.title!!)!].draw(in: CGRect(x:0, y:0, width : size.width,height: size.height)) 184 let resizeImage = UIGraphicsGetImageFromCurrentImageContext() 185 UIGraphicsEndImageContext() 186 187 annotationView?.image = resizeImage 188 189 //タップした時に吹き出しが表示されるようにする 190 annotationView?.canShowCallout = true 191 annotationView?.rightCalloutAccessoryView = UIButton(type: UIButtonType.detailDisclosure) 192 193 } else { 194 annotationView!.annotation = annotation 195 } 196 return annotationView 197 } 198 199 //吹き出しをタップした時に呼ばれる 200 //画像を表示するように遷移する 201 func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { 202 //画面遷移 203 204 //Annotationを非選択にしてColloutを非表示にする 205 mapView.deselectAnnotation(view.annotation, animated: true) 206 } 207} 208 209//Pickerコントローラー 210extension MapViewController:UIImagePickerControllerDelegate{ 211 //写真を撮り終わった後の処理 212 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { 213 if let pickerImage = info[UIImagePickerControllerOriginalImage] as? UIImage{ 214 //画像用の配列に入れる 215 imageArray.append(pickerImage) 216 } 217 218 self.dismiss(animated: true, completion: nil) 219 220 //最後に取得した位置でCLLocationCoordinate2Dを作成する 221 let center : CLLocationCoordinate2D = CLLocationCoordinate2DMake((locationData?.coordinate.latitude)!, (locationData?.coordinate.longitude)!) 222 mapView.setCenter(center, animated: true) 223 224 225 let pin : MKPointAnnotation = MKPointAnnotation() 226 pin.coordinate = center 227 pin.title = "\(mapView.annotations.count)" 228 pin.subtitle = "\(String(describing: locationData?.coordinate.latitude )),\(String(describing: locationData?.coordinate.longitude))" 229 mapView.addAnnotation(pin) 230 } 231 232 //Pickerイメージでキャンセルされた時 233 func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 234 self.dismiss(animated: true, completion: nil) 235 } 236} 237 238// 239extension MapViewController:UINavigationControllerDelegate{ 240 241} 242 243
回答5件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。