Swift:使用 didSelectItemAt indexPath 函数仅选择单元格,即使我点击其中的 UI 元素也是如此

Posted

技术标签:

【中文标题】Swift:使用 didSelectItemAt indexPath 函数仅选择单元格,即使我点击其中的 UI 元素也是如此【英文标题】:Swift: Using didSelectItemAt indexPath func to only select the cell even if I tap on a UI element within it 【发布时间】:2018-07-31 12:11:33 【问题描述】:

下午好。 我正在创建一个简单的小应用程序,并且我有一个简单的“功能”,我无法弄清楚如何实现,对编程来说相当陌生。我有一个 UICollectionView,其单元格位于另一个 UICollectionView 的单元格中,当我点击其中一个单元格时,它们会触发以下 didselect 和 diddeselect 方法:

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 

    if let cell = collectionView.cellForItem(at: indexPath) 

        cell.layer.borderColor = UIColor.flatBlack.cgColor
        cell.layer.borderWidth = 3
        cell.layer.cornerRadius = 7
        cell.backgroundColor = GradientColor(.topToBottom, frame: cell.frame, colors: [UIColor.flatRed.withAlphaComponent(0.2), UIColor.white])


     else return



func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) 

    if let cell = collectionView.cellForItem(at: indexPath) 
        cell.layer.borderColor = UIColor.clear.cgColor
        cell.layer.borderWidth = 0
        cell.layer.cornerRadius = 0
        cell.backgroundColor = .white
     else return


单元格内容:它有点长,但如果被问到我会发布代码(以编程方式创建的单元格)。但基本上我在每个单元格中有几个 UIImageViews、两个 UITextViews、一个 UITextLabel 和一个 UIButton。 (因此单元格是在一个单独的类中声明的,而不是在 UICollectionViewDelegate 和 DataSource 类中)。

问题:我想添加,以便当我点击单元格单个框架中的任何位置时,即使我点击 UITextView 也希望选择它(此时如果我点击 textview 它会进入该视图的编辑模式)。如果我再次点击它,我希望能够编辑文本视图。 - 我该如何实现?

细胞创建代码:

class EventsCell: UICollectionViewCell 
  override init(frame: CGRect) 
    super.init(frame: frame)
    backgroundColor = UIColor.white
    setupViews()



//MARK: - Declaration of cell organelles.
//separatorView for a separating line between cells

let textView: GrowingTextView =    //GrowingTextView is a pod it is a regular UITextView but with some perks.
    let tv = GrowingTextView()
    tv.backgroundColor = .clear
    tv.allowsEditingTextAttributes = true
    tv.isScrollEnabled = false
    tv.font = UIFont(name: "Didot", size: 16)
    tv.textContainerInset = UIEdgeInsetsMake(4, 4, 4, 6)
    tv.placeholder = "Write your event text here"
    tv.placeholderColor = UIColor.lightGray
    tv.autoresizingMask = .flexibleHeight
    tv.isUserInteractionEnabled = false
    return tv
()



let eventPlaceholderMarkImage: UIImageView = 
    let iv = UIImageView()
    iv.image = UIImage(named: "placeHolderEventTitleMark")
    return iv
()

func setupViews() 


    addSubview(textView)
    addSubview(eventPlaceholderMarkImage)


    let eventsPinImageH = frame.width / 2 - 7
    let cellHeight = frame.height
    let cellWidth = frame.width

    //MARK: - Constraints for EventsCell

    addConstraintsWithFormat(format: "H:|-16-[v0(\(frame.width - 32))]-16-|", views: textView)
    addConstraintsWithFormat(format: "V:|-47-[v0]-16-|", views: textView)




    addConstraint(NSLayoutConstraint(item: eventPlaceholderMarkImage, attribute: .bottom, relatedBy: .equal, toItem: textView, attribute: .top, multiplier: 1, constant: -5))
    addConstraint(NSLayoutConstraint(item: eventPlaceholderMarkImage, attribute: .height, relatedBy: .equal, toItem: self, attribute: .height, multiplier: 0, constant: 20)) 
    //Followed by much more constraints
    required init?(coder aDecoder: NSCoder) 
    fatalError("init(coder:) has not been implemented")


然后在类中创建 UICollectionView:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: EventCellID, for: indexPath)

    return cell

感谢您阅读我的帖子!

【问题讨论】:

【参考方案1】:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 

    if let cell = collectionView.cellForItem(at: indexPath) 

        cell.yourTextView.isUserInteractionEnbled = true //1


        cell.layer.borderColor = UIColor.flatBlack.cgColor
        cell.layer.borderWidth = 3
        cell.layer.cornerRadius = 7
        cell.backgroundColor = GradientColor(.topToBottom, frame: cell.frame, colors: [UIColor.flatRed.withAlphaComponent(0.2), UIColor.white])


     else return



func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) 

    if let cell = collectionView.cellForItem(at: indexPath) 
        cell.layer.borderColor = UIColor.clear.cgColor
        cell.layer.borderWidth = 0
        cell.layer.cornerRadius = 0
        cell.backgroundColor = .white
     else return



override func viewWillAppear(_ animated: Bool)         
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear), name: Notification.Name.UIKeyboardWillHide, object: nil)



@objc func keyboardWillDisappear() 

    cell.yourTextView.isUserInteractionEnbled = false //2

创建单元格时:

...
cell.yourTextView.isUserInteractionEnabled = false // 3

1 : 第一次选择单元格时,由于我们在步骤 (3) 中所做的操作,您的 textView 将无法选择,在第一次点击后,我们将启用 textView 以进行第二次触摸

2 : 每当我们在编辑 textview 后关闭键盘时,我们都会将交互设置为 false,以便我们能够在点击时选择单元格而不是 textView

【讨论】:

我遇到的问题是:我无法访问 UICollectionViewDelegate/DataSource 类中的单元格。因为它是另一个 uicollectionview 中的 uicollectionview,所以我有一个集合视图,其中包含我想在另一个类和另一个文件中选择的单元格。我只使用我的类模板在“cellForItemAt”方法中创建单元格 能否请您发布一些有关创建您的单元格的代码,以便我更好地帮助您? 当然!我已经编辑了我的问题并添加了单元格创建代码(第二个代码块) 没关系,我从您的帖子中发现了以下对“keyboardWillDisappear”方法的更改! @objc func keyboardWillDisappear() let cell = collectionView.visibleCells as! [EventsCell] 单元格中的每个单元格 eachCell.textView.isUserInteractionEnabled = false eachCell.eventTitleLabel.isUserInteractionEnabled = false

以上是关于Swift:使用 didSelectItemAt indexPath 函数仅选择单元格,即使我点击其中的 UI 元素也是如此的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式从 collectionView Cell didSelectItemAt 推送到新的 ViewController - swift

覆盖单元格中的触摸后,Swift CollectionView didSelectItemAt 不再工作

如何在Swift中根据json id(意味着indexPath应该与json id匹配)从collectionView didSelectItemAt indexPath pushViewContro

didSelectItemAt 未被调用

Swift3 - UICollectionViewCel 的 intrinsicContentSize 是 (-1, -1)

CollectionView 中的 CollectionView:使用 didSelectItemAt 执行Segue