问题
Been trying to figure this out for a while now and after a couple hours of searching for a solution I decided it was time to ask.
I have a tableview that gets populated by custom UITableViewCells and currently when you tap on a cell it takes you to a detail view.
Within the custom cell there is an image, I would like the user to be able to tap on that image and segue to a popover VC that shows the image.
What I'm having trouble with is creating the segue when the image is tapped.
In the file for the custom cell, I've set up a tap gesture recognizer on the image (pTap):
override func awakeFromNib() {
super.awakeFromNib()
let tap = UITapGestureRecognizer(target: self, action: #selector(PostCell.voteTapped(_:)))
let ptap = UITapGestureRecognizer(target: self, action: #selector(PostCell.imageTapped(_:)))
tap.numberOfTapsRequired = 1
ptap.numberOfTapsRequired = 1
voteImage.addGestureRecognizer(tap)
voteImage.userInteractionEnabled = true
featuredImg.addGestureRecognizer(ptap)
featuredImg.userInteractionEnabled = true
}
I also have a function in the custom cell file for the tap:
func imageTapped(sender: UIGestureRecognizer) {
print("image tapped")
}
In my view controller file I've added a segue in did select row at index path:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let post: Post!
if inSearchMode {
post = filteredVenues[indexPath.row]
} else {
post = posts[indexPath.row]
}
print(post?.venueName)
performSegueWithIdentifier("imageTapped", sender: nil)
performSegueWithIdentifier("DetailsVC", sender: post)
}
Also, in the storyboard I have created a segue from the VC that holds the tableview with the custom cells to the VC I'd like to show when the image is tapped.
I've tried several different methods of getting this to work and haven't had any luck, the code you see above are what remains after my many failed attempts. I feel that the function for the tap in the custom cell file and the segue in the VC file are a part of the solution so that is why I have left them in.
Any help would be appreciated. Thanks!
Updates to code from answers below:
Added protocol
protocol ImageSegueProtocol: class {
func imageTapped(row: Int)
}
class PostCell: UITableViewCell {
Added IAB Func
@IBAction func imageTapped(sender: UIGestureRecognizer) {
guard let row = row else { return }
delegate?.imageTapped(row)
print("image tapped func")
}
Declared delegate in the Main VC
weak var delegate:postCell?
Assigned Delgate
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//let post = posts[indexPath.row]
if let cell = tableView.dequeueReusableCellWithIdentifier("PostCell") as? PostCell {
var img: UIImage?
var vImg: UIImage?
postCell?.delegate = self
Added extension function
extension FeedVC: ImageSegueProtocol {
func imageTapped(row: Int) {
if inSearchMode == true {
let object = filteredVenues[row]
performSegueWithIdentifier("imageTapped", sender: object)
print("ext func")
} else {
let object = posts[row]
performSegueWithIdentifier("imageTapped", sender: object)
print("ext func")
}
}
回答1:
You could do it like this:
Within the cell file, declare a protocol at the top, and then set up some properties within the cell class itself and the delegate behaviour in response to the image being tapped:
protocol SomeCellProtocol: class {
func imageTapped(row: Int)
}
class SomeCell: UITableViewCell {
weak var delegate: SomeCellProtocol?
var row: Int?
@IBAction func imageTapped() {
guard let row = row else { return }
delegate?.imageTapped(row)
}
}
You must then make your ViewController adopt SomeCellProtocol and call the segue within like so:
extension SomeViewController: SomeCellProtocol {
func imageTapped(row: Int) {
//get object from array and call segue here
}
}
And you must set your ViewController as the delegate of your cells by calling:
someCell.delegate = self
and pass the row to the cell:
someCell.row = indexPath.row
within your cellForRowAtIndexPath method of the ViewController.
So, when the button is tapped within the cell (or you can do it with a GestureRecognizer on the ImageView if you want) it will force the delegate (the ViewController) to call its imageTapped function, passing a row parameter which you can use to determine which object in the table (its corresponding data array) should be passed via the Segue.
回答2:
As OhadM said, create a button and set the background image as the image you want displayed. From there, you don't even need an IBAction. Control-drag from the button to the next view controller and create the segue.
Then, if you want to do any setup before the segue, in the first VC you'd have something like:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "imageButtonPressed" { // Make sure you name the segue to match
let controller = segue.destinationViewController as! SecondVC
controller.someText = "Hi"
controller.someInt = 5
}
}
回答3:
What you need to do is to create a button instead of the image and this button will hold the actual image:
The rest is easy, ctrl drag an IBAction into your custom cell file. Now you need to communicate with your View Controller in order to invoke your segue method.
You can achieve that using 2 design patterns:
Using post notification:
Inside your View Controller add an observer:
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourViewController.cellSelected(_:)), name: "CellSelectedNotificationName", object: nil)Your method
cellSelectedinside your View Controller should look like this:func cellSelected(notification : NSNotification) { if let passedObject = notification.object as? YourCustomObject { // Do what ever you need with your passed object // When you're done, you can invoke performeSegue that will call prepareForSegue // When invoking performeSegue you can pass your custom object } }Inside your CustomCell class at the IBAction method of your button:
@IBAction func buttonTapped() { // Prepare the object you want to pass... NSNotificationCenter.defaultCenter().postNotificationName("CellSelectedNotificationName", object: YourCustomObjectYouWantToPass) }In a nut shell, a button inside a cell was tapped, you created an object inside that cell and you pass it to a View Controller using the notification centre. Now, you can segue with your custom object.
NOTE: If you don't need to pass an object you can basically ctrl + drag from your UIButton (at your storyboard) to another View Controller.
- Using a delegate that is pointing to the View Controller.
Good luck.
来源:https://stackoverflow.com/questions/38683564/segue-from-uitableviewcell-by-tapping-on-an-image-inside-of-cell