
기존의 CarMakingContentView 타입
CarMakingContentView 내부에서 정의함
OCP 위반: 섹션의구조가 변경되는 경우 뷰 클래스 전체를 수정해야하며 재사용의 어려움 발생SRP 위반 : **CarMakingContentView**가 섹션 내용 뿐만 아니라 뷰 로직도 담당class CarMakingContentView: UIView
따라서 다음과 같이 **Generic**을 사용하여 CollectionView의 Section 타입을 유연하게 사용하기로 결정하였습니다.
class CarMakingContentView<Section: CarMakingSectionType>: UIView
Conformance of generic class 'CarMakingContentView<Section>' to @objc protocol 'UICollectionViewDelegate' cannot be in an extension@objc 프로토콜을 extension에서 채택할 수 없음.Extensions of generic classes cannot contain '@objc' membersextension CarMakingContentView: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let height = CGSize(width: self.frame.width, height: collectionView.frame.height - Constants.progressBarHeight)
return height
}
}
Objective-C**와의 상호 작용을 위한 프로토콜을 제네릭 클래스에서 확장을 통해 구현하려는 경우 발생하는 문제Objective-C 호환 프로토콜을 사용하는데 문제가 없을 것입니다. 제네릭 클래스와 Objective-C 프로토콜의 상호 작용은 복잡하기 때문에, 이를 분리하여 문제를 해결class CarMakingContentView<Section>: UICollectionView {
let flowLayoutDelegate = FlowLayoutDelegate()
// 나머지 코드 ...
init() {
super.init(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
delegate = flowLayoutDelegate
}
}
class FlowLayoutDelegate: NSObject, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let height = CGSize(width: collectionView.frame.width, height: collectionView.frame.height - Constants.progressBarHeight)
return height
}
}
여기서 FlowLayoutDelegate는 UICollectionViewDelegateFlowLayout를 담당하고, 제네릭 클래스 CarMakingContentView와 Objective-C 프로토콜 간의 충돌을 방지합니다.