【问题标题】:How do I pass a value to a custom UICollectionViewCell?如何将值传递给自定义 UICollectionViewCell?
【发布时间】:2016-05-17 21:19:37
【问题描述】:

我有一个自定义 UICollectionViewCell,我试图将值从我的视图控制器传递给它。我可以将图像传递给单元格,但初始化时其他任何内容都为零。

View Controller中的相关代码:

override func viewDidLoad() {

    self.collectionView!.registerClass(MyCustomCell.self, forCellWithReuseIdentifier: "Cell")

}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! MyCustomCell

    cell.someValue = 5
    cell.imageView.image = UIImage(named: "placeholder.png")

    return cell

}

在自定义单元格类中:

var someValue: Int!
var imageView: UIImageView!

override init(frame: CGRect) {

    super.init(frame: frame)

    imageView = UIImageView(frame: CGRectMake(0, 0, frame.width, frame.height))
    contentView.addSubview(imageView)

    let someValueLabel = UILabel()
    someValueLabel.frame = CGRectMake(0, 75, 200, 30)
    someValueLabel.text = "Value is: \(someValue)"
    self.addSubview(someValueLabel)
}

图像从 UICollectionView 成功传递,我可以显示它,但“someValue”始终为零。

我做错了什么?

【问题讨论】:

  • 另外,您不应该将您的 UIImageView 属性称为“imageView”。由于 UITableViewCell 已经包含一个使用这个名称的。它可能会导致不良影响。也许它已经修复了,但我已经遇到了一些麻烦。喜欢这个Q:stackoverflow.com/questions/11681273/…

标签: ios swift uicollectionview uicollectionviewcell uicollectionviewdelegate


【解决方案1】:

init 方法的调用时间比您想象的要早得多——在dequeue 进程中——在构造单元对象时。初始化过程的一部分是附加在 Storyboard 中设计的UIViews。所以该图像有效,因为UIImageView 在情节提要 (NIB) 加载过程中已经作为容器就位,而您稍后只是设置其内部图像属性。

在单元格渲染和事件处理期间,您已为所有未来使用正确设置了someValue 的值。因此,例如,如果有一个@IBAction 处理程序在显示并点击单元格后运行,它确实可以访问someValue。那就是您的测试打印应该去的地方。你最终使用 someValue 是为了什么?

跟进

所以这是一个简单的错误;您只需要在cellForRowAtIndexPath 中设置文本值。您也不需要单元格中的模型数据副本(即,您的单元格中不需要有 someValue 字段)。只需从您的(正确分离的)模型数据中动态配置 UI:

代替:

cell.someValue = 5

你只需要,例如:

cell.someValueLabel.text = "\(indexPath.row)" // or where ever you're getting your underlying model data from

init 用于任何此类操作都是一种误解。 init 对表格单元的唯一职责是分配内存。单元格是一个完全动态的临时对象,它的所有反映应用程序数据的属性都必须在cellForRowAtIndexPath 方法中设置。单元格的可视化渲染等待cellForRowAtIndexPath方法完成,所以不存在时间问题。

【讨论】:

  • 在真实版本中,我试图传递“indexPath.item”值,以便在初始化期间根据单元格显示的任何内容对单元格的外观进行一些细微的更改。
  • init 期间进行更改是一种误解。init 对表格单元格的唯一责任是分配内存。单元格是一个完全动态的临时对象,它的所有反映应用程序数据的属性都必须在cellForRowAtIndexPath 方法中设置。单元格的可视化渲染等待cellForRowAtIndexPath方法完成,所以不存在时序问题。
【解决方案2】:

在实例化 UICollectionView 时调用 Init 方法。您在 init 方法中记录“someValue”,现在还为时过早。由于您直接使用已实例化的 ImageView,因此会渲染图像。尝试在 init 方法中记录 imageView.image,它也应该是 nil(或者可能不是 nil,因为单元格被重用了)。

您应该在自定义变量 setter 和 getter 中工作,您可以确定它们不是 nil。

var someValue: Int!{
    didSet {
        print("Passed value is: \(newValue)")
    }
}

【讨论】:

    【解决方案3】:

    在初始化单元格后,您正在设置 someValue 的值。

    您在初始化过程中调用print("Passed value is: \(someValue)")

    在单元类的 init 方法上设置断点。在将值 5 分配给该变量之前,您应该看到它通过那里。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-12
      • 1970-01-01
      相关资源
      最近更新 更多