索引数组中的最后一项对UIPanGestureRecognizer无响应

问题描述 投票:0回答:1

我下面的快捷代码应该在调用函数时添加图像视图。然后,当它按下时应该四处移动。现在,第一次按下按钮时,图像视图不起作用,但是如果两次调用该功能,则第一次图像视图会移动。如果函数被调用了3次,则第一个和第二个图像视图会移动,而第三个图像视图则不会。当imageview放在屏幕上时,我希望它立即移动

import UIKit

class ViewController: UIViewController {

    var myArray = [UIImageView]()
    var bt = UIButton()
    var count : Int = 0
    var pgGesture = UIPanGestureRecognizer()
    var ht = -90

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(bt)
        bt.backgroundColor = UIColor.systemOrange
        bt.frame = CGRect(x: view.center.x - 80, y: view.center.y , width: 50, height: 50)
        bt.addTarget(self, action: #selector(add), for: .touchUpInside)
    }

    @objc func add() { 
        pgGesture = UIPanGestureRecognizer(target: self, action: #selector(ViewController.pgGestureMethod(_:)))

        for index in myArray.indices {
            myArray[index].isUserInteractionEnabled = true
            myArray[index].addGestureRecognizer(pgGesture)
            myArray[index].tag = index
        }

        myArray.insert(UIImageView(), at: count)

        myArray[count].frame = CGRect(x: view.center.x - 0, y: view.center.y + CGFloat(ht), width: 50, height: 30)
        myArray.forEach({
            $0.backgroundColor = UIColor.systemTeal
            self.view.addSubview($0)
        })

        count += 1
        ht += 50  
    }

    @objc func pgGestureMethod(_ sender: UIPanGestureRecognizer){
        self.view.bringSubviewToFront(sender.view!)
        let tranistioon = sender.translation(in: self.view)
        sender.view!.center = CGPoint(x: sender.view!.center.x + tranistioon.x, y: sender.view!.center.y + tranistioon.y)
        sender.setTranslation(CGPoint.zero,in: self.view)    
    }
}
arrays swift for-loop indexing uipangesturerecognizer
1个回答
0
投票

这里有几个问题:

  1. 您的手势识别器处理程序正在更新手势视图的center。显然,其目的是将该手势添加到要拖动的视图中。

    所以这里的主要问题是您将手势识别器添加到错误的视图。您应该将其添加到蓝绿色的可拖动视图中,但是要将其添加到主视图中。

  2. 无关,但是add方法正在做很多不必要的事情。假设您要添加第100个新的蓝绿色子视图。为什么还要再次重新更新以前的99个子视图?

    只需配置要添加的视图,并消除那些不必要的for / forEach循环。

  3. 再次,无关,但我建议在使用center时要多加注意。这是该视图位于其父视图内的位置。因此,在视图控制器的view中添加按钮和蓝绿色子视图时,应引用view.bounds.midX.midY,而不是view.center。因为视图占据了整个屏幕,所以您将不会真正看到其中的差异,但是如果视图控制器是另一个视图的子视图控制器,那么会有很大的差异。

因此:

class ViewController: UIViewController {
    // var mySubviews = [UIImageView]()
    var addButton = UIButton()
    var count: Int = 0
    var ht = -90

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(addButton)
        addButton.backgroundColor = .systemOrange
        addButton.frame = CGRect(x: view.bounds.midX - 80, y: view.bounds.midY, width: 50, height: 50)
        addButton.addTarget(self, action: #selector(didTapAdd), for: .touchUpInside)
    }

    @objc func didTapAdd() {
        let subview = UIImageView()
        subview.isUserInteractionEnabled = true
        view.addSubview(subview)
        subview.frame = CGRect(x: view.bounds.midX - 0, y: view.bounds.midY + CGFloat(ht), width: 50, height: 30)
        subview.backgroundColor = .systemTeal
        subview.tag = count

        let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
        subview.addGestureRecognizer(pan)

        count += 1
        ht += 50
        // mySubviews.append(subview)
    }

    @objc func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
        let draggedView = gesture.view!
        view.bringSubviewToFront(draggedView)
        let translation = gesture.translation(in: view)
        draggedView.center = CGPoint(x: draggedView.center.x + translation.x, y: draggedView.center.y + translation.y)
        gesture.setTranslation(.zero, in: view)
    }
}

一些最终结论:

  1. 我不鼓励使用tag。可以用于诊断目的,就可以了。

  2. 在我的代码段中,我也注释掉了声明,并将其追加到子视图数组中,因为这完全没有必要。

  3. 请原谅,但我已将方法和变量重命名。

  4. 我不确定您为什么使用UIImageView。除非您确实打算在以后再添加图片,否则我会亲自使用UIView


0
投票

好的,您可以尝试一下。这就是我所做的更改:pgGesture的声明现在是可选的(无需初始化两次,这就是您在代码中所做的事情),将pgGesture的初始化移至ViewDidLoad而不是放在addFunction内部(它只需要初始化一次,而不是每次调用add()函数都进行初始化),最后(这是您看到的问题的原因),我在插入图像之前将pgGesture添加到了图像中(以前您没有分配panGesture到要插入的图像,而不是到数组的所有其他条目)。

import UIKit

class ViewController: UIViewController {

    var myArray = [UIImageView]()
    var bt = UIButton()
    var count : Int = 0
    var pgGesture: UIPanGestureRecognizer?
    var ht = -90

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(bt)
        bt.backgroundColor = UIColor.systemOrange
        bt.frame = CGRect(x: view.center.x - 80, y: view.center.y , width: 50, height: 50)
        bt.addTarget(self, action: #selector(add), for: .touchUpInside)
        pgGesture = UIPanGestureRecognizer(target: self, action: #selector(ViewController.pgGestureMethod(_:)))

    }

    @objc func add() { 

        for index in myArray.indices {
            myArray[index].isUserInteractionEnabled = true
            myArray[index].tag = index
        }

        let imageToInsert = UIImageView()
        imageToInsert.addGestureRecognizer(pgGesture)
        myArray.insert(UIImageView(), at: count)

        myArray[count].frame = CGRect(x: view.center.x - 0, y: view.center.y + CGFloat(ht), width: 50, height: 30)
        myArray.forEach({
            $0.backgroundColor = UIColor.systemTeal
            self.view.addSubview($0)
        })

        count += 1
        ht += 50  
    }

    @objc func pgGestureMethod(_ sender: UIPanGestureRecognizer){
        self.view.bringSubviewToFront(sender.view!)
        let tranistioon = sender.translation(in: self.view)
        sender.view!.center = CGPoint(x: sender.view!.center.x + tranistioon.x, y: sender.view!.center.y + tranistioon.y)
        sender.setTranslation(CGPoint.zero,in: self.view)    
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.