

現在、読み込んだ一つの動画から複数のサムネイルを取得し横に並べるiOSアプリを作成しています。動画からサムネイルを取得し横に並べることはできたのですが，そこから１つのサムネイルをタップした時に別のUIImageViewにそのサムネイルを表示したいのですがうまくできません。

現状の手法として、UIImageViewを継承したクラスを作成し、その値をタップイベントの方に送っているのですが、値が0,1,2など数字ではなく15桁などのランダムな数字が出てしまいます。

なぜそのような値が返ってくるのかわからないので教えていただけると助かります。また別な方法で構いません。

以下、ソースコード、実行結果と参考にしたサイトになります。

ソースコード

[code]

    import UIKit
    import AVFoundation
    import AssetsLibrary
    
    class ViewController: UIViewController, UIGestureRecognizerDelegate {
    
        @IBOutlet weak var topimage: UIImageView!
        @IBOutlet weak var scroll: UIScrollView!
    
        let time = 20
    
        class MyUIImageView: UIImageView{
            let x:Int
            let y:Int
            init(x:Int,y:Int,frame:CGRect){
                self.x = x
                self.y = y
                super.init(frame:frame)
            }
            required init(coder aDecoder: NSCoder) {
                fatalError("*** init(coder:) has not been implemented")
            }
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let filePath: URL = URL(fileURLWithPath: "動画のパス")
            let asset = AVURLAsset(url: filePath, options: nil)
            let imgGenerator = AVAssetImageGenerator(asset: asset)
            imgGenerator.appliesPreferredTrackTransform = true
    
            scroll.contentSize = CGSize(width: time * 100, height: 200)
            scroll.bounces = false
            self.scroll.isScrollEnabled = true
            self.scroll.showsHorizontalScrollIndicator = false
    
            do{
                for x in 0...time - 1{
                //位置を変えながらviewを作る
                    let iv : UIImageView = MyUIImageView(
                        x:x,
                        y:1,
                        frame:CGRect(x:CGFloat(x)*100, y:100, width:100, height:150))
    
                    //サムネイルの作成
                    let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(Int64(seconds / (time - x)), 3), actualTime: nil)
                    let thumbnail = UIImage(cgImage: cgImage)
    
                    //画像をviewに追加
                    iv.image = thumbnail
                    //タップジェスチャ
                    iv.isUserInteractionEnabled = true
                    iv.addGestureRecognizer(UITapGestureRecognizer(
                        target: self,
                        action: #selector(imageViewTapped)))
    
                    //画面に追加
                    scroll.addSubview(iv)
                }
            }catch let error {
                print("*** Error generating thumbnail:\(error.localizedDescription)")
            }
        }
    
        @objc func imageViewTapped(views:MyUIImageView, gestureRecognizer: UITapGestureRecognizer) {
            //ここでxを取得できれば同じ上記と同じプログラムを書けば表示できると考えています。
            print(views.x)
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
    
        }
    }
    
[/code]

実行結果

[code]

    view at (140434724710272) is tapped //一つ目のサムネイル
    view at (0) is tapped //二つ目のサムネイル
    view at (140434743678464) is tapped //三つ目のサムネイル
    view at (140434724710848) is tapped //四つ目のサムネイル
    
[/code]

参考サイト  
<https://qiita.com/fetaro/items/199e36d71ee9c0015488>


CC BY-SA 3.0
2017-11-30T18:20:41.263
39958
2017-11-30T23:56:33.877
2017-11-30T23:56:33.877
16882
16882
question
swift ios
Swiftにて画像をタップした時の動作について


iOS側からセレクタで指定されたメソッドを呼び出す場合、どのようなパラメーターを渡すかはiOSのどの機能を使うかで決まっています。

[`UIGestureRecognizer`の場合](https://developer.apple.com/documentation/uikit/uigesturerecognizer)、以下のシグニチャーのいずれかでないといけません。

>
[code]

>     @IBAction func myActionMethod()
>     @IBAction func myActionMethod(_ sender: UIGestureRecognizer)
>  
[/code]

`@IBAction`なんてのは単にドキュメントの記述上の話なのでサクッと無視してもらって、肝心なのは引数として受け取れるのは最大で1個、その1個は`UIGestureRecognizer`を表していると言うことです。

メソッド宣言で引数を追加したとしても、iOS側はそんなことは一切無視して1個目の引数として`UIGestureRecognizer`のインスタンス(あなたの場合`UITapGestureRecognizer`)を渡します。あなたのメソッドはそれを無理やり`MyUIImageView`と解釈して`MyUIImageView`用のプロパティゲッターを呼んでいるのですから、まともな値が返らないどころか、即座にクラッシュしていてもおかしくないところです。

セレクタで呼び出されるメソッドには、ちゃんとお約束通りの引数を宣言して下さい。

[code]

    @objc func imageViewTapped(_ gestureRecognizer: UITapGestureRecognizer) {
        //UIGestureRecognizerのセット先のビューを取り出したい場合は、`view`プロパティを使う
        //UITapGestureRecognizerの設定を間違えていた場合にはクラッシュで知らせるため、意図的に`!`や`as!`を使っている
        let myImageView = gestureRecognizer.view! as! MyUIImageView
        print(myImageView.x)
    }
    
[/code]


CC BY-SA 3.0
2017-11-30T21:14:15.690
39959
2017-11-30T21:14:15.690
13972
39958
answer