https://nemecek.be/blog/71/using-background-decoration-views-with-compositional-layout
URLProtocol을 사용하면
mockURLProtocol 오브젝트를 만들면됨
테스트를 위해서 본코드를 바꾸면 안됨
인스턴스 생성 제한
무거운 작업
https://limjs-dev.tistory.com/105
protocol ModelDelegate: class {
}
class Model {
weak var delegate: ModelDelegate?
deinit {
print("deinit Model")
}
}
class ViewController: ModelDelegate {
var model: Model?
func start() {
model = Model()
model?.delegate = self
}
deinit {
print("deinit ViewController")
}
}
var v: ViewController? = ViewController()
v?.start()
v = nil
// MARK: setup Components
extension BoxOfficeViewController {
// ...
private func setupCollectionView() {
let layout = verticalLayout()
// BackgroundDecorationView 등록, collectionView가 아닌 layout에 등록
layout.register(BackgroundDecorationView.self, forDecorationViewOfKind: "background")
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.register(BoxOfficeCollectionViewCell.self, forCellWithReuseIdentifier: BoxOfficeCollectionViewCell.identifier)
collectionView.delegate = self
}
private func setupRefreshControl() {
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(fetchBoxOfficeData), for: .valueChanged)
collectionView.refreshControl = refreshControl
}
}
// MARK: CollectionView Layout
extension BoxOfficeViewController {
private func verticalLayout() -> UICollectionViewCompositionalLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(0.1))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets = NSDirectionalEdgeInsets(top: 1, leading: 0, bottom: 0, trailing: 0)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.2))
let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
// orthogonalScrollingBehavior 세팅 특정 섹션 가로 스크롤
section.orthogonalScrollingBehavior = .continuous
// visibleItemsInvalidationHandler 클로져 블럭 구현, 아이템이 보이기 직전 아이템 설정
section.visibleItemsInvalidationHandler = { [weak self] (visibleItems, offset, env) in
guard let self = self else { return }
visibleItems.forEach({ item in
guard let cell = self.collectionView.cellForItem(at: item.indexPath) else { return }
UIView.animate(withDuration: 0.3) {
cell.backgroundColor = .systemBackground
}
})
}
// decorationItems 설정, 섹션의 백그라운드 설정
let backgroundItem = NSCollectionLayoutDecorationItem.background(elementKind: "background")
section.decorationItems = [backgroundItem]
return UICollectionViewCompositionalLayout(section: section)
}
}
// 섹션에 넣을 UICollectionReusableView 구현
class BackgroundDecorationView: UICollectionReusableView {
override init(frame: CGRect) {
super.init(frame: frame)
// Configure your decoration view's appearance here
self.backgroundColor = .systemFill
// self.layer.cornerRadius = 12
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}