简体   繁体   English

如何将值传递给自定义UICollectionViewCell?

[英]How do I pass a value to a custom UICollectionViewCell?

I have a custom UICollectionViewCell that I am attempting to pass a value to from my view controller. 我有一个自定义UICollectionViewCell,我试图将其值从我的视图控制器传递给它。 I'm able to pass an image to the cell, but anything else comes up nil upon initialization. 我可以将图像传递到单元格,但是初始化时其他所有操作都无效。

Relevant code in the 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

}

In the custom 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)
}

The image is successfully passed from the UICollectionView and I am able to display it, but 'someValue' is always nil. 该图像是从UICollectionView成功传递的,并且能够显示它,但是'someValue'始终为nil。

What am I doing wrong? 我究竟做错了什么?

The init method is called much earlier than you think it is -- within the dequeue process -- when the cell object is constructed. 构造单元对象时, init方法的调用要比您认为的要早得多(在出dequeue过程中)。 Part of initialization process is to attach the UIViews designed in Storyboard. 初始化过程的一部分是附加UIViews在故事板设计。 So that image works because the UIImageView is already in place as a container during the Storyboard (NIB) loading process, and you're just setting its internal image property later. 之所以可以使用该图像,是因为在Storyboard(NIB)加载过程中, UIImageView已作为容器放置到位,并且您稍后将设置其内部image属性。

You have correctly set the value of someValue for all future use, during cell rendering and event handling. 您已经为单元格渲染和事件处理期间的所有将来使用正确设置了someValue的值。 So, for example, if there's an @IBAction handler that runs after the cell is displayed and tapped on, it will indeed have access to someValue . 因此,例如,如果有一个@IBAction处理程序在显示并点按该单元格后运行,则它确实可以访问someValue That's where your test print should go. 那就是您的测试打印应该去的地方。 What are you ultimately using someValue for? 您最终 someValue用于什么?

FOLLOWUP 跟进

So it's a simple error; 因此,这是一个简单的错误; you just need to set the text value in cellForRowAtIndexPath . 您只需要在cellForRowAtIndexPath设置文本值。 You don't need a copy of model data in the cell (ie no need to have a someValue field in your cell), either. 您也不需要在单元格中复制模型数据(即,无需在单元格中有someValue字段)。 Just configure the UI dynamically from your (properly separated) model data: 只需根据您的(正确分隔的)模型数据动态配置UI:

instead of: 代替:

cell.someValue = 5

You just need, eg: 您只需要,例如:

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

It's a misconception to use init for any of this. 使用init进行任何这是一个误解。 The only responsibility of init for table cells is to allocate memory. 表单元的init的唯一责任是分配内存。 A cell is a completely dynamic, temporary object, and all of its properties that reflect Application data must be set in the cellForRowAtIndexPath method. 单元格是一个完全动态的临时对象,其所有反映应用程序数据的属性都必须在cellForRowAtIndexPath方法中设置。 The visual rendering of the cell waits for the cellForRowAtIndexPath method to finish, so there's no timing problem. 单元格的可视化渲染等待cellForRowAtIndexPath方法完成,因此没有计时问题。

Init method is called when the UICollectionView is instantiated. 实例化UICollectionView时将调用Init方法。 You're logging "someValue" in the init method and it's too early. 您正在init方法中记录“ someValue”,这还为时过早。 Image is rendered since you're working to the ImageView directly that has already been instantiated. 由于您正在直接使用已实例化的ImageView,因此将渲染图像。 Try to log imageView.image in the init method, it should be nil too (or maybe not nil because the cell is reused). 尝试在init方法中记录imageView.image,它也应该为nil(或者可能不为nil,因为单元已被重用)。

You should make your job in custom variables setters and getters, where you're sure that they're not nil. 您应该使用自定义变量setter和getter来完成工作,并确保它们不会为零。

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

You are setting the value of someValue after the cell has been initialized. 单元格初始化后,您要设置someValue的值。

You are calling print("Passed value is: \\(someValue)") during the initialization process. 您在初始化过程中正在调用print("Passed value is: \\(someValue)")

Set a break point on the init method of your cell class. 在单元格类的init方法上设置一个断点。 You should see it pass through there before you assign the value 5 to that variable. 在将值5分配给该变量之前,您应该看到它通过那里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM