【问题标题】:last item in index array not responsive to UIPanGestureRecognizer索引数组中的最后一项不响应 UIPanGestureRecognizer
【发布时间】:2020-03-24 09:43:22
【问题描述】:

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

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)    
    }
}

【问题讨论】:

  • 不确定这是否能解决您的问题,但无论如何您应该将以下行 pgGesture = UIPanGestureRecognizer(target: self, action: #selector(ViewController.pgGestureMethod(_:))) 放在 ViewdidLoad 中,而不是放在 add() 函数中。
  • 同样的事情正在发生,没有任何变化。

标签: arrays swift for-loop indexing uipangesturerecognizer


【解决方案1】:

这里有几个问题:

  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.addTarget(self, action: #selector(didTapAdd(_:)), for: .touchUpInside)
    }


    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        addButton.frame = CGRect(x: view.bounds.midX - 80, y: view.bounds.midY, width: 50, height: 50)
    }

    @objc func didTapAdd(_ sender: UIButton) {
        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. 在我的代码 sn-p 中,我还注释掉了声明并​​附加到子视图数组中,因为这完全没有必要。

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

  4. 我不确定你为什么使用UIImageView。我个人会使用UIView,除非你真的打算在以后添加图片。

  5. 如果您要硬编码按钮的frame,则不能在viewDidLoad 中执行此操作(因为尚未布置视图)。如果您要设置frame,您需要在viewDidLayoutSubviews 中进行设置。您可以在viewDidLoad 中设置约束,但不能在框架中设置。

【讨论】:

    【解决方案2】:

    好的,不如你试试这个。这就是我更改的内容: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)    
        }
    }
    

    【讨论】:

    • 我在 imageToInsert.addGestureRecognizer(pgGesture) 处遇到编译错误。说明它必须被打开。我在它构建的 pgGesture 末尾放了一个感叹号,但是触摸时没有任何移动图像视图也没有移动。
    • 我想我在这里遗漏了一些信息。首先,确保在测试代码时从头开始使用空数组,否则它将无法工作。另外,您为什么要启用用户交互?您是否在任何地方禁用它?为什么?
    猜你喜欢
    • 1970-01-01
    • 2021-11-11
    • 2019-11-20
    • 2013-09-14
    • 2010-11-06
    • 2011-03-17
    • 1970-01-01
    • 2015-01-27
    • 2015-11-12
    相关资源
    最近更新 更多