可点击的UITableViewCell,其中还有一个可点击的按钮

时间:2015-05-29 05:09:18

标签: uitableview swift

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

Prototype cell

我想实现这种行为:

  1. 点击该按钮会执行某些代码,例如println("foo"),但不会执行"显示详细信息"原因请看
  2. 点击单元格的其余部分执行show detail segue
  3. 如果不需要#1,我就这样做:

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        selectedPlace = places[indexPath.row]
        self.performSegueWithIdentifier("ShowPlaceSegue", sender: self)
    }
    

    建议的方法是什么?
    这不像HTML DOM事件? (z-index等)

    我尝试了(以非常天真的方式)以下内容:

    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或其他单元格,"显示详细信息"执行segue并且" foo"没有印刷。

    您如何看待将UIView," v"放入包含标签的原型单元格中并制作" v"可点击?像这样的东西:

    UIView inside the table cell prototype

    如果我这样做,那么在敲击时细胞会变灰吗?我想保留它......

2 个答案:

答案 0 :(得分:0)

抱歉,这是一个愚蠢的问题:

“天真”的方式确实是要走的路。实际上它就像HTML DOM一样!...

但我改变了这个:

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

如您所见,我使用UIGestureRecognizer代替UITapGestureRecognizer



编辑:

所以,上面的说法是正确的,但现在我认为在包含tableView的类中使用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()
    }
}

答案 1 :(得分:0)

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

你可以试试这个:

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
}