this is screenshot(image) of my viewcontrollerI'm using collectionview and placed label in header, header and label created in storyboard I want to change label text at runtime.
I know I can do it in viewForSupplementaryElementOfKind of collectionview but I want it in viewdidload method
my code is as below
Controller code
class DeleteViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource {
@IBOutlet weak var collectionView: UICollectionView!
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = .red
return cell
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerId", for: indexPath) as! TestCollectionReusableView
headerView.labelText.text = "dummy" // this line shows dummy
return headerView
}
let testCollectionReusableView = TestCollectionReusableView()
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(TestCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "headerId")
testCollectionReusableView.labelText.text = "Test"
// above line Xcode 12.4 shows error - **Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value**
}
}
Header Class File
class TestCollectionReusableView: UICollectionReusableView {
@IBOutlet weak var labelText: UILabel!
}
Probably the best place to do this is in your DeleteViewController
assuming that this class holds your collection view and is a data source for it.
You can simply add a new property such as headerText: String
which may then be user in your data source method. Whenever you change the text you should reload your collection view (or just the headers) for change to take effect.
So for instance
class DeleteViewController: UIViewController, UICollectionViewDataSource {
@IBOutlet private var collectionView: UICollectionView?
private var currentHeaderText: String = "Dummy"
override func viewDidLoad() {
super.viewDidLoad()
changeHeaderText(to: "Some other text")
}
private func changeHeaderText(to text: String) {
currentHeaderText = text
collectionView?.reloadData()
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerId", for: indexPath) as! TestCollectionReusableView
headerView.labelText.text = currentHeaderText
return headerView
}
}
A more optimized approach may be to detect which index paths need reloading and only reload those index paths. It would even be possible to use methods like collectionView?.visibleSupplementaryViews(ofKind: <#T##String#>)
and loop through all visible views that correspond to your class to apply the change. But this is all up to you.