我在名为 MyCropView
的 UIView 类中的 collectionView 中有一个传感器列表,我在其中显示了有关该裁剪的一些数据。
我试图更改某些传感器的值,例如每次单击时的图标和背景颜色。
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let myCropCard = collectionView.superview as! MyCropCard
let sensor = myCropCard.sensors[indexPath.row]
let cell = myCropCard.superview
//Change the color and icon of the sensors
if let cell = collectionView.cellForItem(at: indexPath) as? MyCollectionViewCell {
//Previous cell in grey
if !self.lastSelectedIndexPath.isEmpty {
let lastCell = collectionView.cellForItem(at: self.lastSelectedIndexPath) as? MyCollectionViewCell
lastCell?.imageView.backgroundColor = UIColor(red: 0.95, green: 0.95, blue: 0.95, alpha: 1.0)
lastCell?.imageView.image = UIImage(named: self.lastSelectedImageName )
}
//Makes sensor green onSelect
cell.imageView.backgroundColor = UIColor(red: 0.882, green: 0.95, blue: 0.882, alpha: 1.0)
cell.imageView.image = UIImage(named: sensor.getType() )
self.lastSelectedIndexPath = indexPath
self.lastSelectedImageName = String(format: "%@_deactivated", sensor.getType())
}
//Show all the alerts of each sensor
for alert:Alert in sensor.getAlerts() {
let viewSensor = cell?.viewWithTag(300) as! SensorView
viewSensor.lblSensor.text = sensor.getTipo()
viewSensor.lblBotLog.text = alerta.getNombreDispositivo()
viewSensor.lblMin.text = String(format: "MIN %.0f", alert.getMin())
viewSensor.lblMax.text = String(format: "MAX %.0f", alert.getMax())
viewSensor.btnDel.tag = Int(alert.getId() + 1000)
viewSensor.btnDel.addTarget(
self,
action: #selector( viewSensor.deleteAlert(_:) ),
for: .touchUpInside
)
viewSensor.isHidden = false
}
}
collectionView 是我们拥有的传感器列表。它适用于第一个 MyCropCard,但不适用于多个 MyCropCard。 Superview 使用它们中的第一个 cropCard,而不是 collectionView 的父级。
我想知道如何才能正确拥有所选 collectionView 的父级?
最佳答案
您的代码中充斥着不必要的逻辑相关代码,这些代码可能与问题无关。
此外,广泛使用 tag
这使得代码不可扩展且难以维护,因此它可能需要大量重构。
以下代码基本上是您想要实现的目标的 MWE(如果我误解了您的问题,请告诉我)。
解释一下代码,这是一个自定义的tableViewCell:
class TableViewCell: UITableViewCell {
var collectionView: UICollectionView? {
didSet {
guard let collectionView = collectionView else { return }
contentView.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.backgroundColor = .white
setupCollectionViewLayout(collectionView)
}
}
private func setupCollectionViewLayout(_ collectionView: UICollectionView) {
NSLayoutConstraint.activate([
collectionView.leadingAnchor
.constraint(equalTo: contentView.leadingAnchor),
collectionView.trailingAnchor
.constraint(equalTo: contentView.trailingAnchor),
collectionView.topAnchor
.constraint(equalTo: contentView.topAnchor),
collectionView.bottomAnchor
.constraint(equalTo: contentView.bottomAnchor),
])
}
}
setupCollectionViewLayout
只需启用 AutoLayout。 collectionView
稍后将添加 tableViewCell
实例出队。
class CollectionViewCell: UICollectionViewCell {}
class ViewController: UIViewController {
private var lastSelectedCollectionViewCell: CollectionViewCell?
private lazy var tableView: UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.delegate = self
tableView.dataSource = self
tableView.register(TableViewCell.self, forCellReuseIdentifier: "cell")
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(tableView)
setupTableViewLayout(tableView)
}
private func setupTableViewLayout(_ tableView: UITableView) {
NSLayoutConstraint.activate([
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
}
tableView
在加载 View 时添加,并通过 setupTableViewLayout
添加 AutoLayout 约束.
请注意,您保留了最后一个索引路径的副本,但我认为保留对单元格本身的引用更好、更简单。
在UITableViewDataSource
扩展名:
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(
withIdentifier: "cell",
for: indexPath) as! TableViewCell
guard cell.collectionView == nil else { return cell }
let collectionView = UICollectionView(
frame: .zero,
collectionViewLayout: UICollectionViewFlowLayout())
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "cell")
cell.collectionView = collectionView
return cell
}
}
extension ViewController: UITableViewDelegate {}
我添加一个 collectionView
仅当它不存在于 tableViewCell
中.
collectionView
分配 dataSource
和 delegate
作为self
,尽管如果有一个额外的 modelController 对象会更好。
UITableViewDelegate
是空的。
现在扩展为 collectionView
小号:
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = .gray
return cell
}
}
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
lastSelectedCollectionViewCell?.backgroundColor = .gray
if let cell = collectionView.cellForItem(at: indexPath) as? CollectionViewCell {
cell.backgroundColor = .yellow
lastSelectedCollectionViewCell = cell
}
}
}
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 20, height: 20)
}
}
重要的部分是collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
,其他的只是样板代码。
选择 collectionViewCell 时,self.lastSelectedCollectionViewCell
的颜色变回灰色,新选择的单元格分配给 lastSelectedCollectionViewCell
, 在其 backgroundColor
之后改变了。
以下是您可以在 Playground 中运行的完整代码:
import UIKit
import PlaygroundSupport
class TableViewCell: UITableViewCell {
var collectionView: UICollectionView? {
didSet {
guard let collectionView = collectionView else { return }
contentView.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.backgroundColor = .white
setupCollectionViewLayout(collectionView)
}
}
private func setupCollectionViewLayout(_ collectionView: UICollectionView) {
NSLayoutConstraint.activate([
collectionView.leadingAnchor
.constraint(equalTo: contentView.leadingAnchor),
collectionView.trailingAnchor
.constraint(equalTo: contentView.trailingAnchor),
collectionView.topAnchor
.constraint(equalTo: contentView.topAnchor),
collectionView.bottomAnchor
.constraint(equalTo: contentView.bottomAnchor),
])
}
}
class CollectionViewCell: UICollectionViewCell {}
class ViewController: UIViewController {
private var lastSelectedCollectionViewCell: CollectionViewCell?
private lazy var tableView: UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.delegate = self
tableView.dataSource = self
tableView.register(TableViewCell.self, forCellReuseIdentifier: "cell")
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(tableView)
setupTableViewLayout(tableView)
}
private func setupTableViewLayout(_ tableView: UITableView) {
NSLayoutConstraint.activate([
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(
withIdentifier: "cell",
for: indexPath) as! TableViewCell
guard cell.collectionView == nil else { return cell }
let collectionView = UICollectionView(
frame: .zero,
collectionViewLayout: UICollectionViewFlowLayout())
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "cell")
cell.collectionView = collectionView
return cell
}
}
extension ViewController: UITableViewDelegate {}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = .gray
return cell
}
}
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
lastSelectedCollectionViewCell?.backgroundColor = .gray
if let cell = collectionView.cellForItem(at: indexPath) as? CollectionViewCell {
cell.backgroundColor = .yellow
lastSelectedCollectionViewCell = cell
}
}
}
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 20, height: 20)
}
}
PlaygroundPage.current.liveView = ViewController()
关于ios - collectionView didSelectItemAt superview 没有选择正确的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57632525/