I have a problem with the UITapGestureRecognizer. I use this code :
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.SelectPictureAction(_:)))
cardView.addGestureRecognizer(gesture)
and my function here :
@objc func SelectPictureAction(_ sender : UITapGestureRecognizer) {
print("card moment is Tapped")
}
The problem is I tap my card and nothing happen. I think the problem is I install a gesture in a UIView that is not init in the same class...
So my question is :
This is possible there are a trouble when I add a
gesture
in a UIView called in another class ?
this is the code of my 3 class I used :
TableView Code :
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(CardCell.self, forCellReuseIdentifier: "Cell")
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:"Cell") as! CardCell
cell.widthOfDevice = tableView.bounds.size.width
if indexPath.row == 1 {
cell.doTheWork(statutOfCard: .selectMoment)
}else{
cell.doTheWork(statutOfCard: .goMoment(picture:#imageLiteral(resourceName: "img2")))
}
return cell
}
}
CardCell code :
class CardCell : UITableViewCell {
let cardView = UIView()
enum statut {
case selectMoment
case goMoment(picture: UIImage)
}
func doTheWork(statutOfCard : statut){
switch statutOfCard {
case .selectMoment:
self.drawMomentPicture()
case .goMoment(let picture):
self.drawGoMoment(image: picture)
default:
cardViewHeightCon.constant = 300
self.addCardShadow()
}
}
func drawMomentPicture(){
if(cardIsDraw == false){
widthOfCard = widthOfDevice - (widthMarginConstraint*2)
cardViewHeightCon.constant = widthOfCard!*ratioOfImage
_ = SelectMoment(countUserMoment: 1, cardView: self.cardView, tableViewCell: self) // Here I call my class
self.addCardShadow()
cardIsDraw = true
}
}
}
SelectMoment code :
class SelectMoment {
let countUserMoment: Int
let cardView : UIView
let selfTableViewCell : UITableViewCell
init(countUserMoment: Int, cardView : UIView, tableViewCell : UITableViewCell) {
self.countUserMoment = countUserMoment
self.cardView = cardView
self.selfTableViewCell = tableViewCell
self.drawCard()
}
func drawCard(){
cardView.backgroundColor = .yellow
cardView.isUserInteractionEnabled = true
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.SelectMomentAction(_:)))
cardView.addGestureRecognizer(gesture)
}
@objc func SelectMomentAction(_ sender : UITapGestureRecognizer) {
print("card moment is Tapped")
}
}
What you want is probably something like a helper struct:
struct SelectMoment {
// ...
}
class CardCell : UITableViewCell {
var selectMoment : SelectMoment!
override func viewDidLoad() {
super.viewDidLoad()
self.selectMoment = SelectMoment(...)
// ...
}
// ...
}
Now your SelectMoment struct instance has a place to live in connection with your CardCell instance, and the CardCell can see it; with the right properties, they can even talk back and forth to each other with no problem.
Please note that that architecture is just a sketch to show you how to separate the powers of the two types. I don't know your intended use case. Maybe what you want is to be able to assign a SelectMoment differently configured to each different cell type. In that case, don't set selectMoment
in viewDidLoad
; allow some other class to set it (possibly through the initializer or possibly just by setting it directly), and respond accordingly. That architecture is called dependency injection.