Uitableview 可点击的可视单元格,其中还有一个可点击的按钮

Uitableview 可点击的可视单元格,其中还有一个可点击的按钮,uitableview,swift,Uitableview,Swift,我有一个原型单元,上面有一些标签和一个按钮(实际上是一个imageView,不是一个按钮): 我想实现这种行为: 点击按钮执行某些代码,比如说println(“foo”),但不执行“显示详细信息”序列 点击单元格的其余部分,执行“显示细节”序列 如果要求1不是必需的,我会这样做: override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { select

我有一个原型单元,上面有一些标签和一个按钮(实际上是一个imageView,不是一个按钮):

我想实现这种行为:

  • 点击按钮执行某些代码,比如说
    println(“foo”)
    ,但不执行“显示详细信息”序列
  • 点击单元格的其余部分,执行“显示细节”序列
  • 如果要求1不是必需的,我会这样做:

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        selectedPlace = places[indexPath.row]
        self.performSegueWithIdentifier("ShowPlaceSegue", sender: self)
    }
    
    实现这一目标的推荐方法是什么?
    这与HTML DOM事件不同?(z指数等)

    我尝试了(非常简单的尝试)以下几点:

    class PlaceTableViewCell: UITableViewCell {
    
        @IBOutlet weak var favoritedImageView: UIImageView!
        @IBOutlet weak var nameLabel: UILabel!
        @IBOutlet weak var administrativeAreaLevel3: UILabel!
    
        func configureCellWith(place: Place) {
           nameLabel.text = place.name
           administrativeAreaLevel3.text = place.administrativeAreaLevel3
           favoritedImageView.addGestureRecognizer(UIGestureRecognizer(target: self, action:Selector("bookmarkTapped:")))
        }
    
        func bookmarkTapped(imageView: UIImageView) {
           println("foo")
        }
    }
    
    但无论我单击imageView还是单元格的其余部分,都会执行“show detail”序列,而不会打印“foo”

    在包含标签的原型单元中放置UIView“v”并使“v”可点击,您认为如何?大概是这样的:


    如果我这样做,当点击时,单元格会变灰吗?我想保留…

    对不起,这是个愚蠢的问题:

    “奈夫”之路确实是一条必经之路。事实上,它的工作原理就像HTMLDOM

    但我改变了这一点:

    func configureCellWith(place: Place) {
       nameLabel.text = place.name
       administrativeAreaLevel3.text = place.administrativeAreaLevel3
       favoritedImageView.addGestureRecognizer(UIGestureRecognizer(target: self, action:Selector("bookmarkTapped:")))
    }
    
    func bookmarkTapped(imageView: UIImageView) {
       println("foo")
    }
    
    为此:

    func configureCellWith(place: Place) {
       nameLabel.text = place.name
       administrativeAreaLevel3.text = place.administrativeAreaLevel3
    
       let gestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("bookmarkTapped:"))
       gestureRecognizer.numberOfTapsRequired = 1
    
       favoritedImageView.userInteractionEnabled = true
       favoritedImageView.addGestureRecognizer(gestureRecognizer)
    }
    
    func bookmarkTapped(sender: UIImageView!) {
       println("foo")
    }
    
    如您所见,我使用的是
    uigesturecognizer
    ,而不是
    uicapgesturecognizer



    编辑:

    因此,上面所说的是对的,但是现在我认为最好在包含tableView的类中使用action函数,而不是在cell类中使用action函数

    因此,我已将
    addGestureRecognizer
    移动到
    cellForRowAtIndexPath
    方法,即:

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("PlacePrototype", forIndexPath: indexPath) as! PlaceTableViewCell
    
        // Configure the cell
        let place = places[indexPath.row]
    
        cell.configureCellWith(place)
    
        // HERE!
        let gestureRecognizer = UITapGestureRecognizer(target: self, action:Selector("bookmarkTapped:"))
        gestureRecognizer.numberOfTapsRequired = 1
    
        cell.favoritedImageView.userInteractionEnabled = true
        cell.favoritedImageView.addGestureRecognizer(gestureRecognizer)
    
        return cell
    }
    
    以及行动:

    func bookmarkTapped(gestureRecognizer: UIGestureRecognizer) {
        // println("foo")
    
        var point = gestureRecognizer.locationInView(self.tableView)
    
        if let indexPath = self.tableView.indexPathForRowAtPoint(point)
        {
            places[indexPath.row].toggleBookmarked()
            self.tableView.reloadData()
        }
    }
    

    假设您的tableView可以显示五个单元格,那么
    cellForRow
    将被调用五次,并且您将向五个不同的图像视图添加
    UITapgestureRecognitor
    。但是,当您滚动到第七个单元格时,您将在cellForRow中获得一个重用的单元格(可能是第一个单元格),该单元格的imageView有一个UITapGestureRecognitizer,如果您再次将UITapGestureRecognitizer添加到imageView中,将导致您点击一次触发多次

    您可以尝试以下方法:

    class PlaceTableViewCell: UITableViewCell {
    
        @IBOutlet weak var favoritedImageView: UIImageView!
        var favoritedTappedBlock: ((Void) -> Void)? // block as callback
    
        override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
    
            commonInit()
        }
    
        required init(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
    
            commonInit()
        }
    
        private func commonInit() {
            let gestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("favoritedImageViewTapped"))
            gestureRecognizer.numberOfTapsRequired = 1
    
            favoritedImageView.addGestureRecognizer(gestureRecognizer)
            favoritedImageView.userInteractionEnabled = true
        }
    
        private func favoritedImageViewTapped() {
            if let favoritedTappedBlock = self.favoritedTappedBlock {
                favoritedTappedBlock()
            }
        }
    }
    
    cellForRow

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("PlacePrototype", forIndexPath: indexPath) as! PlaceTableViewCell
    
        // Configure the cell
        let place = places[indexPath.row]
    
        cell.configureCellWith(place)
    
        cell.favoritedTappedBlock = {
            println("tapped")
        }
    
        return cell
    }
    

    userInteractionEnabled
    很重要,如果是
    NO
    ,它将导致触摸事件(
    UIView
    uigesturecognizer
    )不会被触发。我认为最重要的是我使用的是
    uigesturecognizer
    ,而不是
    uiapgesturecognizer
    。还更改了允许我使用
    .numberOfTapsRequired=1
    。我不确定是否需要编程设置
    userInteractionEnabled
    ,因为在故事板中,我看到imageView已经为true,在
    cellForRow
    中添加手势识别器是危险的。UITableView单元格将被重用,您每次实例化一个新的UIAPTgestureRecognitor,但是,单元格的favoritedImageView可能有一个UIAPTgestureRecognitor。