I'm trying to glow a view on touch and unglow it when touch is ended. While doing this, I noticed that when I raise my finger from the view, - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
method is not called but instead - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
method is called on the view. Is that a normal behaviour? I thought touchesCancelled
is called if touches are cancelled because of a system issue like low memory warning. I did my job by using touchesCancelled but nevertheless I am wondering why it does not properly call touchesEnded
. Is it a bug?
5 に答える
これは正常な動作ではありません。指を上げると、touchesEndedが呼び出されます。
touchesCancelledは、タッチ中にビューが削除されたとき、またはシステムイベントが発生したときに呼び出される必要があります(たとえば、指が画面に触れているときに電話をロックする)
touchesEndedおよびtouchesCancelledのドキュメントを参照してください。
あなたのコードがなければ、何が起こっているのかを知ることは不可能です。ただし、touchedEndedが正常に呼び出されたとしても、両方のケースに対応したいと思うようです。迅速に:
class MyView: UIView {
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
stopGlow()
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
stopGlow()
}
private func stopGlow() {
//Your code here...
}
}
そのビューに触れて指を上げるときは、指をドラッグしないでください。そのようにした場合は、touchesCancelled:
メソッドが呼び出されます。ですから、あなたの見方は小さすぎて触れられないと思います。はいの場合は、大きなビューを作成して再試行してください。それはあなたのために働くでしょう。
comment
これを..と考えてください。
自動UIModalPresentationOverFullScreenを使用してドキュメントウィンドウを表示すると、モーダルであってもウィンドウが少し上下に移動する可能性があるという状況がありました。親ビューのタッチを追跡してサブビューを移動したときに、touchesCancelledを呼び出すだけで十分でした。サブビューの端をつかんで指をすばやく動かすと、表示されたウィンドウが少し移動し、タッチがキャンセルされます。これは、touchesCancelledと呼ばれます。
この質問に答えるにはあまりにも多くの情報を省略しました。それをやり直すか、それを捨てます。それまでの間、この問題や、touchesBegan / Moved / Ended / Cancelledに関連する予期しない動作に関連するその他の問題が発生した場合は、タッチポイントを抽出しているビューを確認する必要があります。タッチポイントデータが、たとえば、から[touches.anyObject locationInView:touches.anyObject.view]
のものである場合は、ビューへの別の参照を使用しますself.view
。それは多くの問題を解決するでしょう。
タッチが開始してから最初の1秒ほどで十分に移動しない場合、touchesEndedではなくtouchesCancelledが呼び出されるようです。小さいながらも速い動きをすると、全体の動きが十分に大きくなかったため、touchesCancelledが起動します。小さな動きをゆっくりと行うと、iOSがさらに動くかどうかを待つのをあきらめるため、動きが終了する前にtouchesCancelledが起動します。どうやらiOSは、どれだけの動きが「重要」であるかについてある程度の判断を下しており、小さな動きをキャンセルされたタッチと見なしているようです。
それが役立つ場合は、touchesCancelledからtouchesEndedを呼び出すだけです。ただし、非常に速い移動の場合、これはタイムアウト期間まで呼び出されないため、移動が実際に終了してからtouchsCancelledが起動されるまでに遅延が生じる可能性があります。
ちなみに、touchsCancelledが起動する前に、小さくて速い動きをしてから指を離してから別の動きを開始すると、それは新しい動きとは見なされず、touchsBeganは起動しないことにも気づきました。これは私のアプリの手書き機能を複雑にします。手書きはすべて小さくて速い動きに関するものだからです。