我下面的快捷代码应该在调用函数时添加图像视图。然后,当它按下时应该四处移动。现在,第一次按下按钮时,图像视图不起作用,但是如果两次调用该功能,则第一次图像视图会移动。如果函数被调用了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)
}
}
这里有几个问题:
您的手势识别器处理程序正在更新手势视图的center
。显然,其目的是将该手势添加到要拖动的视图中。
所以这里的主要问题是您将手势识别器添加到错误的视图。您应该将其添加到蓝绿色的可拖动视图中,但是要将其添加到主视图中。
无关,但是add
方法正在做很多不必要的事情。假设您要添加第100个新的蓝绿色子视图。为什么还要再次重新更新以前的99个子视图?
只需配置要添加的视图,并消除那些不必要的for
/ forEach
循环。
再次,无关,但我建议在使用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)
}
}
一些最终结论:
我不鼓励使用tag
。可以用于诊断目的,就可以了。
在我的代码段中,我也注释掉了声明,并将其追加到子视图数组中,因为这完全没有必要。
请原谅,但我已将方法和变量重命名。
我不确定您为什么使用UIImageView
。除非您确实打算在以后再添加图片,否则我会亲自使用UIView
。
如果要对按钮的frame
进行硬编码,则不能在viewDidLoad
中执行此操作(因为尚未布置视图)。如果要设置frame
,则需要在viewDidLayoutSubviews
中进行设置。您可以在viewDidLoad
中设置约束,但不能在帧中设置。
好的,您可以尝试一下。这就是我所做的更改: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)
}
}