问题
I would like to implement feature that if profileImage tapped in tableviewCell, segue to detailView. I add tapGesture but I still can't figure out how to get indexPath to pass data. I tried like this but app will crash.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "detailSegue" {
let next: DetailViewController = segue.destination as! DetailViewController
// pattern1
let indexPath = tableView.indexPath(for: sender as! CustomTableViewCell)
// pattern2
let indexPath = tableView.indexPathForSelectedRow! as NSIndexPath
next.data = datas[indexPath.row]
}
}
How can I fix this? Thank you in advance!
回答1:
1: set tag of ImageView in cellForRowAtIndexpath method , tag will be equal to indexPath.row
imgView.tag = indexPath.row
2: add a target to tapGuestureRecognizer attached on imageView
3: get tag of imageView in that method
let imgView = sender as! UIImageView
let tag = imgView.tag
4: get data accordingly ,and push
let next = self.storyBoard.instatiateViewController(WithIdentifer:"detailVC")
next.data = datas[tag]
self.navigationController.pushViewController(next)
回答2:
If you add
UITapGestureRecognizer
to anUIImageView
then don't forget to setisUserInteractionEnabled
property totrue
.
Create a variable to store selected indexPath.row
var selectedCell:Int!
In cellForRow
method add gesture to the image view.
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tapBtnAction(_:)))
cell.imageView.tag = indexPath.row
cell.imageView.addGestureRecognizer(tapGesture)
In target method perform segue
func tapBtnAction(_ sender: UITapGestureRecognizer) {
print("\(sender.view.tag) Tapped")
self.selectedCell = sender.view.tag
self.performSegueWithIdentifier("detailSegue", sender: self)
}
In prepareforsegue
method get data from the array.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "detailSegue" {
let next: DetailViewController = segue.destination as! DetailViewController
next.data = datas[self.selectedCell]
}
}
回答3:
Solution 1 : use touchBegun method, make sure imageView UserInteraction is enable
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let cell = touch?.view?.superview?.superview as? YourCellClass {
let indexPath = yourTablView.indexPath(for: cell)
//Do whatever you want
}
}
Solution 2: you can use button.
@IBAction func onBtnClick(_ sender : UIButton) {
if let cell = sender.superview?.superview as? UITableViewCell {
let indexPath = tbl_songsInfo.indexPath(for: cell)
//Do whatever you want
}
}
Solution 3 : Same as above but use sender.tag
@IBAction func onBtnClick(_ sender : UIButton) {
let data = yourDataArray[sender.tag]
//Do whatever you want
}
回答4:
I have made a sample project to demonstrate the solution. It is working perfectly fine. See the gif!
You can download the sample project code using the link https://drive.google.com/file/d/1zF8Uq2H6eQYyrHU6KqnZu7b5cU_HtZY0/view?usp=sharing
Actually, you have to add a gesture recognizer to your image and attach an action to this gesture. See the implementation of cellforRowAt.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:"TableViewCellUser") as! TableViewCellUser
//handle image and its gesture
cell.imgUser.image = userImagesArray[indexPath.row]
//enable the interaction so that touch could be captured.
cell.imgUser.isUserInteractionEnabled = true
let gesture = UITapGestureRecognizer(target: self, action: #selector(userImageTapped(gesture:)))
gesture.numberOfTouchesRequired = 1
gesture.delegate = self as? UIGestureRecognizerDelegate
cell.imgUser.tag = indexPath.row
cell.imgUser.addGestureRecognizer(gesture)
//handle label
cell.lblUserName.text = userNames[indexPath.row]
return cell
}
//action on user tap
guard let indexPathRow = gesture.view?.tag else {
return
}
print(indexPathRow)
guard indexPathRow >= 0 else {
print("Array index must be greater than zero. Going to return")
return
}
selectedUserImage = userImagesArray[indexPathRow]
selectedUserName = userNames[indexPathRow]
self.performSegue(withIdentifier: "UsersToDetail", sender: self)
You can download the fully working code from the above mentiond link. Let me know in comments if any problem Occurs
This link will also help [UITapGestureRecognizer tag]: unrecognized selector sent to instance
回答5:
There are multiple ways to achieve this, but the easiest way would be adding the UIButton above the UIImageView. and setting the tag of the UIButton with respect to IndexPath of the UITableViewCell and add the click event of the UIButton.
cell.btnImage.tag = indexPath.row
when the user tries to click the UIImage, UIButton above the image will be clicked and click event of the button will be triggered, here you can you can get the index of the UIButton tapped which is same as UIImageView in that particular cell.
@IBAction func BtnClick(_ sender : UIButton) {
print(sender.tag)//here you will get the IndexPath for that particular UIImageView in Cell.
}
来源:https://stackoverflow.com/questions/48739894/how-to-get-indexpath-when-image-inside-cell-tapped