Das letzte Mal habe ich [Artikel zur Implementierung von UICollectionView von iOS14] geschrieben (https://qiita.com/maruiyugo/items/70b02bf22bec51f3b97a "Qiita"). Es scheint also, dass sich der Umgang mit benutzerdefinierten Zellen geändert hat. Schreiben wir dies also auch in den Artikel! Ich habe es in dem Gedanken geschrieben, aber es war schwierig, weil sich die Behandlung gegenüber zuvor erheblich geändert hat. Ich mache mir Sorgen, wenn es richtig ist, also irre ich mich hier, du solltest das schreiben! Bitte kommentieren Sie, wenn Sie welche haben: durchhalten:
Es ist nur eine Zellklasse. Ich mache nichts Besonderes.
Es hält den Staat. "isSelected" und "isFocused" werden standardmäßig bereitgestellt. Sie können auch anpassen und hinzufügen. (Diesmal nicht behandelt.)
Erstellen Sie eine benutzerdefinierte Ansicht.
Eine Klasse, die eine benutzerdefinierte Ansicht initialisiert, die anzuzeigenden Daten von der Zelle und "UICellConfigurationState" empfängt, sie in der benutzerdefinierten Ansicht widerspiegelt und die Ansicht an die Zelle zurückgibt. Es ist das Wichtigste. Es ist Nummer 4.
Setzen Sie einen Stern, um einen Unterschied zum vorherigen Artikel zu machen. ..
Insgesamt gibt es 6 Dateien.
SimpleCustomCell.storyboard
SimpleCustomCellViewController.swift
SimpleCustomCell.swift
SimpleCustomCellConfiguration.swift
SimpleCustomCellView.xib
SimpleCustomCellView.swift
SimpleCustomCellViewController.swift
SimpleCustomCellViewController.swift
class SimpleCustomCellViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
enum Section: CaseIterable {
case kanto
case kyusyu
}
let data: [Section: [String]] = [
.kanto: ["Kanto", "Tokyo", "Chiba"],
.kyusyu: ["Kyusyu", "Fukuoka", "Miyazaki"]
]
var collectionViewDataSource: UICollectionViewDiffableDataSource<Section, String>!
override func viewDidLoad() {
super.viewDidLoad()
var layoutConfig = UICollectionLayoutListConfiguration(appearance: .grouped)
layoutConfig.headerMode = UICollectionLayoutListConfiguration.HeaderMode.firstItemInSection
let layout = UICollectionViewCompositionalLayout.list(using: layoutConfig)
collectionView.collectionViewLayout = layout
collectionViewDataSource = createDataSource()
reloadList()
}
func createDataSource() -> UICollectionViewDiffableDataSource<Section, String> {
let normalCell = UICollectionView.CellRegistration<UICollectionViewListCell, String> { (cell, indexPath, text) in
var content = cell.defaultContentConfiguration()
content.text = text
cell.contentConfiguration = content
}
let customCell = UICollectionView.CellRegistration<SimpleCustomCell, String> { (cell, indexPath, text) in
cell.title = text
}
return UICollectionViewDiffableDataSource<Section, String>(collectionView: collectionView) {
(collectionView, indexPath, text) -> UICollectionViewCell? in
//Für den Abschnittstitel wird eine normale Zelle verwendet.
if indexPath.row == 0 {
return collectionView.dequeueConfiguredReusableCell(using: normalCell, for: indexPath, item: text)
} else {
return collectionView.dequeueConfiguredReusableCell(using: customCell, for: indexPath, item: text)
}
}
}
func reloadList(){
var snapshot = NSDiffableDataSourceSnapshot<Section, String>()
snapshot.appendSections(Section.allCases)
snapshot.appendItems(data[.kanto]!, toSection: .kanto)
snapshot.appendItems(data[.kyusyu]!, toSection: .kyusyu)
collectionViewDataSource.apply(snapshot)
}
}
Dies ist der einzige Ort, der etwas Besonderes ist. Beim Festlegen von "UICollectionViewListCell" habe ich die Methode "defaultContentConfiguration" aufgerufen, um den Inhalt festzulegen. Da der Prozess jedoch auf "SimpleCustomCell" verschoben wurde, übergebe ich hier nur "title".
let customCell = UICollectionView.CellRegistration<SimpleCustomCell, String> { (cell, indexPath, text) in
cell.title = text
}
SimpleCustomCell.swift
SimpleCustomCell.swift
class SimpleCustomCell: UICollectionViewListCell {
var title: String!
override func updateConfiguration(using state: UICellConfigurationState) {
var newConfiguration = SimpleCustomCellConfiguration()
newConfiguration.title = title
contentConfiguration = newConfiguration
}
}
updateConfiguration
ist eine Methode, die aufgerufen wird, wenn die Daten auf die collectionView angewendet werden und wenn die Methode setNeedsUpdateConfiguration
aufgerufen wird und das Layout aktualisiert werden muss.
Hier wird die Konfiguration initialisiert und die Daten (Titel) werden gepackt und in die contentConfiguration der Zelle selbst gesetzt.
(Der Argumentstatus wird nicht verwendet, da er diesmal den Status nicht verarbeitet.)
SimpleCustomCellConfiguration.swift
SimpleCustomCellConfiguration.swift
struct SimpleCustomCellConfiguration: UIContentConfiguration, Hashable {
var title: String?
func makeContentView() -> UIView & UIContentView {
return SimpleCustomCellView(configuration: self)
}
func updated(for state: UIConfigurationState) -> Self {
return self
}
}
Die Methode makeContentView
ist eine Methode, die eine Ansicht erstellt, die in einer Zelle angezeigt werden soll.
Sich als Argument an die Ansicht übergeben.
Die "aktualisierte" Methode ist eine Methode, die aufgerufen wird, wenn sich der Status ändert. Es wird nicht verwendet.
SimpleCustomCellView.xib(.swift)
SimpleCustomCellView.swift
class SimpleCustomCellView: UIView, UIContentView {
@IBOutlet var nameLabel: UILabel!
var configuration: UIContentConfiguration
init(configuration: SimpleCustomCellConfiguration) {
self.configuration = configuration
super.init(frame: .zero)
loadNib()
setUpUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func loadNib() {
let nib = UINib(nibName: "\(SimpleCustomCellView.self)", bundle: nil)
guard let view = nib.instantiate(withOwner: self, options: nil).first as? UIView else { return }
view.frame = frame
addSubview(view)
}
private func setUpUI() {
guard let configuration = configuration as? SimpleCustomCellConfiguration else { return }
nameLabel.text = configuration.title
}
}
Ich lade xib und setze die übergebenen Konfigurationsdaten auf Label. Insbesondere gibt es nichts zu erklären.
Es scheint, dass die Verwendung von "Konfiguration" die Wiederverwendung leichter und einfacher macht. Im Vergleich zur herkömmlichen Methode mit Delegate und DataSource wusste ich nicht, wo und welche Methode aufgerufen wurde, und ich hatte das Gefühl, dass das Gefühl der Black Box zunahm. Wird es mich nicht stören, wenn ich mich daran gewöhnt habe? ..
Als nächstes werde ich einen Artikel mit dem Status schreiben, den ich dieses Mal nicht verwendet habe. Bitte LGTM, wenn Sie möchten, da es kahl sein wird \ (^ o ^) /
Klicken Sie hier für Git! https://github.com/ymarui/iOS14_UICollectionView_sample
https://qiita.com/shiz/items/4227accc7d13ae439d1d#推奨される使用方法 https://swiftsenpai.com/development/collectionview-expandable-list-part2/
Recommended Posts