[英]Get indexPath from UICollectionViewController to UICollectionViewCell subclass
in my view controller I Am loading a custom CollectionViewCell with subclass. 在我的视图控制器中,我正在加载带有子类的自定义CollectionViewCell。 Based on the position of a cell's indexpath I want to format the text labels differently. 根据单元格索引路径的位置,我想以不同的方式设置文本标签的格式。 Ie first row has only one cell with bigger text, whereas the second has two cell with smaller text. 即第一行只有一个具有较大文本的单元格,而第二行有两个具有较小文本的单元格。
How can I access the indexpath from my UICollectionView in my UICollectionViewCell subclass? 如何从UICollectionViewCell子类中的UICollectionView访问索引路径? I tried a delegate protocol but this always returns nil. 我尝试了委托协议,但这总是返回nil。
Code below and Thanks so much! 下面的代码,非常感谢!
Markus 马库斯
UICollectionViewController: UICollectionViewController:
import UIKit
protocol WorkoutDataViewControllerCVDataSource: AnyObject {
func workoutType(for workoutDataViewControllerCV: WorkoutDataViewControllerCV) -> WorkoutType
func workoutDistance(for workoutDataViewControllerCV: WorkoutDataViewControllerCV) -> Double
func workoutDuration(for workoutDataViewControllerCV: WorkoutDataViewControllerCV) -> Double
func workoutInstantVelocity(for workoutDataViewControllerCV: WorkoutDataViewControllerCV) -> Double
}
final class WorkoutDataViewControllerCV: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
weak var dataSource: WorkoutDataViewControllerCVDataSource!
private lazy var velocityFormatter = VelocityFormatter(dataSource: self, delegate: self)
private lazy var averageVelocityFormatter = VelocityFormatter(dataSource: self, delegate: self)
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView.register(MeasurementCollectionViewCell.preferredNib, forCellWithReuseIdentifier: MeasurementCollectionViewCell.preferredReuseIdentifier)
}
}
// MARK: - Managing UICollectionView
extension WorkoutDataViewControllerCV: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Measurement Cell", for: indexPath)
return cell
}
}
extension WorkoutDataViewControllerCV: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let availableWidth = self.view.frame.width
switch indexPath.row {
case 0: return CGSize(width: availableWidth, height: 150)
case 1: return CGSize(width: availableWidth/2.1, height: 150)
case 2: return CGSize(width: availableWidth/2.1, height: 150)
case 3: return CGSize(width: availableWidth, height: 150)
default:
return CGSize(width: availableWidth/2.1, height: 150)
}
}
}
// MARK: - Managing VelocityFormatter
extension WorkoutDataViewControllerCV: VelocityFormatterDataSource {
func duration(for velocityFormatter: VelocityFormatter) -> Double {
return dataSource.workoutDuration(for: self)
}
func distance(for velocityFormatter: VelocityFormatter) -> Double {
return dataSource.workoutDistance(for: self)
}
func instantVelocity(for velocityFormatter: VelocityFormatter) -> Double {
return dataSource.workoutInstantVelocity(for: self)
}
}
UICollectionViewCell.swift UICollectionViewCell.swift
import UIKit
final class MeasurementCollectionViewCell: UICollectionViewCell {
@IBOutlet private var measurementPropertyLabel: UILabel!
@IBOutlet private var measurementValueLabel: UILabel!
@IBOutlet private var measurementUnitLabel: UILabel!
static let preferredReuseIdentifier = "Measurement Cell"
static let preferredNib = UINib(nibName: "MeasurementCollectionViewCell", bundle: nil)
override func awakeFromNib() {
super.awakeFromNib()
updateMeasurement(property: "Speed", value: "100", unit: "km/h")
//measurementValueLabel.font = measurementValueLabel.font.monospacedDigitFont
}
func updateMeasurement(property: String, value: String, unit: String?) {
measurementPropertyLabel.text = property
measurementValueLabel.text = value
measurementUnitLabel.text = unit
}
}
Get the instance of cell in UICollectionView delegate
method collectionView(_, didSelectItemAt _)
. 在UICollectionView delegate
方法collectionView(_, didSelectItemAt _)
获取单元格的实例。
extension WorkoutDataViewControllerCV: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let cell = collectionView.cellForItem(at: indexPath) as? MeasurementCollectionViewCell {
cell.selectedIndexPath(indexPath)
}
}
}
The indexPath
will be passed as an argument in method selectedIndexPath
to MeasurementCollectionViewCell
from above method. indexPath
将作为方法selectedIndexPath
的参数从上述方法传递到MeasurementCollectionViewCell
。
class MeasurementCollectionViewCell: UICollectionViewCell {
......
func selectedIndexPath(_ indexPath: IndexPath) {
//Do your business here.
}
}
You can use the responder chain to get the collection view of a cell with which you can get the index path. 您可以使用响应者链来获取单元格的集合视图,通过该单元格可以获取索引路径。 Just add these extensions in a new file called UICollectionViewCell+IndexPath.swift
. 只需将这些扩展名添加到名为UICollectionViewCell+IndexPath.swift
的新文件中UICollectionViewCell+IndexPath.swift
。
extension UIResponder {
func next<T: UIResponder>(_ type: T.Type) -> T? {
return next as? T ?? next?.next(type)
}
}
extension UICollectionViewCell {
var indexPath: IndexPath? {
return next(UICollectionView.self)?.indexPath(for: self)
}
}
Now inside your cell, you can use self.indexPath
现在在您的单元格内,您可以使用self.indexPath
Pretty straight forward way would be storing the indexPath
into the subclass of UICollectionViewCell
class. 非常简单的方法是将indexPath
存储到indexPath
类的UICollectionViewCell
类中。 Assign it while returning from cellForRow at: index path
. 从cellForRow at: index path
返回时cellForRow at: index path
分配它cellForRow at: index path
。 So now the subclassed collectionviewcell has access to the indexpath of it's own 因此,现在子类化的collectionviewcell可以访问其自身的indexpath
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.