3개 모두 적용. ㅇㅋ.
<aside> ✏️ 2022.10.20 ~ 2022.10.21
새로운 컬렉션 뷰 API를 작성할 때는 순서를 주의해야겠다. 그리고 MVVM을 나눌 때 애매하면 뷰모델에서는 import UIKit를 절대 !! 절대 !! 하지 말자 !!!
</aside>
// MARK: - CollectionView
extension ParkingDetailViewController {
private func createCompositionalLayout() -> UICollectionViewCompositionalLayout {
return UICollectionViewCompositionalLayout { (sectionIndex, NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1),
heightDimension: .fractionalHeight(1))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
if sectionIndex == 0 {
let groupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1),
heightDimension: .absolute(109))
let group = NSCollectionLayoutGroup.horizontal(
layoutSize: groupSize,
subitems: [item])
let headerSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1),
heightDimension: .absolute(0))
let header = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: headerSize,
elementKind: ParkingDetailViewController.sectionHeaderElementKind,
alignment: .bottom
)
let section = NSCollectionLayoutSection(group: group)
section.boundarySupplementaryItems = [header]
return section
} else {
let groupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1),
heightDimension: .absolute(60))
let group = NSCollectionLayoutGroup.horizontal(
layoutSize: groupSize,
subitems: [item])
let headerSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1),
heightDimension: .absolute(60))
let header = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: headerSize,
elementKind: ParkingDetailViewController.sectionHeaderElementKind,
alignment: .top
)
let section = NSCollectionLayoutSection(group: group)
section.boundarySupplementaryItems = [header]
return section
}
}
}
private func createLayout() -> UICollectionViewLayout {
let configuration = UICollectionViewCompositionalLayoutConfiguration()
let layout = createCompositionalLayout()
layout.configuration = configuration
return layout
}
private func configureDataSource() {
let locationCellRegistration = UICollectionView.CellRegistration<ParkingDetailLocationCollectionViewCell, (String, String)> { cell, indexPath, itemIdentifier in
cell.setData(itemIdentifier.0, itemIdentifier.1)
}
let cellRegistration = UICollectionView.CellRegistration<ParkingDetailCollectionViewCell, String> { cell, indexPath, itemIdentifier in
if indexPath.section == 1 {
let arr = ["기본", "추가"]
cell.setData(arr[indexPath.item], itemIdentifier)
} else if indexPath.section == 2 || indexPath.section == 3 {
let arr = ["평일", "토요일", "공휴일"]
cell.setData(arr[indexPath.item], itemIdentifier)
} else {
cell.setData("주차장", itemIdentifier)
}
}
let headerRegistration = UICollectionView.SupplementaryRegistration
<ParkingDetailHeaderView>(elementKind: ParkingDetailViewController.sectionHeaderElementKind) { (supplementaryView, string, indexPath) in
switch indexPath.section {
case 1: supplementaryView.title = "요금"
case 2: supplementaryView.title = "무/유료"
case 3: supplementaryView.title = "운영시간"
case 4: supplementaryView.title = "전화번호"
default: return
}
}
dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView, cellProvider: { collectionView, indexPath, itemIdentifier in
switch itemIdentifier {
case .location(let name, let location):
let cell = collectionView.dequeueConfiguredReusableCell(using: locationCellRegistration, for: indexPath, item: (name, location))
return cell
case .defatultFee(let value), .additionalFee(let value):
let cell = collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: value)
return cell
case .isWeekdayFree(let value), .isSaturdayFree(let value), .isHolidayFree(let value):
let cell = collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: value)
return cell
case .weekdayOperatingTime(let value), .saturdayOperatingTime(let value), .holidayOperatingTime(let value):
let cell = collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: value)
return cell
case .contact(let value):
let cell = collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: value)
return cell
}
})
dataSource.supplementaryViewProvider = { (view, kind, index) in
return self.collectionView.dequeueConfiguredReusableSupplementary(
using: headerRegistration, for: index)
}
}
}
아직 감이 안잡혀서 애매했지만 .. 가장 큰 기준은 UIKit를 import하면 안된다는 것 !!!
import UIKit
import SnapKit
import Then
import NiCarNaeCar_Util
import NiCarNaeCar_Resource
// MARK: - ParkingDetailViewModel
final class ParkingDetailViewModel {
// MARK: - Property
var parkingLot: CObservable<ParkingLot> = CObservable(ParkingLot())
// MARK: - Data Method
func fetchParkingDetailInfo(_ item: ParkingDetailInfo) {
parkingLot.value.name = item.parkingName
parkingLot.value.location = item.addr
processFee(item)
parkingLot.value.isWeekdayFree = item.payNm
parkingLot.value.isSaturdayFree = item.saturdayPayNm
parkingLot.value.isHolidayFree = item.holidayPayNm
processOperatingTime(item)
parkingLot.value.contact = item.tel
}
private func processFee(_ item: ParkingDetailInfo) {
parkingLot.value.defaultFee = "\\(item.rates)원/\\(item.timeRate)분"
parkingLot.value.additionalFee = "\\(item.addRates)원/\\(item.addTimeRate)분"
}
private func processOperatingTime(_ item: ParkingDetailInfo) {
parkingLot.value.weekdayOperatingTime = "\\(stringFormatter(item.weekdayBeginTime)) ~ \\(stringFormatter(item.weekdayEndTime))"
parkingLot.value.saturdayOperatingTime = "\\(stringFormatter(item.weekdayBeginTime)) ~ \\(stringFormatter(item.weekdayEndTime))"
parkingLot.value.holidayOperatingTime = "\\(stringFormatter(item.holidayBeginTime)) ~ \\(stringFormatter(item.holidayEndTime))"
}
private func stringFormatter(_ str: String) -> String {
var time = str
time.insert(":", at: time.index(time.startIndex, offsetBy: 2))
return time
}
}