【问题标题】:Segue from UITableViewCell by tapping on an image inside of cell通过点击单元格内的图像从 UITableViewCell 中分离
【发布时间】:2016-07-31 11:36:59
【问题描述】:

我想解决这个问题已经有一段时间了,在寻找解决方案几个小时后,我决定是时候问了。

我有一个由自定义 UITableViewCells 填充的表格视图,当前当您点击一个单元格时,它会将您带到详细视图。

在自定义单元格中有一张图片,我希望用户能够点击该图片并转到显示该图片的弹出框 VC。

我遇到的问题是在点击图像时创建转场。

在自定义单元格的文件中,我在图像上设置了一个点击手势识别器(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


}

我在自定义单元格文件中也有一个用于水龙头的功能:

func imageTapped(sender: UIGestureRecognizer) {

  print("image tapped")


}

在我的视图控制器文件中,我在索引路径处的选择行中添加了一个 segue:

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)

}

另外,在情节提要中,我创建了一个从 VC 到我想在点击图像时显示的带有自定义单元格的 tableview 的 segue。

我已经尝试了几种不同的方法来使其工作,但没有任何运气,您在上面看到的代码是我多次尝试失败后剩下的代码。我觉得自定义单元格文件中的 tap 功能和 VC 文件中的 segue 是解决方案的一部分,所以我把它们留在里面。

任何帮助将不胜感激。谢谢!

从以下答案更新代码:

添加协议

protocol ImageSegueProtocol: class {
    func imageTapped(row: Int)
}


class PostCell: UITableViewCell {

添加了 IAB 功能

@IBAction func imageTapped(sender: UIGestureRecognizer) {
   guard let row = row else { return }
    delegate?.imageTapped(row)
    print("image tapped func")
}

在主 VC 中声明的委托

weak var delegate:postCell?

委派的德尔盖特

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

增加了扩展功能

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")
    }



}

【问题讨论】:

  • 您是否在表格视图单元格上创建了​​委托?
  • 嘿,冉,不,我没有

标签: ios swift uitableview xcode7 segue


【解决方案1】:

你可以这样做:

在单元格文件中,在顶部声明一个协议,然后在单元格类本身中设置一些属性以及代理行为以响应被点击的图像:

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)
    }
}

然后你必须让你的 ViewController 采用 SomeCellProtocol 并像这样调用 segue:

extension SomeViewController: SomeCellProtocol {

    func imageTapped(row: Int) {
        //get object from array and call segue here
    }
}

您必须通过调用将您的 ViewController 设置为您的单元格的代表:

someCell.delegate = self

并将行传递给单元格:

someCell.row = indexPath.row

在 ViewController 的 cellForRowAtIndexPath 方法中。

因此,当在单元格中点击按钮时(或者如果需要,您可以使用 ImageView 上的 GestureRecognizer 来执行此操作),它将强制委托(ViewController)调用其 imageTapped 函数,并传递一个行参数可用于确定表中的哪个对象(其对应的数据数组)应通过 Segue 传递。

【讨论】:

  • 谢谢罗斯,你能帮我从 VC 扩展的数组中获取对象吗?只需要解释一下您的确切含义
  • 基本上您需要知道要显示哪个对象的详细信息。您将行传递给单元格,它会在委托方法中将行返回给您,因此只需使用该行从数组中获取对象:如果您处于搜索模式或 let object = post[row] 如果没有!
  • 谢谢 那会是这样吗? extension FeedVC: ImageSegueProtocol { func imageTapped(row: Int) { if inSearchMode == true { let object = filteredVenues[row] performSegueWithIdentifier("imageTapped", sender: nil) } else { let object = posts[row] performSegueWithIdentifier("imageTapped", sender: nil) } } } 代表是:PostCell().delegate = self PostCell 是我的自定义单元格的文件
  • 将发送者设为对象,然后在 performSegueWithIdentifier 中获取发送者并将其传递给destinationViewController。设置委托将由 cellForRowAtIndexPath 中的 postCell.delegate = self 完成
  • 嘿罗斯,还是有一些麻烦。这就是我所做的: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") } } 也很困惑如何让代表postCell.delegate = self 工作,因为我在任何地方都没有postCell
【解决方案2】:

正如 OhadM 所说,创建一个按钮并将背景图像设置为您要显示的图像。从那里,您甚至不需要 IBAction。 按住 Control 从按钮拖动到下一个视图控制器并创建转场

然后,如果你想在 segue 之前做任何设置,在第一个 VC 中你会得到类似的东西:

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】:

    你需要做的是创建一个按钮而不是图像,这个按钮将保存实际的图像:

    剩下的很简单,按 ctrl 将 IBAction 拖入您的自定义单元格文件中。 现在您需要与您的视图控制器进行通信才能调用您的 segue 方法。

    您可以使用 2 种设计模式来实现:

    1. 使用post notification

      在你的 View Controller 中添加一个观察者:

      NSNotificationCenter.defaultCenter().addObserver(self,
                                selector: #selector(YourViewController.cellSelected(_:)),
                                name: "CellSelectedNotificationName",
                                object: nil)
      

      您的 View Controller 中的方法 cellSelected 应如下所示:

      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
        }
       }
      

      在按钮的 IBAction 方法中的 CustomCell 类中:

      @IBAction func buttonTapped()
      {
        // Prepare the object you want to pass...
        NSNotificationCenter.defaultCenter().postNotificationName("CellSelectedNotificationName", object: YourCustomObjectYouWantToPass)
       } 
      

      简而言之,点击单元格内的按钮,您在该单元格内创建了一个对象,然后使用通知中心将其传递给视图控制器。现在,您可以使用自定义对象进行 segue。

    注意:如果您不需要传递对象,您基本上可以 ctrl + 从 UIButton(在您的故事板中)拖动到另一个视图控制器。

    1. 使用指向视图控制器的delegate

    祝你好运。

    【讨论】:

    • 谢谢 Ohad,我会试试这个。你能给我一些关于需要指向 VC 的委托的信息吗?
    • 我已经为每个设计添加了链接,看看它们。如果您仍然不明白,请告诉我,我会添加一个示例。
    • 太棒了,谢谢,我会看看,如果需要的话会回复你
    • 嘿哦哈德,你能为我添加一个例子吗?
    • @ryanbilak,我已经用 NSNotificationCenter 的示例和 NOTE 部分中的另一个示例更新了答案。如果您需要委托示例,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多