Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
350 views
in Technique[技术] by (71.8m points)

uiview - Swift 5 How UICollectionViewCell changes it's content

I am so confused right now, In cellForItemAt method, I changed the label.text value, but I found that this line is called after cell Instance being created [Here is the preview collection view][1]

let data = self.data[indexPath.item]
cell.myLabel.text = "(indexPath.row)"
print(cell.myLabel.text)

However, In my custom cell class,

self.contentView.addSubview(myLabel)
print((myLabel.text)

myLabel is added to contentView in init()

I don't know how does changing myLabel.text in cellForItemAt update the label that is already added to contenView,

So when I trying to figure it out by printing out the text I got, CUSTOM, 1, CUSTOM, 2, CUSTOM, 3 ...

.... Which means myLabel.text was not changed to indexPath.row before it's added into the contentView, So how this happens?? Anyone can help me? If I don't figure it out I can't continue my project, I am stuck here

Here is the some code

class Cell: UICollectionViewCell {

static var identifier: String = "Cell"

var textLabel: UILabel!

var myLabel: UILabel = {
    let label = UILabel()
    label.text = "CUSTOM"
    label.backgroundColor = .green
    label.textAlignment = .center
    return label
} ()

override init(frame: CGRect) {
    super.init(frame: frame)

    
    self.contentView.addSubview(myLabel)
    
    print(myLabel.text) // print the text after label is added to contentView 
    // I got Optional("CUSTOM") Which was not changed here

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override func layoutSubviews() {
    super.layoutSubviews()
    
    myLabel.frame = CGRect(x: 0, y: 0, width: contentView.frame.size.width - 50, height: 50)
}
}

DataSource

extension ViewController: UICollectionViewDataSource {

func collectionView(_ collectionView: UICollectionView,
                    numberOfItemsInSection section: Int) -> Int {
    return self.data.count
}

func collectionView(_ collectionView: UICollectionView,
                    cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Cell.identifier, for: indexPath) as! Cell
    let data = self.data[indexPath.item]
    cell.myLabel.text = "(indexPath.row)" 
    print(cell.myLabel.text) // I got Optional("0"), Optional("1"), Optional("2") .. here
                            // But the label was already added with text "CUSTOM"
    return cell
}
}
question from:https://stackoverflow.com/questions/65831372/swift-5-how-uicollectionviewcell-changes-its-content

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First, the .text property of a UILabel can be nil, so it is optional.

If you add this to a view controller's viewDidLoad():

    let label = UILabel()
    print(label.text)
    label.text = "abc"
    print(label.text)

the output in the debug console will be:

nil
Optional("abc")

Next, if you set the text of a label and then set it again, it replaces any existing text:

    let label = UILabel()
    print(label.text)
    label.text = "abc"
    print(label.text)
    label.text = "1"
    print(label.text)

now the output is:

nil
Optional("abc")
Optional("1")

If you want to get rid of the "Optional" part, you need to unwrap the text:

    let label = UILabel()
    if let s = label.text {
        print(s)
    }
    label.text = "abc"
    if let s = label.text {
        print(s)
    }
    label.text = "1"
    if let s = label.text {
        print(s)
    }

output:

abc
1

Note there is no "nil" output... because the first if let... statement fails, so the print statement does not get executed.

So, if you want your label to show "CUSTOM 1" / "CUSTOM 2" / "CUSTOM 3" / etc, you can either set it that way in cellForRowAt:

cell.myLabel.text = "CUSTOM (indexPath.row)"

or, you can append the existing text:

// unwrap the optional text
if let s = cell.myLabel.text {
    cell.myLabel.text = s + " (indexPath.row)"
}

Note, however, that cells are reused, so you could end up with:

CUSTOM 1 7 15 8 23

Much better to set the full text to what you want it to be, than to try and append something each time the cell is used.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...