Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- clean architecture
- combine
- ios
- Clean Code
- UITextView
- HIG
- 스위프트
- Xcode
- swiftUI
- MVVM
- tableView
- 리펙터링
- Protocol
- Refactoring
- 리팩토링
- SWIFT
- Observable
- rxswift
- collectionview
- ribs
- 클린 코드
- UICollectionView
- 애니메이션
- 리펙토링
- uitableview
- map
- swift documentation
- Human interface guide
- RxCocoa
- uiscrollview
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 3. UICollectionViewCompositionalLayout - 둘러보기2 (DecorationView, Badge, NSCollectionLayoutAnchor) 본문
iOS 응용 (swift)
[iOS - swift] 3. UICollectionViewCompositionalLayout - 둘러보기2 (DecorationView, Badge, NSCollectionLayoutAnchor)
jake-kim 2022. 4. 21. 00:501. UICollectionViewCompositionalLayout - 개념 (section, group, item)
2. UICollectionViewCompositionalLayout - 둘러보기1 (SupplementaryView, Header, Footer)
3. UICollectionViewCompositionalLayout - 둘러보기2 (DecorationView, Badge, NSCollectionLayoutAnchor)
5. UICollectionViewCompositionalLayout - 응용 (유튜브 뮤직 앱 UI 구현)
복습) SupplementaryView와 DecorationView
- 애플에서의 개념으로 이해하면, UICollectionView는 크게 3가지로 존재
- item cell: 메인 데이터가 있는 UI
- supplementaryView: 메인 데이터를 보충해주는 UI
- decorationView: 데이터를 표출하지 않는 단순 UI (컬렉션 뷰의 모델과 독립적인 뷰) - 배경, 섹션 하이라이트에 사용
DecorationView로 배경 설정하기
- DecorationView는 섹션별로 적용이 가능
Section에 Decoration이 없는 경우 | Section에 DecorationView를 넣어준 경우 |
- 데이터가 없으므로 데이터를 반영하지 않아도 되는 prepare이 없는 뷰 준비
- SupplementaryView와 동일하게 UICollectionReusableView를 상속하여 구현
import UIKit
class MyDecorationView: UICollectionReusableView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.white.withAlphaComponent(1)
layer.borderColor = UIColor.black.cgColor
layer.borderWidth = 0
layer.cornerRadius = 12
layer.shadowColor = UIColor.black.cgColor
layer.shadowRadius = 5
layer.shadowOpacity = 1
}
required init?(coder: NSCoder) {
fatalError("not implemented")
}
}
- supplementaryView와 다르게 dataSource 델리게이트를 사용하지 않고 간편하게 사용
- supplementaryView는 collectionView.register하지만, 데코레이션뷰는 layout에서 register하여 사용
static func getLayout() -> UICollectionViewCompositionalLayout {
let layout = UICollectionViewCompositionalLayout { (section, env) -> NSCollectionLayoutSection? in
...
layout.register(MyDecorationView.self, forDecorationViewOfKind: "MyDecorationView")
return layout
}
- section에 `decorationItems` 프로퍼티에 데코레이션 뷰를 주입하여 적용
- 시스템에서 제공하는 아래 static method API를 사용하여 위에서 등록한 ofKind 값으로 인스턴스 획득
open class func background(elementKind: String) -> Self
// in getLayout()
// Section
let section = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(top: itemInset, leading: itemInset, bottom: itemInset, trailing: itemInset)
// Decoration
let decorationView = NSCollectionLayoutDecorationItem.background(elementKind: "MyDecorationView")
decorationView.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8)
section.decorationItems = [decorationView]
return section
Badge 사용 방법
- NSCollectionLayoutAnchor 개념
- cell의 우측 상단에 위치하도록 레이아웃을 잡을 때 NSCollectionLayoutAnchor를 사용하여 쉽게 구현 (아래에서 계속)
// 아래에서 볼 코드
// Badge
let badgeItemSize = NSCollectionLayoutSize(widthDimension: .absolute(25), heightDimension: .absolute(25))
let badgeItemAnchor = NSCollectionLayoutAnchor(edges: [.top, .trailing], fractionalOffset: CGPoint(x: 0.3, y: -0.3))
let badgeItem = NSCollectionLayoutSupplementaryItem(
layoutSize: badgeItemSize,
elementKind: "MyBadgeView",
containerAnchor: badgeItemAnchor
)
- BadgeView 정의
- SupplementaryView의 한 종류이므로 UIColelctionReusableView 서브클래싱
import UIKit
final class MyBadgeView: UICollectionReusableView {
private let button: UIButton = {
let button = UIButton()
button.setImage(UIImage(named: "close"), for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.clipsToBounds = true
self.addSubview(button)
NSLayoutConstraint.activate([
self.button.centerXAnchor.constraint(equalTo: self.centerXAnchor),
self.button.centerYAnchor.constraint(equalTo: self.centerYAnchor),
self.button.widthAnchor.constraint(equalToConstant: 25),
self.button.heightAnchor.constraint(equalToConstant: 25),
])
}
required init?(coder: NSCoder) {
fatalError("Not implemented")
}
}
- SupplemtaryView와 마찬가지로 register와 dataSource 델리게이트 설정
// collectionView 초기화 부분
view.register(MyBadgeView.self, forSupplementaryViewOfKind: "MyBadgeView", withReuseIdentifier: "MyBadgeView")
// dataSource 델리게이트
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case "MyBadgeView":
let badgeView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "MyBadgeView", for: indexPath) as! MyBadgeView
return badgeView
...
}
- Item 셀의 우측상단에 위치해야하므로, 해당 레이아웃 작성
- NSCollectionLayoutAnchor를 통해 top, trailing을 걸어주고, 약간의 offset을 주어서 cell보다 더 우측상단에 위치하도록 설정
- 이 item을 정의하고 메인 cell item에 supplementaryItems에 넣어주면 완성
static func getLayout() -> UICollectionViewCompositionalLayout {
let layout = UICollectionViewCompositionalLayout { (section, env) -> NSCollectionLayoutSection? in
...
// Badge
let badgeItemSize = NSCollectionLayoutSize(widthDimension: .absolute(25), heightDimension: .absolute(25))
let badgeItemAnchor = NSCollectionLayoutAnchor(edges: [.top, .trailing], fractionalOffset: CGPoint(x: 0.3, y: -0.3))
let badgeItem = NSCollectionLayoutSupplementaryItem(
layoutSize: badgeItemSize,
elementKind: "MyBadgeView",
containerAnchor: badgeItemAnchor
)
// Item
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(itemFractionalWidthFraction),
heightDimension: .fractionalHeight(1)
)
let item = NSCollectionLayoutItem(layoutSize: itemSize, supplementaryItems: [badgeItem])
...
layout.register(MyDecorationView.self, forDecorationViewOfKind: "MyDecorationView")
return layout
}
* 전체 코드: https://github.com/JK0369/ExCompositionalLayout3
* 참고
https://ebookreading.net/view/book/EB9781484212424_13.html
'iOS 응용 (swift)' 카테고리의 다른 글
Comments