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

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

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

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

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Q&A

解決済

1回答

2497閲覧

UIPanGestureRecognizerを使うとTouchesMovedが1回しか呼ばれず、TouchesEndedが1回も呼ばれない。

yrema

総合スコア286

iOS

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

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

0グッド

0クリップ

投稿2019/05/22 08:16

タイトルの通りですが、お絵描きアプリで
TouchesBegan
TouchesMoved
TouchesEnded
を使ってフリーハンド描画を行っています。
ここにUIPanGestureRecognizerを追加して全体表示を平行移動させようとしています。
下記の「★ここをコメントアウトするとフリーハンド描画できる」の行で、
UIPanGestureRecognizerをAddGestureRecognizerすると、
TouchesBegan → 呼ばれる
TouchesMoved → 1回だけしか呼ばれない
TouchesEnded → 呼ばれない
となってしまい、フリーハンド描画ができなくなってしまいました。
2回目以降のTouchesMovedとTouchesEndedを呼ぶにはどうすればよろしいでしょうか?

c#

1 // ピンチジェスチャー追加 2 UIPinchGestureRecognizer pinchGesture = new UIPinchGestureRecognizer(Pinch); 3 pinchGesture.Delegate = new GestureDelegate((PaintViewController)viewController, m_BaseImageView); 4 paintCanvasView.AddGestureRecognizer(pinchGesture); 5 6 // パンジェスチャー追加 7 UIPanGestureRecognizer panGesture = new UIPanGestureRecognizer(Pan); 8 panGesture.Delegate = new GestureDelegate((PaintViewController)viewController, m_BaseImageView); 9 paintCanvasView.AddGestureRecognizer(panGesture); // ★ここをコメントアウトするとフリーハンド描画できる

c#

1 2 internal void Pan(UIPanGestureRecognizer gestureRecognizer) 3 { 4 //nint numberOfTouches = gestureRecognizer.NumberOfTouches; 5 ////Debug.WriteLine("numberOfTouches " + numberOfTouches.ToString()); 6 //// シングルタップでもPanだと見なされてしまうらしいのでマルチタップの時だけ移動させる 7 //if (numberOfTouches >= 2) 8 //{ 9 // // フリーハンドキャンセル 10 // //m_PaintCanvasView.PaintFreeHandView.CancelTouch(); 11 12 // // 画像の移動 13 // TranslateImage(gestureRecognizer); 14 //} 15 } 16 17 // Scales the image by the current scale 18 internal void TranslateImage(UIPanGestureRecognizer gestureRecognizer) 19 { 20 Debug.WriteLine("TranslateImage1"); 21 22 AdjustAnchorPointForGestureRecognizer(gestureRecognizer); 23 // If it's just began, cache the location of the image 24 if (gestureRecognizer.State == UIGestureRecognizerState.Began) 25 { 26 m_OriginalImageFrame = m_BaseImageView.Frame; 27 } 28 29 // Move the image if the gesture is valid 30 if (gestureRecognizer.State != (UIGestureRecognizerState.Cancelled | UIGestureRecognizerState.Failed 31 | UIGestureRecognizerState.Possible)) 32 { 33 // Move the image by adding the offset to the object's frame 34 PointF offset = (PointF)gestureRecognizer.TranslationInView(m_BaseImageView); 35 RectangleF newFrame = (RectangleF)m_OriginalImageFrame; 36 newFrame.Offset(offset.X, offset.Y); 37 m_BaseImageView.Frame = newFrame; 38 } 39 } 40 41 42 internal void Pinch(UIPinchGestureRecognizer gestureRecognizer) 43 { 44 // フリーハンドキャンセル 45 m_PaintCanvasView.PaintFreeHandView.CancelTouch(); 46 47 // 画像の拡縮 48 ScaleImage(gestureRecognizer); 49 } 50 51 // Scales the image by the current scale 52 internal void ScaleImage(UIPinchGestureRecognizer gestureRecognizer) 53 { 54 Debug.WriteLine("ScaleImage1"); 55 AdjustAnchorPointForGestureRecognizer(gestureRecognizer); 56 if (gestureRecognizer.State == UIGestureRecognizerState.Began || gestureRecognizer.State == UIGestureRecognizerState.Changed) 57 { 58 Debug.WriteLine("ScaleImage2"); 59 gestureRecognizer.View.Transform *= CGAffineTransform.MakeScale(gestureRecognizer.Scale, gestureRecognizer.Scale); 60 // Reset the gesture recognizer's scale - the next callback will get a delta from the current scale. 61 gestureRecognizer.Scale = 1; 62 } 63 } 64 // Scale and rotation transforms are applied relative to the layer's anchor point. 65 // This method moves a UIGestureRecognizer's view anchor point between the user's fingers 66 static void AdjustAnchorPointForGestureRecognizer(UIGestureRecognizer gestureRecognizer) 67 { 68 Debug.WriteLine("AdjustAnchorPointForGestureRecognizer1"); 69 if (gestureRecognizer.State == UIGestureRecognizerState.Began) 70 { 71 Debug.WriteLine("AdjustAnchorPointForGestureRecognizer2"); 72 var image = gestureRecognizer.View; 73 var locationInView = gestureRecognizer.LocationInView(image); 74 var locationInSuperview = gestureRecognizer.LocationInView(image.Superview); 75 76 image.Layer.AnchorPoint = new CGPoint(locationInView.X / image.Bounds.Size.Width, locationInView.Y / image.Bounds.Size.Height); 77 image.Center = locationInSuperview; 78 } 79 } 80 class GestureDelegate : UIGestureRecognizerDelegate 81 { 82 PaintViewController controller; 83 UIImageView uiImageView; 84 85 public GestureDelegate(PaintViewController controller, UIImageView uiImageView) 86 { 87 Debug.WriteLine("GestureDelegate"); 88 this.controller = controller; 89 this.uiImageView = uiImageView; 90 } 91 92 public override bool ShouldReceiveTouch(UIGestureRecognizer aRecogniser, UITouch aTouch) 93 { 94 Debug.WriteLine("ShouldReceiveTouch"); 95 return true; 96 } 97 98 // Ensure that the pinch, pan and rotate gestures are all recognized simultaneously 99 public override bool ShouldRecognizeSimultaneously(UIGestureRecognizer gestureRecognizer, UIGestureRecognizer otherGestureRecognizer) 100 { 101 Debug.WriteLine("Test1"); 102 // if the gesture recognizers's view isn't one of our images don't recognize 103 if (gestureRecognizer.View != uiImageView) 104 return false; 105 106 Debug.WriteLine("Test2"); 107 // if the gesture recognizers views differ, don't recognize 108 if (gestureRecognizer.View != otherGestureRecognizer.View) 109 return false; 110 111 Debug.WriteLine("Test3"); 112 // if either of the gesture recognizers is a long press, don't recognize 113 if (gestureRecognizer is UILongPressGestureRecognizer || otherGestureRecognizer is UILongPressGestureRecognizer) 114 return false; 115 116 Debug.WriteLine("Test4"); 117 return true; 118 } 119 }

◆環境
Visual Studio 2017
Xamarin 4.12
Xamarin.iOS 12.2

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

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

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

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

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

guest

回答1

0

ベストアンサー

ほとんど当てずっぽうですが、たぶん平行移動用のアンカーか何かがあって、そこが起点のパンは平行移動で、それ以外はフリーハンド描画にしたいんですよね?

であれば、たしか

public override bool ShouldReceiveTouch(UIGestureRecognizer aRecogniser, UITouch aTouch)

でaTouchの座標を見て、アンカーに当たっていない座標であればfalseを返してしまえばうまく行った記憶があります。

投稿2019/05/22 08:33

takabosoft

総合スコア8356

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

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

yrema

2019/05/22 08:38

アンカーはありません。二本指でぐるぐるとドラッグすることを想定しています。 二本指で動かすことをパン操作という認識でいたのですが、ここから私が間違ってたりしますか?
yrema

2019/05/22 08:45

素晴らしいです!MinimumNumberOfTouches = 2にして解決できました!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問