2017-03-13 8 views
5

私は自分でSwift 3を学習しています。現在の学習プロジェクトでは、ユーザーが写真をスナップし、現在の場所を固定してマップスナップショットを取得できるようにします。Swift 3 MKMapSnapShotterスナップショットにカスタム注釈ピンを追加

私は2016年6月からthis answerを2015年8月からthis answerに誘導していますが、まだ正しい経路を見つけることができませんでした。

今、私は...

  1. バッファ
  2. からの写真は、マップのスナップショット

をゲットすることができますしかし、私はちょうどピンを配置することはできません。私は自分のコードが不完全で効果がないことを知っています - これは単なるデバッグの質問以上のものです。

let snapShotter = MKMapSnapshotter(options: mapSnapshotOptions) 

snapShotter.start() { 

    snapshot, error in 

     guard let snapshot = snapshot else { 
      return 
     } 

     let image = snapshot.image 
     let annotation = MKPointAnnotation() 
     annotation.coordinate = needleLocation // is a CLLocationCoordinate2D 
     annotation.title = "My Title" 

     let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotation") 

     // I want to push the final image to a global variable 
     // can't figure out how to define finalImage as the pinned map 
     self.myMap = finalImage 


     } // close snapShotter.start 

は私が今日間立ち往生してきたので、私は確かに任意の洞察力をいただければ幸いです。ここには、私は(上記のリンクに基づくだけでなく、多くのバリエーション)で作業していたものです。ありがとう!手動でスナップショットのimageと注釈ビューのimage新しいグラフィックコンテキスト上に描画し、そのコンテキストから新しいイメージを取得する必要が注釈ビューでMKMapSnapshotを、レンダリングするために

+0

ロブ、ありがとう。私はリンクをたどり、MapKitビデオがリンクをリンクしているのを見ました。しかし、これに慣れていないので、私は4歳のObjective-Cと現在のSwift 3の構文とAPIの間のギャップを埋めることができません。実際には利用可能ないくつかのSwift 2の例とSwift 3の間のギャップを埋め尽くすことができませんでした。 – niblettes

答えて

10

。スウィフト3:

let rect = self.imageView.bounds 

let snapshot = MKMapSnapshotter(options: options) 
snapshot.start { snapshot, error in 
    guard let snapshot = snapshot, error == nil else { 
     print("\(error)") 
     return 
    } 

    UIGraphicsBeginImageContextWithOptions(options.size, true, 0) 
    snapshot.image.draw(at: .zero) 

    let pinView = MKPinAnnotationView(annotation: nil, reuseIdentifier: nil) 
    let pinImage = pinView.image 

    var point = snapshot.point(for: location.coordinate) 

    if rect.contains(point) { 
     let pinCenterOffset = pinView.centerOffset 
     point.x -= pinView.bounds.size.width/2 
     point.y -= pinView.bounds.size.height/2 
     point.x += pinCenterOffset.x 
     point.y += pinCenterOffset.y 
     pinImage?.draw(at: point) 
    } 

    let image = UIGraphicsGetImageFromCurrentImageContext() 

    UIGraphicsEndImageContext() 

    // do whatever you want with this image, e.g. 

    DispatchQueue.main.async { 
     self.imageView.image = image 
    } 
} 

これは、それ自体がWWDC 2013ビデオPutting MapKit in Perspectiveから適合された、https://stackoverflow.com/a/18776723/1271826から適合させました。ここで

.satelliteFlyoverとスナップショットの一例である:

enter image description here

+0

Rob、ほぼ完璧に動作しました。 'rect.contains'が "未解決の識別子の使用"エラーをスローする場合。 CGRectを試しましたが、CLLOcationCoordinate2Dポイントタイプで "Can not invoke contains ..."エラーが発生しました。 私はCore Graphicについて読んできましたが、含まれていますが、エラーを解決することはできません。私はそれを解決するIFステートメントを削除することができますが、もちろん私はチェックを緩める。 – niblettes

+0

'MKMapSnapshotOptions'の' size'を作成するときに使用した 'UIImageView'の' bounds'として 'rect'を定義しました。そのコードサンプルにその宣言を追加しました... – Rob

+0

これは本当に役に立ちます。もちろん、私はまだエラーが発生します。 UIImageViewはUIViewから.boundsを継承します。しかし、MKMapSnapshotは.boundsを提供しないNSObjectから継承します。だから私のコードは何か間違っているようだ。私はそれを下に掲示するでしょう。 – niblettes

0

私MKMapSnapshotterイメージがUIImageであるので、私は「RECT」を定義ロブのコードからエラーを取得しました。しかし、.boundsはUIImageViewではなくUIImageViewのプロパティです。したがって、rect定義はエラーをスローします。

 let mapSnapshotOptions = MKMapSnapshotOptions() 

     // Set the region of the map that is rendered. 
     let needleLocation = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude) 
     let region = MKCoordinateRegionMakeWithDistance(needleLocation, 1000, 1000) 
     mapSnapshotOptions.region = region 

     // Set the scale of the image. We'll just use the scale of the current device, which is 2x scale on Retina screens. 
     mapSnapshotOptions.scale = UIScreen.main.scale 

     // Set the size of the image output. 
     mapSnapshotOptions.size = CGSize(width: 300, height: 300) 

     // Show buildings and Points of Interest on the snapshot 
     mapSnapshotOptions.showsBuildings = true 
     mapSnapshotOptions.showsPointsOfInterest = false 

ので.boundsプロパティにアクセスするための別の方法がある:ここでは

は、私はオプションの構成方法ありますか?または私は私のスナップショットを間違って作成しましたか?

+0

'bounds'は必要ありません。目標は、アノテーションビューのCGPointが可視イメージ内にあることを確認することです。スナップショットの画像を 'UIImageView'に合わせてサイズ調整したので、' imageView.bounds'を使用しました。しかし、固定サイズのCGSizeを作成している場合は、それを使用してください。 'let rect = CGRect(origin:.zero、size:mapSnapshotOptions.size)'を実行します。確かに、アノテーションを指すようにマップビューを明示的に作成した場合、 'if rect.contains(...){...}'の要素は必要ありません。アノテーションが表示されていることを100%保証していない場合にのみ必要です。 – Rob

関連する問題