如何知道在 UICollectionView 中点击了自定义单元格的哪一部分?

Posted

技术标签:

【中文标题】如何知道在 UICollectionView 中点击了自定义单元格的哪一部分?【英文标题】:How to know which part of a customised cell have been clicked on in UICollectionView? 【发布时间】:2017-04-21 13:02:40 【问题描述】:

我正在通过 swift 做一个项目。我已经定义了一个集合视图并自定义了它的单元格,使它看起来像图像 down 。现在,一旦我点击单元格,我的函数将告诉我我点击了哪个单元格,但我想获得更详细的信息,例如我在单元格编号 2 中获得图片。为此,我试图定义一个轻击手势,但它似乎不起作用?这是我所有的代码:

导入 UIKit 导入 AVFoundation 导入 AVKit

class ViewUSRController: UIViewController , UICollectionViewDelegate , UICollectionViewDataSource  

    @IBOutlet var collectionView: UICollectionView!
    var cell : MyCollectionViewCell?

    var names = ["Danial" , "dkfloza" , "Kosarifar" , "ios" , "Learning", "sina" ]
    var likes = ["23" , "7" , "17" , "100K" , "1000K" , "100"]

    var dislikes = ["0","0","0","0","0","0"]





    var playerViewController = AVPlayerViewController()
    var playerView = AVPlayer()


 override func viewDidLoad() 
        super.viewDidLoad()

        view.backgroundColor = .black
        self.collectionView.delegate = self




        let tap = UITapGestureRecognizer(target: self.cell?.myLabel, action:#selector(handleTap))
        tap.numberOfTapsRequired =  1
        cell?.myLabel.addGestureRecognizer(tap)

    

    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int

        return self.names.count
    


    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
         cell = collectionView.dequeueReusableCell(withReuseIdentifier: "id", for: indexPath as IndexPath) as! MyCollectionViewCell

        // Use the outlet in our custom class to get a reference to the UILabel in the cell
        cell?.myLabel?.text = self.names[indexPath.row]
        cell?.myLabel?.textColor = .black
        cell?.likes_num?.text = likes[indexPath.row]
        cell?.dislike_num?.text = dislikes[indexPath.row]
        cell?.likes_num?.textColor = .black
        cell?.dislike_num?.textColor = .black


        return cell!

    






//    
//    
//    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
//        // handle tap events
//        print("You selected cell #\(indexPath.item)!")
//        
//        
//        
//        
//    


    func handleTap()
        print("hello")
    














class MyCollectionViewCell : UICollectionViewCell
    //appClub
    @IBOutlet var myLabel: UILabel!
    //imagePlace
    @IBOutlet var viewTesting: UIView!
    //likes
    @IBOutlet var likes_num: UILabel!
    //dislikes
    @IBOutlet var dislike_num: UILabel!












【问题讨论】:

您可以将按钮放在标签上,然后将它们自动布局为中心+等宽+等高,然后创建基于委托或闭包的操作; 这方面的最佳实践太多了。但是在每次练习中,您都必须自己处理 UITouch 对象。尝试同时使用 touches 事件和集合视图委托。在集合视图(或您所在的单元格)中识别您正在触摸的项目(单元格)和触摸位置。稍后您可以在触摸项目的坐标系中映射该触摸位置以获取视图。 如果您尝试使用任何手势来完成您的工作,您可能会更改响应者(UIResponder 对象)层次结构。这会让你的情况变得更糟。 【参考方案1】:

-> 向表格视图添加手势

override func viewDidLoad() 
        super.viewDidLoad()

        let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        tap.delegate = self
        tap.numberOfTapsRequired = 1
        tap.numberOfTouchesRequired = 1
        tableView.addGestureRecognizer(tap)
    

->检测水龙头

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool 
    let tableView = gestureRecognizer.view as! UITableView
    let point: CGPoint = gestureRecognizer.location(in: tableView)
    if (tableView.indexPathForRow(at: point) != nil) 
        return true;
    
    return false;

-> 在单元格中找到位置,并通过给子视图视图(例如 imageView、标签)提供标签,您也可以获得确切的视图。

public func handleTap(tap: UITapGestureRecognizer)

    if (UIGestureRecognizerState.ended == tap.state) 
        let tableView = tap.view as! UITableView
        let point: CGPoint = tap.location(in: tableView)
        let indexPath = tableView.indexPathForRow(at: point)
        tableView.deselectRow(at: indexPath!, animated: false)
        let cell = tableView.cellForRow(at:indexPath!)
        let pointInCell = tap.location(in: cell)
        if ((cell?.imageView?.frame)!.contains(pointInCell)) 
            // user tapped image
         else 
            // user tapped cell
        
    

【讨论】:

我正在尝试将您提供的代码从 tableView 转换为 CollectionView 。一切都很好,除了if ((cell?.imageView?.frame)!.contains(pointInCell)) 行之外,似乎在cell? 之后,我无法获取单元格中的任何元素,例如标签或imageView 或....顺便说一句,用于点击检测,选择器应该是#selector(self.handleTap(tap:)) 否则对于歧义的用法,它会给出编译错误:) 好的,现在您无法访问标签单元格是什么问题?.myLabel?如果这些属性在单元类中定义为公共的或内部的,则您可以访问这些属性。

以上是关于如何知道在 UICollectionView 中点击了自定义单元格的哪一部分?的主要内容,如果未能解决你的问题,请参考以下文章

如何通知 UICollectionView 框架更改

如何知道 UICollectionView 是不是会在 scrollToItemAtIndexPath: 被调用后实际滚动?

如何知道在 UICollectionView 中点击了自定义单元格的哪一部分?

如何在 uicollectionview 标题中添加 uicollectionview

如何在顶部 UICollectionView 上制作粘性标题

请问如何在vs2010中点开c#的aspx文件的视图设计器