Как инициализировать ячейку с текстом, используя init - PullRequest
0 голосов
/ 15 марта 2019

Я застреваю при попытке инициализировать подкласс UICollectionViewCell с каким-то текстом :( Я, конечно, довольно плохо знаком с инициализаторами, и мой обычный неудачный обходной путь (для передачи данных в целом, а не для ячеек) заключается в вызове функция настройки для передачи информации потом. Любые мудрые слова? Большое спасибо заранее.

class MainCell: UICollectionViewCell {
    let titleLbl: UILabel = {
        let lbl = UILabel() // other stuff was in here
        lbl.text = "Placeholder text"
        return lbl
    }()    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupViews()
    }
    func setupViews() {
        // adding to subviews, constraints, etc. Placeholder text works.
    }
}


class SubCell: MainCell {
    convenience init(title: String) {
        self.init()
        titleLbl.text = title
    }
}


SubCell(title: "Test") // doesn't return a cell with "Test" in the label

Решено: Хотел поделиться своим решением на случай, если оно может кому-нибудь помочь. Как указал @rmaddy, я снимал с ячеек клетки, которые не были инициализированы моей строкой.

Я видел, как правило, они основаны на массивах и передаче данных таким образом. Но у меня есть 4 ячейки с разными элементами, и я хотел бы избежать логики indexPath, если это возможно.

Мое решение (я уверен, что я не единственный, но я нигде не мог его найти) заключалось в создании пользовательских классов для каждой ячейки, например, как работают контроллеры представления. Теперь у меня есть массив, который содержит ячейки, и если мне нужно добавить новый, я создаю класс ячейки и добавляю его в список, не вмешиваясь ни в какие ячейки cellId или indexPath. Извините, я продолжаю, я очень взволнован. Вот мой код, если кто-то хочет его прожарить:

class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {


    let cells = [CellOne(), CellTwo(), CellThree(), CellFour()]
    // subclasses of UICollectionViewCell, defined elsewhere


    override init(collectionViewLayout layout: UICollectionViewLayout) {
        super.init(collectionViewLayout: layout)
    }


    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.backgroundColor = bgColor

        for cell in cells {
            collectionView.register(type(of: cell), forCellWithReuseIdentifier: String(describing: type(of: cell)))
        }
    }


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return collectionViewCellSize
    }


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


    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cellType = type(of: cells[indexPath.item])
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: cellType), for: indexPath)
        return cell
    }
}

1 Ответ

2 голосов
/ 15 марта 2019

Вы не хотите передавать строку в инициализаторе.Ячейки используются повторно, и вам необходимо обновить существующие ячейки.Создайте ячейку как обычно, а затем обновите свойство tltleLbl отдельно в cellForRowAt.

Что-то вроде:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "whatever" for: indexPath)
    cell.titleLbl.text = // whatever value is appropriate for this row

    return cell
}
...