简体   繁体   English

从UICollectionViewController获取indexPath到UICollectionViewCell子类

[英]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.

相关问题 在点击UIBarButtonItem时从indexPath获取UICollectionViewCell - Get UICollectionViewCell from indexPath when UIBarButtonItem is tapped 获取UICollectionViewCell的indexPath - Get indexPath of UICollectionViewCell 从Swift中的UITableViewCell子类中获取IndexPath - Get the IndexPath from inside a UITableViewCell subclass in Swift 在UICollectionViewCell类中获取IndexPath值 - Get IndexPath Value in UICollectionViewCell Class 从UICollectionViewController中的选定索引路径加载UITableViewController - loading a UITableViewController from a selected indexpath in a UICollectionViewController 如何从UICollectionViewCell中的按钮关闭UICollectionViewController - How to dismiss UICollectionViewController from button in UICollectionViewCell 如何从UICollectionViewController验证UICollectionViewCell的值 - How to validate values of UICollectionViewCell from the UICollectionViewController 为什么我的 UICollectionViewCell 没有从 UICollectionViewController 获取数据? - Why is my UICollectionViewCell not getting data from UICollectionViewController? cellForItem(at:IndexPath)方法不使用UICollectionViewCell子类进行调用 - cellForItem(at: IndexPath) method doesn't call with UICollectionViewCell subclass 如何基于单元格文本获取UICollectionViewCell的indexPath? - How to get indexPath of UICollectionViewCell based on cell text?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM