Swift - 如何将点击手势添加到 UIView 数组?
Swift - How to add tap gesture to array of UIViews?
希望将点击手势添加到 UIView
数组 - 但没有成功。 Tap 似乎在这个阶段无法被识别。
在下面的代码(摘录)中:
在主视图上显示一系列 PlayingCardViews
(每个 UIView
)。
汇集为一个数组:cardView
。
需要能够独立地点击每个 PlayingCardView
(然后能够识别被点击的是哪一个)。
@IBOutlet private var cardView: [PlayingCardView]!
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(tapCard(sender: )))
for index in cardView.indices {
cardView[index].isUserInteractionEnabled = true
cardView[index].addGestureRecognizer(tap)
cardView[index].tag = index
}
}
@objc func tapCard (sender: UITapGestureRecognizer) {
if sender.state == .ended {
let cardNumber = sender.view.tag
print("View tapped !")
}
}
你需要
@objc func tapCard (sender: UITapGestureRecognizer) {
let clickedView = cardView[sender.view!.tag]
print("View tapped !" , clickedView )
}
这里不需要检查状态,因为这种手势类型的方法只被调用一次,而且每个视图都应该有一个单独的点击,所以在 for 循环中创建它
for index in cardView.indices {
let tap = UITapGestureRecognizer(target: self, action: #selector(tapCard(sender: )))
您可以尝试将视图控制器作为参数传递给视图,以便它们可以从视图调用父视图控制器上的函数。要减少内存,您可以使用协议。 e.x
protocol testViewControllerDelegate: class {
func viewTapped(view: UIView)
}
class testClass: testViewControllerDelegate {
@IBOutlet private var cardView: [PlayingCardView]!
override func viewDidLoad() {
super.viewDidLoad()
for cardView in self.cardView {
cardView.fatherVC = self
}
}
func viewTapped(view: UIView) {
// the view that tapped is passed ass parameter
}
}
class PlayingCardView: UIView {
weak var fatherVC: testViewControllerDelegate?
override func awakeFromNib() {
super.awakeFromNib()
let gr = UITapGestureRecognizer(target: self, action: #selector(self.viewDidTap))
self.addGestureRecognizer(gr)
}
@objc func viewDidTap() {
fatherVC?.viewTapped(view: self)
}
}
我不会推荐所选答案。因为在循环中创建一个 tapGesture 数组对我来说没有意义。最好在 PlaycardView 中添加手势。
相反,这种布局应该使用 UICollectionView 来设计。如果万一您需要自定义布局并且想要使用 scrollView 甚至 UIView,那么更好的方法是创建单个手势识别器并添加到超级视图。
使用点击手势,您可以获得点击的位置,然后您可以使用该位置获取 selectedView。
请参考下面的例子:
import UIKit
class PlayCardView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.red
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
backgroundColor = UIColor.red
}
}
class SingleTapGestureForMultiView: UIViewController {
var viewArray: [UIView]!
var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
scrollView = UIScrollView(frame: UIScreen.main.bounds)
view.addSubview(scrollView)
let tapGesture = UITapGestureRecognizer(target: self,
action: #selector(tapGetsure(_:)))
scrollView.addGestureRecognizer(tapGesture)
addSubviews()
}
func addSubviews() {
var subView: PlayCardView
let width = UIScreen.main.bounds.width;
let height = UIScreen.main.bounds.height;
let spacing: CGFloat = 8.0
let noOfViewsInARow = 3
let viewWidth = (width - (CGFloat(noOfViewsInARow+1) * spacing))/CGFloat(noOfViewsInARow)
let viewHeight = (height - (CGFloat(noOfViewsInARow+1) * spacing))/CGFloat(noOfViewsInARow)
var yCordinate = spacing
var xCordinate = spacing
for index in 0..<20 {
subView = PlayCardView(frame: CGRect(x: xCordinate, y: yCordinate, width: viewWidth, height: viewHeight))
subView.tag = index
xCordinate += viewWidth + spacing
if xCordinate > width {
xCordinate = spacing
yCordinate += viewHeight + spacing
}
scrollView.addSubview(subView)
}
scrollView.contentSize = CGSize(width: width, height: yCordinate)
}
@objc
func tapGetsure(_ gesture: UITapGestureRecognizer) {
let location = gesture.location(in: scrollView)
print("location = \(location)")
var locationInView = CGPoint.zero
let subViews = scrollView.subviews
for subView in subViews {
//check if it subclass of PlayCardView
locationInView = subView.convert(location, from: scrollView)
if subView.isKind(of: PlayCardView.self) {
if subView.point(inside: locationInView, with: nil) {
// this view contains that point
print("Subview at \(subView.tag) tapped");
break;
}
}
}
}
}
希望将点击手势添加到 UIView
数组 - 但没有成功。 Tap 似乎在这个阶段无法被识别。
在下面的代码(摘录)中:
在主视图上显示一系列 PlayingCardViews
(每个 UIView
)。
汇集为一个数组:cardView
。
需要能够独立地点击每个 PlayingCardView
(然后能够识别被点击的是哪一个)。
@IBOutlet private var cardView: [PlayingCardView]!
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(tapCard(sender: )))
for index in cardView.indices {
cardView[index].isUserInteractionEnabled = true
cardView[index].addGestureRecognizer(tap)
cardView[index].tag = index
}
}
@objc func tapCard (sender: UITapGestureRecognizer) {
if sender.state == .ended {
let cardNumber = sender.view.tag
print("View tapped !")
}
}
你需要
@objc func tapCard (sender: UITapGestureRecognizer) {
let clickedView = cardView[sender.view!.tag]
print("View tapped !" , clickedView )
}
这里不需要检查状态,因为这种手势类型的方法只被调用一次,而且每个视图都应该有一个单独的点击,所以在 for 循环中创建它
for index in cardView.indices {
let tap = UITapGestureRecognizer(target: self, action: #selector(tapCard(sender: )))
您可以尝试将视图控制器作为参数传递给视图,以便它们可以从视图调用父视图控制器上的函数。要减少内存,您可以使用协议。 e.x
protocol testViewControllerDelegate: class {
func viewTapped(view: UIView)
}
class testClass: testViewControllerDelegate {
@IBOutlet private var cardView: [PlayingCardView]!
override func viewDidLoad() {
super.viewDidLoad()
for cardView in self.cardView {
cardView.fatherVC = self
}
}
func viewTapped(view: UIView) {
// the view that tapped is passed ass parameter
}
}
class PlayingCardView: UIView {
weak var fatherVC: testViewControllerDelegate?
override func awakeFromNib() {
super.awakeFromNib()
let gr = UITapGestureRecognizer(target: self, action: #selector(self.viewDidTap))
self.addGestureRecognizer(gr)
}
@objc func viewDidTap() {
fatherVC?.viewTapped(view: self)
}
}
我不会推荐所选答案。因为在循环中创建一个 tapGesture 数组对我来说没有意义。最好在 PlaycardView 中添加手势。
相反,这种布局应该使用 UICollectionView 来设计。如果万一您需要自定义布局并且想要使用 scrollView 甚至 UIView,那么更好的方法是创建单个手势识别器并添加到超级视图。
使用点击手势,您可以获得点击的位置,然后您可以使用该位置获取 selectedView。
请参考下面的例子:
import UIKit
class PlayCardView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.red
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
backgroundColor = UIColor.red
}
}
class SingleTapGestureForMultiView: UIViewController {
var viewArray: [UIView]!
var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
scrollView = UIScrollView(frame: UIScreen.main.bounds)
view.addSubview(scrollView)
let tapGesture = UITapGestureRecognizer(target: self,
action: #selector(tapGetsure(_:)))
scrollView.addGestureRecognizer(tapGesture)
addSubviews()
}
func addSubviews() {
var subView: PlayCardView
let width = UIScreen.main.bounds.width;
let height = UIScreen.main.bounds.height;
let spacing: CGFloat = 8.0
let noOfViewsInARow = 3
let viewWidth = (width - (CGFloat(noOfViewsInARow+1) * spacing))/CGFloat(noOfViewsInARow)
let viewHeight = (height - (CGFloat(noOfViewsInARow+1) * spacing))/CGFloat(noOfViewsInARow)
var yCordinate = spacing
var xCordinate = spacing
for index in 0..<20 {
subView = PlayCardView(frame: CGRect(x: xCordinate, y: yCordinate, width: viewWidth, height: viewHeight))
subView.tag = index
xCordinate += viewWidth + spacing
if xCordinate > width {
xCordinate = spacing
yCordinate += viewHeight + spacing
}
scrollView.addSubview(subView)
}
scrollView.contentSize = CGSize(width: width, height: yCordinate)
}
@objc
func tapGetsure(_ gesture: UITapGestureRecognizer) {
let location = gesture.location(in: scrollView)
print("location = \(location)")
var locationInView = CGPoint.zero
let subViews = scrollView.subviews
for subView in subViews {
//check if it subclass of PlayCardView
locationInView = subView.convert(location, from: scrollView)
if subView.isKind(of: PlayCardView.self) {
if subView.point(inside: locationInView, with: nil) {
// this view contains that point
print("Subview at \(subView.tag) tapped");
break;
}
}
}
}
}