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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

3回答

254閲覧

Maps SDK for iOSのPanoramaViewでheadingをKVOで監視するには? Value of type 'GMSOrientation' has no member...

testyoutatsu

総合スコア29

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2019/02/28 20:12

編集2019/03/06 01:00

##前提・実現したいこと
GoogleのMaps SDK for iOSを使って表示させたPanoramaView(ストリートビュー)の向いてる方角(heading)を取得したい)

以前こちらで質問したものです。
headingpanoView.camera.orientation.headingで取得します。

これを"リアルタイム"で取得する方法をご教授ください。

*追記
・今回の場合、ストリートビューが動いている間の値(heading)の変更を常に監視したい(指を離した後フェードで動きが止まるまで)。

headingを元にLabelに方角をリアルタイムで表示したいと考えています。
touchesbeganではタッチ開始の1度しか値を取得できずうまくいきませんでした。

よろしくお願いします。

##コード

Swift

1import UIKit 2import GoogleMaps 3 4class ViewController: UIViewController { 5 6 @IBOutlet weak var streetView: UIView! 7 8 @objc dynamic var panoView: GMSPanoramaView! 9 @objc dynamic var heading: CLLocationDirection = 0 10 let latitude: CLLocationDegrees = 36.5780574 11 let longitude: CLLocationDegrees = 136.6486596 12 13 14 override func viewDidLayoutSubviews() { 15 let width = <> 16 let height = <> 17 let frame = CGRect(x: 0, y: 0, width: width, height: height) 18 19 panoView = GMSPanoramaView(frame: frame) 20 panoView.camera = GMSPanoramaCamera(heading: heading, pitch: -10, zoom: 1) 21 panoView.moveNearCoordinate(CLLocationCoordinate2D(latitude: latitude, longitude: longitude)) 22 streetView.addSubview(panoView) 23 24 heading = panoView.camera.orientation.heading 25 } 26 27 override func viewDidLoad() { 28 super.viewDidLoad() 29 30 self.addObserver(self, forKeyPath: "対象プロパティ", options: [.old, .new], context: nil) // <- ここを以下に訂正 31 panoView.camera.orientation.addObserver(self, forKeyPath: "heading", options: [.old, .new], context: nil) // <- ここでエラー 32 } 33 34 35 override func observeValue(forKeyPath keyPath: String?, of object: Any?, 36 change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) { 37 38 print(change![.oldKey]!) // before 39 print(change![.newKey]!) // after 40 } 41} 42

##試したこと

教えていただいたKVOを試してみました。
panoView.camera.orientation.addObserver(self, forKeyPath: "heading", options: [.old, .new], context: nil).orientation
エラーValue of type 'GMSOrientation' has no member 'addObserverが発生します。

知識不足で申し訳ないのですがご教授いただけると幸いです。

##リンク
Maps SDK for iOS Reference

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

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

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

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

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

fuzzball

2019/03/01 02:57 編集

「リアルタイム」の意味がイマイチ分からないのですが、現状ではリアルタイムに取得できないのでしょうか?takabosoftさんの回答のように、値の変更を監視したいということでしょうか?
testyoutatsu

2019/03/02 05:47

はい、質問に追記しました。
fuzzball

2019/03/06 00:11

Q1. 「1本または2本指で動かしている間」というのは、どうやって判断していますか? Q2. 「なのでtouchesbeganではうまくいきません。」の「なので」は、どういう意味ですか?何が「なので」なのでしょうか?
testyoutatsu

2019/03/06 01:02 編集

A1. 画面をタッチしている指の数で処理を分ける必要がなくなったので削除します。 A2. 画面に指がタッチしている(触れている)間、常に値の変更を監視したいと考えています。 touchesbeganではタッチ開始の1度しか値を取得できないことに対してです。 今気づきましたがストリートビューを動かした時、指を離したあともフェードアウトするように動くので、タッチの検知を考える必要がありませんでした。こちらも訂正します。
fuzzball

2019/03/06 01:00

Q1で聞いているのは指の数のことではありません。「間」をどうやって判断しているのか?という質問だったのですが、それが分からないということでしょうか?
testyoutatsu

2019/03/06 01:03

失礼しました。おっしゃる通りでどのように判断するのか分かりません。
guest

回答3

0

動くかどうかはやってみないとわかりませんが、
NSObjectから派生しているクラスでは
KVO(Key-Value Observing)という「プロパティの変更を通知してくれる仕組み」が用意されていますので
それを使ってみてはいかがでしょうか。

"KVO swift4"でググってもらえればやり方は出ると思います。

投稿2019/03/01 00:34

takabosoft

総合スコア8356

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

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

testyoutatsu

2019/03/02 07:50 編集

回答ありがとうございます。この機能は知りませんでした。 早速調べて試してみたところ、コードで監視対象の変数の値を変更した時に呼び出すことはできましたが、PanoramaViewのプロパティの変更を検知させる方法が分かりませんでした。 質問に簡略したコードを追記します。 追記しました。
takabosoft

2019/03/04 01:32

> self.addObserver(self, forKeyPath: "対象プロパティ", options: [.old, .new], context: nil) ↑ここちゃんと書いてくださいね。 panoView.camera.orientation.addObserver(self, forKeyPath: "heading", options: [.old, .new], context: nil)
testyoutatsu

2019/03/04 17:25

返信ありがとうございます。 ここではself.ではなくpanoView.camera.orientation.なのですね。試してみます。
testyoutatsu

2019/03/05 16:47 編集

早速試してみましたが、panoView.camera.orientation.addObserverのorientation の箇所で Value of type 'GMSOrientation' has no member 'addObserver' のエラーが出ました。これはGMSOrietntation対応していないということで諦めるべきでしょうか?
takabosoft

2019/03/06 01:07

あー、ひょっとしてGMSOrientationは構造体ですかね? それならpanoView.camera.addObserver(self, forKeyPath: "orientation", options: [.old, .new], context: nil) でorientationをまるごと監視してみてはいかがでしょうか。
testyoutatsu

2019/03/06 02:17 編集

panoView.camera.addObserver(self, forKeyPath: "orientation", options: [.old, .new], context: nil) でも無理でした。 @objc dynamic var orientation: GMSOrientation! orientation = panoView.camera.orientation self.addObserver(self, forKeyPath: "orientation", options: [.old, .new], context: nil) のようにも書いてみましたが、 Property cannot be marked @objc because its type cannot be represented in Objective-C のエラーが出ました。非対応...?
guest

0

自己解決

GMSPanoramaViewDelegateを使うことで解決できました。

  • panoramaView:didMoveCamera:

Called repeatedly during changes to the camera on GMSPanoramaView.

This may not be called for all intermediate camera values, but is always called for the final position of the camera after an animation or gesture.

Swift

1import UIKit 2import GoogleMaps 3 4class ViewController: UIViewController, GMSPanoramaViewDelegate { 5 6 @IBOutlet weak var streetView: UIView! 7 8 var panoView: GMSPanoramaView! 9 var heading: CLLocationDirection = 0 10 let latitude: CLLocationDegrees = 36.5780574 11 let longitude: CLLocationDegrees = 136.6486596 12 13 14 override func viewDidLayoutSubviews() { 15 let width = <> 16 let height = <> 17 let frame = CGRect(x: 0, y: 0, width: width, height: height) 18 19 panoView = GMSPanoramaView(frame: frame) 20 panoView.camera = GMSPanoramaCamera(heading: heading, pitch: -10, zoom: 1) 21 panoView.moveNearCoordinate(CLLocationCoordinate2D(latitude: latitude, longitude: longitude)) 22 streetView.addSubview(panoView) 23 } 24 25 override func viewDidLoad() { 26 super.viewDidLoad() 27 panoView.delegate = self 28 } 29// 以下を追加 30 func panoramaView(_ panoramaView: GMSPanoramaView, didMove camera: GMSPanoramaCamera) { 31 heading = camera.orientation.heading 32 print(heading) 33 } 34// ここまで 35}

投稿2019/03/06 03:04

testyoutatsu

総合スコア29

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

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

takabosoft

2019/03/06 04:14 編集

ありゃ、遠回りさせてしまって申し訳ないです。
testyoutatsu

2019/03/06 06:11

いえ、とんでもないです。私がリファレンスを読み間違えてたので。 KVOについても勉強になりました!ありがとうございました。
guest

0

質問への追記・修正より、

touchesbeganではタッチ開始の1度しか値を取得できない

Beganだけではなく、Moved, Ended, Cancelledがあります。
移動時(ドラッグ時)はMovedが呼ばれます。

ref. UIResponder

投稿2019/03/06 01:10

fuzzball

総合スコア16731

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

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

testyoutatsu

2019/03/06 01:31

回答ありがとうございます。 Movedも試してみましたが、こちらもタッチ開始から0.1秒間の数回しか値を取得することができませんでした。
fuzzball

2019/03/06 01:34

移動しなければ呼ばれませんが、そういうことではなくて?
testyoutatsu

2019/03/06 01:46

指を動かしていますがタッチ開始時しか値を取得できません。
fuzzball

2019/03/06 01:52

touchesMovedが呼ばれていないということですか?
testyoutatsu

2019/03/06 02:01

touchesMovedはタッチした瞬間だけ数回呼ばれます。そのあと指を動かしても全く呼ばれません。一度指を離し、再度タッチすると同じくタッチした瞬間だけ数回呼ばれます。 スワイプした場合、呼ばれた数回がそれぞれ違う値を返すので瞬間的には移動を検知しています。
testyoutatsu

2019/03/06 02:54

touchesMovedについては分かりません。。。 delegateで以下があります。これで解決することができました。 - panoramaView:didMoveCamera: Called repeatedly during changes to the camera on GMSPanoramaView. This may not be called for all intermediate camera values, but is always called for the final position of the camera after an animation or gesture. "after an animation or gesture." ここをアニメーション、ジェスチャ完了直後に"1度だけ"呼ばれるものと思い込んで試していませんでした。"Called repeatedly"と書いてありますね。 お手数おかけしました。回答ありがとうございました。
fuzzball

2019/03/06 02:56

自己解決でクローズして下さい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問