35680


現在勉強なども含めてやったことがないことに挑戦しようと課題(こんなアプリを作る)を決めてアプリ制作をしています。(今回は妖精が飛び交うようなアプリにしようと思っています。)

今回アプリの中でタイマーで動かしているアニメーションの座標またはタグを取得してタッチしたものがそうであれば成功のアラート違えば違うアラートを出したいと考えています。

しかし。タッチした時のタッチした場所の座標の取得などはできたり、もともとのviewがタッチしたところからどれだけ離れているかなどはわかるのですが、移動最中のviewのリアルタイムの座標の取得方法が全くわかりません。

現在までにできているのはランダムに移動した後のviewの座標の更新(あくまで設定した座標なので移動中とか全く関係なくなってしまいます。)ぐらいです。

何か、いい方法やヒントなどあればご教授お願いします。

ちなみに、コードはswift3で以下のような形で書いています。

[code]

    import UIKit
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let FairyView:UIImageView = UIImageView()
            FairyView.isUserInteractionEnabled = true
            FairyView.frame.size.height = 130
            FairyView.frame.size.width = 130
            FairyView.backgroundColor = UIColor.blue
            let sampleX = Int(arc4random_uniform(UInt32(self.view.frame.size.width)))
            let sampley = Int(arc4random_uniform(UInt32(self.view.frame.size.height)))
            FairyView.frame.origin.x = CGFloat(sampleX)
            FairyView.frame.origin.y = CGFloat(sampley)
            self.view.addSubview(FairyView)
            FairyView.tag = 1
    
            _ = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.createFairy), userInfo: nil, repeats: true)
    
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
    
        }
    
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch: UITouch in touches {
    
            let tag = touch.view!.tag
            if (tag == 1) {
    
                let alert = UIAlertView()
                alert.title = "成功"
                alert.message = "次"
                alert.addButton(withTitle: "Ok")
                alert.show()
    
    
            }else{
    
                let alert = UIAlertView()
                alert.title = "失敗"
                alert.message = "ゲームオーバー！"
                alert.addButton(withTitle: "Ok")
                alert.show()
    
            }
        }
    }
    
    
    
    func createFairy(){
    
        let sampleXx = Int(arc4random_uniform(UInt32(self.view.frame.size.width)))
        let sampleyy = Int(arc4random_uniform(UInt32(self.view.frame.size.height)))
        let animation = CABasicAnimation(keyPath: "position")
        animation.toValue = [sampleXx, sampleyy]
        animation.duration = 2.0
        animation.repeatCount = MAXFLOAT
        animation.autoreverses = true
        view.viewWithTag(1)?.frame.origin = CGPoint(x:sampleXx , y:sampleyy)
        view.viewWithTag(1)?.layer.add(animation, forKey: nil)
        view.viewWithTag(1)?.setNeedsDisplay()
    
    
    }
    
    
    }
    
[/code]


CC BY-SA 3.0
2017-06-18T05:33:32.470
35678
2017-06-18T23:59:16.313
23867
question
swift ios xcode swift3
アニメーション途中の座標の取得の方法がわかりません。考え方などでも教えていただけると嬉しいです。


アニメーション中の`UIView`（のサブクラス）の位置情報（`center`、`frame`など）は、アニメション終了時の位置情報になります。そのままでは、移動中の位置情報は得られません。それを知るには、`CALayer`クラスのメソッド`presentation()`によって、“見かけ”のレイヤーオブジェクトを取得し、それの位置情報を取得するという方法をとります。  
以下、サンプルコードを示します。メソッド`startAnimation()`は、`UIViewController`のサブクラスのメソッドで、`targetView`をアニメーションさせるとともに、タイマーを使って、その位置情報を`print`します。

[code]

    func startAnimation() {
        UIView.animate(withDuration: 5.0){
            self.targetView.center = CGPoint(x: self.targetView.center.x, y: self.targetView.center.y - 200.0)
        }
        var counter = 0
        Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true){timer in
            if let position = self.targetView.layer.presentation()?.position {
                print(position)
            }
            counter += 1
            if counter > 9 {
                timer.invalidate()
            }
        }
    }
    
[/code]

`presentation()`メソッドの返り値がオプショナルである点をお忘れなく。


CC BY-SA 3.0
2017-06-18T08:43:09.560
35680
2017-06-18T08:43:09.560
18540
35678
answer