如何将值传递给自定义 UICollectionViewCell?
How do I pass a value to a custom UICollectionViewCell?
我有一个自定义的 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
}
在自定义单元格中 class:
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' 始终为零。
我做错了什么?
您正在初始化单元格后设置 someValue 的值。
您正在初始化过程中调用 print("Passed value is: \(someValue)")
。
在单元格的 init 方法上设置一个断点 class。在将值 5 赋给该变量之前,您应该看到它通过那里。
init
方法的调用时间比您想象的要早得多——在 dequeue
进程中——当构建单元格对象时。初始化过程的一部分是附加在 Storyboard 中设计的 UIViews
。所以该图像有效,因为 UIImageView
在 Storyboard (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
对 table 个单元格的唯一责任是分配内存。单元格是一个完全动态的临时对象,它的所有反映应用程序数据的属性都必须在 cellForRowAtIndexPath
方法中设置。单元格的可视化渲染等待 cellForRowAtIndexPath
方法完成,因此不存在时间问题。
在实例化UICollectionView 时调用Init 方法。您正在 init 方法中记录 "someValue" 并且为时过早。由于您正在直接处理已经实例化的 ImageView,因此会呈现图像。尝试在 init 方法中记录 imageView.image,它也应该是 nil(或者可能不是 nil,因为单元格被重用)。
你应该在自定义变量 setter 和 getter 中工作,你确定它们不是 nil。
var someValue: Int!{
didSet {
print("Passed value is: \(newValue)")
}
}
我有一个自定义的 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
}
在自定义单元格中 class:
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' 始终为零。
我做错了什么?
您正在初始化单元格后设置 someValue 的值。
您正在初始化过程中调用 print("Passed value is: \(someValue)")
。
在单元格的 init 方法上设置一个断点 class。在将值 5 赋给该变量之前,您应该看到它通过那里。
init
方法的调用时间比您想象的要早得多——在 dequeue
进程中——当构建单元格对象时。初始化过程的一部分是附加在 Storyboard 中设计的 UIViews
。所以该图像有效,因为 UIImageView
在 Storyboard (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
对 table 个单元格的唯一责任是分配内存。单元格是一个完全动态的临时对象,它的所有反映应用程序数据的属性都必须在 cellForRowAtIndexPath
方法中设置。单元格的可视化渲染等待 cellForRowAtIndexPath
方法完成,因此不存在时间问题。
在实例化UICollectionView 时调用Init 方法。您正在 init 方法中记录 "someValue" 并且为时过早。由于您正在直接处理已经实例化的 ImageView,因此会呈现图像。尝试在 init 方法中记录 imageView.image,它也应该是 nil(或者可能不是 nil,因为单元格被重用)。
你应该在自定义变量 setter 和 getter 中工作,你确定它们不是 nil。
var someValue: Int!{
didSet {
print("Passed value is: \(newValue)")
}
}