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

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

新規登録して質問してみよう
ただいま回答率
85.49%
Swift

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

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

Q&A

解決済

2回答

2053閲覧

CollectionViewと連動してピン画像を変更させたい

Y_M

総合スコア265

Swift

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

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

0グッド

0クリップ

投稿2016/11/08 09:04

###前提・実現したいこと
タイトルの通りになります。
MapViewCollectionViewが連動する形の画面を作りたいと思っています。
その際、ピンタップ時および、collectionViewでページめくりした際に、
対象のアノテーションへズームし、ピン画像を指定したものに変えるというものです。

ページスクロール終了を検知したさいにcollectionView上の名前アノテーションのタイトルが一致した際に
ピンを変えようと思い処理を書いてみたのですがうまく画像が切り替わりません。

###補足情報(言語/FW/ツール等のバージョンなど)
Xcode7.3.1
Swift2.2

###該当のソースコード(抽出)

Swift

1func scrollViewDidEndDecelerating(scrollView: UIScrollView) { 2 if fmod(scrollView.contentOffset.x, scrollView.frame.maxX) == 0 { 3 currentPage = Int(scrollView.contentOffset.x / scrollView.frame.maxX) 4 for i in 0..<mapView.annotations.count { 5 if mapView.annotations[i].title! == data[currentPage]["name"] as? String { 6 let identifier = "annotation" 7 let annotationView = MKAnnotationView(annotation: self.mapView.annotations[i], reuseIdentifier: identifier) 8 annotationView.image = UIImage(named: "sample") 9 } 10 } 11 let span = MKCoordinateSpanMake(0.01, 0.01) 12 let coordinate = CLLocationCoordinate2DMake((data[currentPage]["latitude"] as? Double)! , (data[currentPage]["longitude"] as? Double)!) 13 let region = MKCoordinateRegionMake(coordinate, span) 14 mapView.setRegion(region, animated:true) 15 } 16 }

###該当のソースコード(全文)

Swift

1class ViewController2: UIViewController, MKMapViewDelegate, UICollectionViewDataSource { 2 3 @IBOutlet weak var mapView: MKMapView! 4 @IBOutlet weak var collectionView: UICollectionView! 5 6 private var beforePage = 0 7 private var currentPage = 0 8 var data: [[String:AnyObject?]] = [] 9 10 override func viewWillAppear(animated: Bool) { 11 super.viewWillAppear(animated) 12 self.navigationItem.title = "概要" 13 } 14 15 override func viewDidAppear(animated: Bool) { 16 super.viewDidAppear(animated) 17 alamoNetwork() 18 } 19 20 func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? { 21 22 let customAnnotation = annotation as! MapAnnotationSetting 23 24 let identifier = "annotation" 25 if let annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("annotation") { 26 return annotationView 27 } else { 28 if customAnnotation.pinImage != nil { 29 let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier) 30 annotationView.annotation = annotation 31 annotationView.canShowCallout = false 32 annotationView.image = UIImage(named: (customAnnotation.pinImage)!) 33 34 return annotationView 35 } else { 36 return nil 37 } 38 } 39 } 40 41 func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) { 42 for i in 0..<data.count { 43 let title = view.annotation?.title 44 if title! == data[i]["name"] as? String { 45 view.image = UIImage(named: "sample") 46 let span = MKCoordinateSpanMake(0.01, 0.01) 47 let coordinate = CLLocationCoordinate2DMake((data[i]["latitude"] as? Double)! , (data[i]["longitude"] as? Double)!) 48 let region = MKCoordinateRegionMake(coordinate, span) 49 mapView.setRegion(region, animated:true) 50 } 51 } 52 } 53 54 func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView) { 55 let customAnnotation = view.annotation as! MapAnnotationSetting 56 view.image = UIImage(named: (customAnnotation.pinImage)!) 57 } 58 59 func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 60 return data.count 61 } 62 63 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 64 let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! CustomCell 65 if data.count > 0 { 66 cell.shopName.text = data[indexPath.row]["name"] as? String 67 } 68 return cell 69 } 70 71 func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { 72 let width = collectionView.frame.width 73 let height = collectionView.frame.height 74 75 return CGSize(width: width, height: height) 76 } 77 78 func scrollViewWillBeginDragging(scrollView: UIScrollView) { 79 beforePage = Int(scrollView.contentOffset.x / scrollView.frame.maxX) 80 } 81 /* ーーーーーーーーこの部分に記載してありますーーーーーーーー*/ 82 func scrollViewDidEndDecelerating(scrollView: UIScrollView) { 83 if fmod(scrollView.contentOffset.x, scrollView.frame.maxX) == 0 { 84 currentPage = Int(scrollView.contentOffset.x / scrollView.frame.maxX) 85 for i in 0..<mapView.annotations.count { 86 if mapView.annotations[i].title! == data[currentPage]["name"] as? String { 87 let identifier = "annotation" 88 let annotationView = MKAnnotationView(annotation: self.mapView.annotations[i], reuseIdentifier: identifier) 89 annotationView.image = UIImage(named: "sample") 90 } 91 } 92 let span = MKCoordinateSpanMake(0.01, 0.01) 93 let coordinate = CLLocationCoordinate2DMake((data[currentPage]["latitude"] as? Double)! , (data[currentPage]["longitude"] as? Double)!) 94 let region = MKCoordinateRegionMake(coordinate, span) 95 mapView.setRegion(region, animated:true) 96 } 97 } 98 /* ーーーーーーーーーーーーここまでーーーーーーーーーーーー*/ 99 100 func dropPin() { 101 if self.data.count > 0 { 102 for i in 0..<data.count { 103 let latitude = self.data[i]["latitude"] as? Double 104 let longitude = self.data[i]["longitude"] as? Double 105 106 let annotation = MapAnnotationSetting() 107 annotation.coordinate = CLLocationCoordinate2DMake(latitude!, longitude!) 108 annotation.title = self.data[i]["name"] as? String 109 annotation.pinImage = "map_01" 110 111 mapView.addAnnotation(annotation) 112 } 113 mapView.showAnnotations(mapView.annotations, animated: true) 114 } 115 } 116 117 func alamoNetwork() { 118 ※省略※ 119 } 120 121} 122

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

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

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

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

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

guest

回答2

0

swift

1let annotationView = MKAnnotationView(annotation: self.mapView.annotations[i], reuseIdentifier: identifier)

これだと新しいAnnotationViewを作ってしまう(ような気がする)ので、

swift

1let annotationView = mapView.viewForAnnotation(mapView.annotations[i])

こんな感じにしないといけないんじゃないでしょうか?

投稿2016/11/09 01:11

fuzzball

総合スコア16731

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

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

Y_M

2016/11/09 01:45

想定していた動きになりました!が、 アノテーションはあるはずなのにnilが返ってきてクラッシュするようになりました。
Y_M

2016/11/09 01:52 編集

let annotationView = mapView.viewForAnnotation(mapView.annotations[i]) ここで取得した”annotationView”にnilが返ってくる場合があるみたいです。 だからといって"if let"でやってしまうと画像が変わらないですし。。。
fuzzball

2016/11/09 02:00

画面外に出ているときはnilになる(ことがある)んじゃないでしょうか?
Y_M

2016/11/09 02:10

そのとおりでした。 この場合画面外にいる場合でも"nil"にならないようにするには、 再利用しないようにすればよいのですかね。 (でも再利用しない設定なんてないですよね・・・)
fuzzball

2016/11/09 02:34 編集

nilだったときはとりあえずスルーしておいて、画面内に入ってきたときに呼ばれるviewForAnnotationの中で切り替えればいいのかな。(切り替えるというか"sample"をセットしてやる)
Y_M

2016/11/09 02:49

"viewForAnnotation"こちらは画面に入ってくる度呼ばれるものなのでしょうか。 "print"で検証したところ、最初の1回しか呼ばれていませんが。
Y_M

2016/11/09 02:55 編集

解決しました! ピンへのズームを最後に行っていたのを、 ピン画像を変える処理の前に持ってきたところうまく動作しました。 ズームで画面を移動し、アノテーション情報を再生成後に画像を変える。 ものすごく単純なことだったのかもしれません。。。
fuzzball

2016/11/09 03:03

見た目的にそれでいいなら、それが簡単でいいですね。 >>"viewForAnnotation"こちらは画面に入ってくる度呼ばれるものなのでしょうか。 nilになっているなら生成し直されるはずなので呼ばれると思いますよ。 (UITableViewのcellForRowAtIndexPathと同じだと思ってます)
Y_M

2016/11/09 03:12

>>nilになっているなら生成し直されるはずなので呼ばれると思いますよ。 想定していた動作にはなりましたが、そのあたりについても調査・検証したいと思います。 ご協力ありがとうございました。
guest

0

自己解決

Swift

1func scrollViewDidEndDecelerating(scrollView: UIScrollView) { 2 if fmod(scrollView.contentOffset.x, scrollView.frame.maxX) == 0 { 3 beforePage = currentPage 4 currentPage = Int(scrollView.contentOffset.x / scrollView.frame.maxX) 5 6/*--------------------------------------------------- これを先に持ってくる ---------------------------------------------------*/ 7 let span = MKCoordinateSpanMake(0.01, 0.01) 8 let coordinate = CLLocationCoordinate2DMake((data[currentPage]["latitude"] as? Double)! , (data[currentPage]["longitude"] as? Double)!) 9 let region = MKCoordinateRegionMake(coordinate, span) 10 mapView.setRegion(region, animated:true) 11/*------------------------------------------------------------------------------------------------------------------------------*/ 12 13 for i in 0..<mapView.annotations.count { 14 if mapView.annotations[i].title! == data[beforePage]["name"] as? String { 15 if let annotationView = mapView.viewForAnnotation(mapView.annotations[i]) { 16 annotationView.image = UIImage(named: "map_01") 17 } 18 } 19 if mapView.annotations[i].title! == data[currentPage]["name"] as? String { 20 if let annotationView = mapView.viewForAnnotation(mapView.annotations[i]) { 21 annotationView.image = UIImage(named: "sample") 22 } 23 } 24 } 25 } 26 }

投稿2016/11/09 02:58

Y_M

総合スコア265

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問