如何从目标函数集(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 代码?
module.map 用于从测试目标访问主目标中的(Swift 和 Objective-C)类