49161


タッチしたところに四角(UIImageView)を作成することは出来たのですが、その複数作成した中の一つの四角をタップしたら、削除。また、ドラッグしたら移動する。ようなプログラムがどうしても書けません。

現状は下記のコードで、  
・何もないところに四角の作成。  
・一番最後に作成した四角をドラッグする。  
は実装できました。

作成段階で整理されていないコードですが、お願いします。

[code]

    import UIKit
    
    var pointX: CGFloat = 0.0
    var pointY: CGFloat = 0.0
    var w: CGFloat = 50
    var h: CGFloat = 50
    var flag: Int = 0
    
    class ViewController: UIViewController {
        @IBOutlet var tapG: UITapGestureRecognizer!
        @IBOutlet weak var ImageView: UIImageView!
        @IBOutlet weak var view_safe: UIView!
        var boxViewArray: Array<UIImageView> = []
        var tap = UITapGestureRecognizer()
        var drag = UIPanGestureRecognizer()
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        @IBAction func tapGesture_action(_ sender: UITapGestureRecognizer) {
            let boxImage: UIImage
            let point = sender.location(in: view_safe)
    
            pointX = point.x
            pointY = point.y
    
            //四角形のイメージを生成
            boxImage = makeBoxImage(x: pointX-(w/2), y: pointY-(h/2), width: w, height: h)
    
            var tmp: UIImageView = UIImageView()
            tmp = UIImageView(image: boxImage)
            tmp.tag = flag
            flag += 1
    
            tap = UITapGestureRecognizer()
    
            drag = UIPanGestureRecognizer(target: self, action: #selector(self.panView(sender:)))
            tmp.isUserInteractionEnabled = true
            tmp.addGestureRecognizer(drag)
    
            boxViewArray.append(tmp)
    
            self.ImageView.addSubview(boxViewArray.last!)
            //self.ImageView.bringSubview(toFront: boxViewArray.last!)
        }
    
        func makeBoxImage(x: CGFloat, y: CGFloat, width w: CGFloat, height h: CGFloat) -> UIImage{
            print("makeBoxImage 開始")
            //イメージ処理の開始
            let size = CGSize(width: ImageView.frame.width, height: ImageView.frame.height)
            UIGraphicsBeginImageContextWithOptions(size, false, 1.0)
            //コンテキスト
            let context = UIGraphicsGetCurrentContext()
            //サイズを決める
            let drawRect = CGRect(x: x, y: y, width: w, height: h)
            //パスを作る
            let drawPath = UIBezierPath(rect: drawRect)
            //塗り色
            context?.setFillColor(red: 0.0, green: 1.0, blue: 1.0, alpha: 1.0)
            //パスを塗る
            drawPath.fill()
            //線の色
            context?.setStrokeColor(red: 0.0, green: 1.0, blue: 1.0, alpha: 1.0)
            //パスを描く
            drawPath.stroke()
            //イメージコンテキストからUIImageを作る
            let image = UIGraphicsGetImageFromCurrentImageContext()
            //イメージ処理の終了
            UIGraphicsEndImageContext()
    
            return image!
        }
    
        @objc func panView(sender: UIPanGestureRecognizer){
    
            //let tagNo = sender.view?.tag
            //print(tagNo)
            //移動量を取得
            let move: CGPoint = sender.translation(in:self.view)
            //ドラッグした部品の座標に移動量を加算
            sender.view!.center.x += move.x
            sender.view!.center.y += move.y
            //移動量を0に
            sender.setTranslation(CGPoint.zero, in: self.view)
        }
    
        @objc func delete_tapped(_ sender: UITapGestureRecognizer){
            print("delete")
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            print(#function)
            for touch in touches {
                let location = touch.location(in: view_safe)
                print(location)
    
            }
        }
    
        override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
            for touch in touches {
            let location = touch.location(in: view_safe)
            let thePoint: CGPoint = location
            let hitView: UIView = UIView()
    
            hitView.hitTest(thePoint, with: event)
            //NSLog("Hit Test : tag = %ld", hitView.tag)
            }
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()}
    }
    
[/code]


CC BY-SA 4.0
2018-10-10T15:39:38.733
49151
2018-10-10T22:39:57.820
2018-10-10T17:51:44.153
3060
30462
question
swift ios macos swift4 uiimageview
タッチしたUIimageView(複数)を移動、削除させる方法を教えてください。


まず、「・一番最後に作成した四角をドラッグする。」ことしかできないのは`makeBoxImage(x:y:width:height:)`で作られる画像が大き過ぎて画面全体を覆ってしまっているからです。これでは一番最後に付け加えられた`UIImageView`以外はタップイベントに反応できなくなります。

「削除」がどうしても書けませんについては、メソッドの内容も空、`addGestureRecognizer(tap)`なんてコードも見当たらないので、何がわからなくてどうしても書けないのかがわかりません。と言うわけで、以下のコードでは`delete_tapped(_:)`メソッドが呼び出されるところまでにしておきます。

[code]

    import UIKit
    
    let w: CGFloat = 50
    let h: CGFloat = 50
    
    class ViewController: UIViewController {
        @IBOutlet weak var imageView: UIImageView!
        var boxViewArray: Array<UIImageView> = []
    
        var nextTagForImage: Int = 1
    
        override func viewDidLoad() {
            super.viewDidLoad()
            print("done")
        }
    
        @IBAction func tapGesture_action(_ sender: UITapGestureRecognizer) {
            let point = sender.location(in: imageView)
    
            let pointX = point.x
            let pointY = point.y
    
            //四角形のイメージを生成
            //### 計算した位置は`UIImageView`の位置を決めるのに使用する
            let imageViewFrame = CGRect(x: pointX-(w/2), y: pointY-(h/2), width: w, height: h)
            let boxImage = makeBoxImage(width: w, height: h)
    
            let newImageView = UIImageView(frame: imageViewFrame)
            newImageView.image = boxImage
            newImageView.tag = nextTagForImage
            nextTagForImage += 1
    
            let tap = UITapGestureRecognizer(target: self, action: #selector(self.delete_tapped(_:)))
            newImageView.addGestureRecognizer(tap)
    
            let drag = UIPanGestureRecognizer(target: self, action: #selector(self.panView(sender:)))
            newImageView.isUserInteractionEnabled = true
            newImageView.addGestureRecognizer(drag)
    
            boxViewArray.append(newImageView)
    
            self.imageView.addSubview(newImageView)
        }
    
        func makeBoxImage(width w: CGFloat, height h: CGFloat) -> UIImage {
            print("makeBoxImage 開始")
            //イメージ処理の開始
            //### `CGSize(width: ImageView.frame.width, height: ImageView.frame.height)`は大き過ぎる
            let size = CGSize(width: w, height: h)
            UIGraphicsBeginImageContextWithOptions(size, false, 1.0)
            //コンテキスト
            let context = UIGraphicsGetCurrentContext()
            //サイズを決める
            let drawRect = CGRect(x: 0.0, y: 0.0, width: w, height: h)
            //パスを作る
            let drawPath = UIBezierPath(rect: drawRect)
            //塗り色
            //# 色が変わらないとテストしにくいのでランダムに選ぶようにしました
            let hue = CGFloat.random(in: 0.0...1.0)
            let fillColor = UIColor(hue: hue, saturation: 1.0, brightness: 1.0, alpha: 1.0)
            context?.setFillColor(fillColor.cgColor)
            //パスを塗る
            drawPath.fill()
            //線の色
            context?.setStrokeColor(red: 0.0, green: 1.0, blue: 1.0, alpha: 1.0)
            //パスを描く
            drawPath.stroke()
            //イメージコンテキストからUIImageを作る
            let image = UIGraphicsGetImageFromCurrentImageContext()
            //イメージ処理の終了
            UIGraphicsEndImageContext()
    
            return image!
        }
    
        @objc func panView(sender: UIPanGestureRecognizer){
            guard let targetView = sender.view as? UIImageView else {
                print("targetView is not UIImageView")
                return
            }
            //let tagNo = targetView.tag
            //print(tagNo)
            //移動量を取得
            let move = sender.translation(in: self.view)
            //ドラッグした部品の座標に移動量を加算
            targetView.center.x += move.x
            targetView.center.y += move.y
            //移動量を0に
            sender.setTranslation(CGPoint.zero, in: self.view)
        }
    
        @objc func delete_tapped(_ sender: UITapGestureRecognizer) {
            print("delete")
            guard let targetView = sender.view as? UIImageView else {
                print("targetView is not UIImageView")
                return
            }
            //targetView を`boxViewArray`から削除
            //...
            //targetView を`self.imageView`の子ビューから削除
            //...
        }
    }
    
[/code]

あなたのコードには「やってはいけない」や「いくら何でもこれはないだろう」と言う部分が多々見受けられましたので、その辺は修正してあります。

  * インスタンス変数またはローカル変数にすべきものがグローバル変数になっている

明確な目的と必要性があって、その動作を理解して使用するのでない限り、「グローバル変数は使ってはいけない」と思っておいた方がいいでしょう。

  * 使いもしないインスタンスを生成している部分がある
[code]     var tap = UITapGestureRecognizer()

    var drag = UIPanGestureRecognizer()
    
[/code]

とか

[code]     var tmp: UIImageView = UIImageView()

    tmp = UIImageView(image: boxImage)
    
[/code]

の部分ですが、あなたは使いもしないインスタンスを作成して、それで変数を初期化するくせがあるようです。
**使いもしないインスタンスで変数を初期化するのは絶対にやめるべき**
です。(本題じゃないのでなぜ「絶対に」かは省略しますが、残念ながらこんなコードはネット上に蔓延しています。ダメなものは真似しないでください。)

その他、いくら「作成段階で整理されていない」とは言え、もう要らないだろうと言う部分はバッサリ削除し、あまりにも酷い変数名も修正してあります。何かよくわからない点があればコメント等でお知らせ下さい。

* * *

なお、以上のコードはXcode
10用になっています。何らかの理由で古いXcodeを使用されているのであれば、その旨ご質問中に明記していただいた方がいいでしょう。


CC BY-SA 4.0
2018-10-10T22:17:59.333
49161
2018-10-10T22:39:57.820
2018-10-10T22:39:57.820
13972
13972
49151
answer