如何从目标函数集(Swift 3)访问 UICollectionView 中的按钮

Posted

技术标签:

【中文标题】如何从目标函数集(Swift 3)访问 UICollectionView 中的按钮【英文标题】:How to access buttons in a UICollectionView from a target function set (Swift 3) 【发布时间】:2016-11-27 23:20:36 【问题描述】:

在我的视图控制器中,我有一个集合视图,它在渲染时显示 3 个单元格,每个单元格都有一个标签和一个按钮。标签显示颜色的名称,按钮具有显示色样的背景图像。

我希望这样,每当您单击其中一个按钮时,该按钮周围会出现深色边框,而其他按钮上会出现浅色边框,以指示单击的按钮被“选中”。或者,我可以通过根据图像的选定状态更改图像来做到这一点 - 但我的问题仍然是一样的。

如何访问其他两个按钮以切换它们的属性?

我实现了一个脚本,允许我为某人单击的按钮添加边框 - 但我无法弄清楚如何访问 CollectionView 的其他单元格中的其他按钮以更改其边框属性。

这是我的源代码(去掉了不相关/不相关的位)

class trimSelectorVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource 

    @IBOutlet weak var trimSelector: UICollectionView!

    struct trimObject 
        var trimName: String
        var trimButton: String
        var trimID: Int
    

    var trimArray: [trimObject] = []

    override func viewDidLoad() 
        super.viewDidLoad()
        trimArray.append(trimObject(trimName: "Chrome", trimButton: "chrome-swatch", trimID: 0))
        trimArray.append(trimObject(trimName: "Gold", trimButton: "gold-swatch", trimID: 1))
        trimArray.append(trimObject(trimName: "Gun Metal", trimButton: "gunmetal-swatch", trimID: 2))

        trimSelector.delegate = self
        trimSelector.dataSource = self
    


    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)
    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return trimArray.count
    

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

        //Set the label text
        cell.trimLabel.text = trimArray[indexPath.item].trimName

        //Set the image for the button
        cell.trimButton.setImage(UIImage(named: trimArray[indexPath.item].trimButton), for: UIControlState.normal)

        //Sets a target function for the button
        cell.trimButton.addTarget(self, action: #selector(selectedSwatch), for: .touchUpInside)

        return cell
    


    func selectedSwatch(sender: UIButton) 

        //These set the "selected" border to the button you clicked on.
        sender.layer.borderWidth = 2
        sender.layer.borderColor = UIColor(red: 83/255, green: 71/255, blue: 65/255, alpha: 1.00).cgColor


    

谁能告诉我如何访问我的“selectedSwatch”功能中的其他按钮?

【问题讨论】:

【参考方案1】:

您可以通过多种方式处理此问题。 UICollectionView 视图有一个 visibleCells() 方法,它返回其可见单元格的数组。您可以使用它来获取指向单元格的指针。您需要一种方法来确定哪个是哪个。例如,您可以使用indexPath(for: UICollectionViewCell) 找出每个单元格的索引路径。

【讨论】:

我认为这肯定是在正确的轨道上。我可以使用此方法提取集合视图中的单元格数量。我将如何使用返回的数组深入到单元格内的 UIButton?类似于: var allCells = trimSelector.visibleCells() allCells[0].>.layer.borderColor = UIColor.black 使您的集合视图单元格成为 UICollectionViewCell 的自定义子类。定义原型单元并连接故事板中的插座。然后将您从调用 visibleCells 返回的单元格转换为您的自定义单元格类型,并使用插座找到按钮。 有关设置单元原型的说明,请参见此链接:techotopia.com/index.php/…【参考方案2】:

我不知道这是否有帮助,但是如果将 IndexPath 存储在 cellForItemAt 方法的结构中呢?

你将拥有:

struct trimObject 
    var trimName: String
    var trimButton: String
    var trimID: Int
    var idx : IndexPath

然后:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! trimSelectionCell
            ....

 trimArray[indexPath.item].idx = indexPath
     .... 

在您的 selectedSwatch 方法中:

func selectedSwatch(sender: UIButton) 

    //These set the "selected" border to the button you clicked on.
    sender.layer.borderWidth = 2
    sender.layer.borderColor = UIColor(red: 83/255, green: 71/255, blue: 65/255, alpha: 1.00).cgColor

    if let cell = (sender.superview as? UICollectionViewCell) 

        //Cell with the button selected:
        let idx = collectionView.indexPath(for: cell)

        //array of the other objects:
        let allOtherObjects = trimArray.filter  ($0 as! trimObject).idx != idx 

        allOtherObject.forEach( (trimObj) in
            let cell = collection.cellForItem(at: trimObj.idx)
            //Do whatever yo need to do...
            //cell.trimButton.layer
        )
    


【讨论】:

【参考方案3】:

可能为时已晚,但对某些人仍然有用 斯威夫特 4 版本: 您可以将发件人超级视图用作 UiCollectionViewCell * 在集合视图单元格中考虑发送者的层次结构

func selectedSwatch(sender: UIButton) 
   let cell = sender.superview?.superview as! trimSelectionCell
   //cell.yourbtn 

【讨论】:

【参考方案4】:

试试这个,

 class trimSelectorVC: UIViewController, UICollectionViewDelegate, 
 UICollectionViewDataSource 

@IBOutlet weak var trimSelector: UICollectionView!

struct trimObject 
    var trimName: String
    var trimButton: String
    var trimID: Int
    var isSelected : String


var trimArray: [trimObject] = []

override func viewDidLoad() 
    super.viewDidLoad()
    trimArray.append(trimObject(trimName: "Chrome", trimButton: "chrome-swatch", trimID: 0,isSelected : "0"))
    trimArray.append(trimObject(trimName: "Gold", trimButton: "gold-swatch", trimID: 1,isSelected : "0"))
    trimArray.append(trimObject(trimName: "Gun Metal", trimButton: "gunmetal-swatch", trimID: 2,isSelected : "0"))

    trimSelector.delegate = self
    trimSelector.dataSource = self



override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    return trimArray.count


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

    //Set the label text
    cell.trimLabel.text = trimArray[indexPath.item].trimName

    //Set the image for the button
    cell.trimButton.setImage(UIImage(named: 
  trimArray[indexPath.item].trimButton), for: UIControlState.normal)
   if(trimArray[indexPath.item].isSelected == "0")
   // button not clicked
  // change shadow color of button

    
   else
    
   // button  clicked
       cell.trimButton.layer.borderWidth = 2
      cell.trimButton.layer.borderColor = UIColor(red: 83/255, green: 
       71/255,blue: 65/255, alpha: 1.00).cgColor
    
     // set tag to the button
     cell.trimButton.tag = indexPath.item 

    //Sets a target function for the button
    cell.trimButton.addTarget(self, action:#selector(selectedSwatch), 
         for: .touchUpInside)

     return cell
  


func selectedSwatch(sender: UIButton) 

    //These set the "selected" border to the button you clicked on.

  let index = sender.tag
   for obj in trimArray 
   obj.isSelected = "0"
   

   trimArray[index].isSelected = "1"

  collectionView.reloadData()

【讨论】:

以上是关于如何从目标函数集(Swift 3)访问 UICollectionView 中的按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Swift 单元测试访问测试目标中存在的 Objective-C 代码?

如何在swift中仅使用角半径为3条边添加阴影?

从 Swift 3 中的另一个项目访问视图控制器

module.map 用于从测试目标访问主目标中的(Swift 和 Objective-C)类

使用 Swift 从 AFNetworking 访问 JSON 数据

从Swift中的另一个ViewController访问rightBarButton函数