Я новичок в Swift и хочу создавать свои первые приложения. В приложении я использую collectionViews, потому что я следую совету Построим это приложение на Youtube.
В моем приложении я хочу иметь вертикальный collectionView. В этом collectionView я хочу другой collectionView, который состоит из 2 разных ячеек: 1x TitleCell и? X ContentCell.
Для этих ячеек отправляется API-запрос для установки их значений. После завершения API-вызова я перезагружаю collectionView с помощью:
self.collectionView.reloadData()
К сожалению, когда я перезагружаю данные, мой TitleCell перезаписывается ContentCell. Как я прочитал в быстрых документах о reloadData (): при его вызове он стирает каждую ячейку и заменяет ее последней вызванной ячейкой: в моем случае ContentCell.
Поэтому мой вопрос заключается в том, есть ли способ перезагрузить TitleCell и ContentCell таким образом, чтобы они не перезаписывались?
А также: это плохая практика - создавать collectionView с двумя разными клетки?
Вот мой код:
API:
class ApiService: NSObject {
static let sharedInstance = ApiService()
var contentBaseUrl = "netAddress"
func fetchContent(from url: String, completion: @escaping ([ContentModel]) -> ()) {
fetchFeedForUrlString(urlString: "\(contentBaseUrl)/"folder"/\(url)", completion: completion)
}
func fetchFeedForUrlString<T: Decodable>(urlString: String, completion: @escaping (T) -> ()) {
let url = URL(string: urlString)
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
guard let data = data else {
return
}
do {
let json = try JSONDecoder().decode(T.self, from: data)
DispatchQueue.main.async {
completion(json)
}
} catch let jsonError {
print(jsonError)
}
}
task.resume()
}
}
CollectionView, который вызывает API:
class VHomeCell: BaseCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
var firstCell = true
var content: [ContentModel]?
override func setupViews() {
super.setupViews()
fetchVideos()
collectionView.register(HomeContentCell.self, forCellWithReuseIdentifier: "ContentCellID")
collectionView.register(LeagueCell.self, forCellWithReuseIdentifier: "TitleCellID")
}
//Method that causes the "error"
func fetchMatches() {
ApiService.sharedInstance.fetchData(from: "ApiNetworkAddress", completion: { (content: [ContentModel]) in
self.content = content
self.collectionView.reloadData()
})
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return content?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if firstCell {
firstCell = false
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TitleCellID", for: indexPath) as! TitleCell
return cell
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ContentCellID", for: indexPath) as! ContentCell
cell.match = matches?[indexPath.item]
return cell
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: frame.width, height: 50)
}
ContentCell и TitleCell - это всего лишь 2 UICollectionView Cells с различным содержанием в них:
class TitleCell: BaseCell {
var content: ContentModel? {
didSet {
title.text = content.titleText
}
}
}
class ContentCell: BaseCell {
var content: ContentModel? {
didSet {
content.Text = content.text
}
}
}
Вот используемый BaseCell:
class BaseCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
func setupViews() {
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Я знаю, что мой код нуждается в большой очистке и прочем. Поэтому я рад, если кто-то также может указать, как я могу очистить свой код или сделать его более эффективным.