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

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

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

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

Swift 2

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

Q&A

解決済

2回答

3942閲覧

アニメーションで動かしたUIButtonのタップイベントの起こし方

todayske

総合スコア36

Xcode

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

Swift 2

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

0グッド

2クリップ

投稿2016/04/12 12:20

UIButtonをアニメーションで動かすとタップイベントを検知できず、困っております。
ググってみたらHittestを使うとうまくいくとの情報が得られたのですが、詳細の実装方法が載っておらず、技術力低めの私では対応が難しい状況です。
現状のコードは下に貼ってあるようなものです。

何か解決方法をご存知の方がいらっしゃいましたら、ご教示いただけますと大変助かります。
ざっくりとした質問になってしまって大変恐縮ですが、何卒よろしくお願いいたします。

Swift

1class ViewController: UIViewController { 2 3 var charaBtn:UIButton! 4 5//中略 6 7func initAnime(){ 8 var nextx = self.charaBtn.frame.origin.x + CGFloat(Int(arc4random() % dist) - Int(dist)/2) 9 var nexty = self.charaBtn.frame.origin.y + CGFloat(Int(arc4random() % dist) - Int(dist)/2) 10 while (nextx < 0 || self.view.frame.size.width - self.charaBtn.frame.width < nextx ) { 11 nextx = self.charaBtn.frame.origin.x + CGFloat(Int(arc4random() % dist) - Int(dist)/2) 12 } 13 while (nexty < 0 || self.view.frame.size.height - self.charaBtn.frame.height < nexty ) { 14 nexty = self.charaBtn.frame.origin.y + CGFloat(Int(arc4random() % dist) - Int(dist)/2) 15 } 16 17 UIView.animateWithDuration(duration, 18 animations: {() -> Void in 19 // アニメーションする処理 20 self.charaBtn.frame.origin.x = nextx 21 self.charaBtn.frame.origin.y = nexty 22 23 }, completion: { finished in 24 self.initAnime() 25 }) 26 } 27}

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

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

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

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

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

guest

回答2

0

ベストアンサー

ユーザの操作を受け付けるオプションを指定して下さい。

swift

1UIView.animateWithDuration(duration, delay: 0, 2 options: [.AllowUserInteraction], //←これ 3 animations: { () -> Void in 4 // アニメーションする処理 5 self.charaBtn.frame.origin.x = nextx 6 self.charaBtn.frame.origin.y = nexty 7 }) { (finished) -> Void in 8 self.initAnime() 9}

投稿2016/04/13 05:49

編集2016/04/13 06:01
fuzzball

総合スコア16731

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

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

todayske

2016/04/13 11:56

こんなに簡単な方法があったなんて、、、 すごいです。ありがとうございます!
guest

0

ちょっと検索してみたところ、
http://anz-note.tumblr.com/post/66976503846/続uiviewアニメーション奮闘記-o
でhitTestを使った例を見つけました。

この記事に書かれてあるBaseViewの使い方が分からなかったのであれば、以下のようにすれば使えると思います。
1.記事に書いてあるBaseViewを自分のプロジェクトに取り込む(swiftで書きたければswiftに変換)
2.StoryboardにUIViewを貼り付け、そのクラスをBaseViewに変更
3.BaseViewの中にUIButtonを貼り付ける。(このUIButtonをアニメーションさせる)
これで、アニメーション中のUIButtonをタップするとTouchDownイベントが発生すると思います。


(4/13 15:00追記)
追伸します。
その記事通りにできるかどうかちょっと試してみたところ、hitTestは複数回発生することがあるのでTouchDownイベントも複数回発生してしまうようです。それで問題ないならこのまま使えば良いと思いますが、通常、ボタンのタップはタッチを離した時(TouchUpInside)に検出するものという点も気になるので、その点を含めて代替案を作ってみました。

swift

1import UIKit 2 3class BaseView: UIView { 4 5 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 6 let touchPoint = touches.first!.locationInView(self) 7 for subView in self.subviews { 8 if subView is UIButton { 9 let layer = subView.layer.presentationLayer() as! CALayer 10 if CGRectContainsPoint(layer.frame, touchPoint) { 11 let button = subView as! UIButton 12 button.sendActionsForControlEvents(.TouchDown) 13 } 14 } 15 } 16 } 17 18 override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 19 let touchPoint = touches.first!.locationInView(self) 20 for subView in self.subviews { 21 if subView is UIButton { 22 let layer = subView.layer.presentationLayer() as! CALayer 23 if CGRectContainsPoint(layer.frame, touchPoint) { 24 let button = subView as! UIButton 25 button.sendActionsForControlEvents(.TouchUpInside) 26 } 27 } 28 } 29 } 30}

1.BaseViewを上記のコードで作成する。(hitTestは実装しない)
2.StoryboardにUIViewを貼り付け、そのクラスをBaseViewに変更する。
3.BaseViewの中にUIButtonを貼り付ける。(このUIButtonをアニメーションさせる)
4.貼り付けたUIButtonの「User Interaction Enabled」のチェックをOFFにする。

これでボタンの上でタッチ開始した時にTouchDownが発生し、ボタンの上でタッチを離した時にTouchUpInsideが発生すると思います。
もうちょっとちゃんとするなら、タッチ開始時にボタンをキャプチャして、ボタンの表示をハイライトにし、タッチを離した時にボタン内ならTouchUpInsideを発生させ、ボタン外で離したらTouchUpOutsideを発生させないといけないですが、そこまで求めているかどうかわからないので、ここまでにしておきます。
必要なら上記コードを改造してタッチ中のボタンをキャプチャする実装にすればさほど難しくなくできると思います。

投稿2016/04/13 04:06

編集2016/04/13 06:06
TakeOne

総合スコア6299

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

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

todayske

2016/04/13 11:58

ご教示いただいた方法で動作を確認させていただきました。 詳細にご教示いただき、ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問