Как изменить место текста метки в заголовке collectionveiw во время выполнения?

#ios #swift #uicollectionview #uicollectionreusableview

Вопрос:

это снимок экрана(изображение) моего viewcontroller, который я использую collectionview, и разместил метку в заголовке, заголовок и метку, созданные в раскадровке, я хочу изменить текст метки во время выполнения.

Я знаю, что могу сделать это в viewForSupplementaryElementOfKind из collectionview, но я хочу, чтобы это было в методе viewdidload

мой код выглядит следующим образом

Код контроллера

 
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**
        
    }


}
 

Файл класса заголовка

 
class TestCollectionReusableView: UICollectionReusableView {
        
    @IBOutlet weak var labelText: UILabel!
    
}
 

Ответ №1:

Вероятно, лучшее место для этого- DeleteViewController предположить, что этот класс содержит представление вашей коллекции и является для нее источником данных.

Вы можете просто добавить новое свойство, например, headerText: String которое затем может быть пользователем в вашем методе источника данных. Всякий раз, когда вы изменяете текст, вы должны перезагрузить представление коллекции (или только заголовки), чтобы изменения вступили в силу.

Так, например

 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
    }

}
 

Более оптимизированный подход может заключаться в том, чтобы определить, какие пути индекса нуждаются в перезагрузке, и загружать только эти пути индекса. Было бы даже возможно использовать такие методы, как collectionView?.visibleSupplementaryViews(ofKind: <#T##String#>) и перебирать все видимые представления, соответствующие вашему классу, чтобы применить изменение. Но все это зависит от тебя.

Комментарии:

1. У меня есть только один заголовок в верхней части collectionview

2. @Dhiren все равно

3. Привет, это работает. @Matic Oblak есть ли какой-нибудь способ сделать то же самое?

4. @Dhiren что ты имеешь в виду под этим? Вы имеете в виду наличие метода, который изменяет текст без вызова перезагрузки в представление коллекции?

5. нет, я имею в виду, не принимая «currentHeaderText» и не касаясь метода viewForSupplementaryElementOfKind.