์ด๋ชจ์ ๋ชจ/UIKit
Modern UIKit Collection, TableView #2-1
ARpple
2023. 9. 3. 15:46
Advances in Collection View Layout - 1
Advances in Collection View Layout - WWDC19 - Videos - Apple Developer
Collection View Layouts make it easy to build rich interactive collections. Learn how to make dynamic and responsive layouts that range...
developer.apple.com
๐ก Collection View Layout์ ์ฌ์ฉํ๋ฉด ํ๋ถํ interactive ์ปฌ๋ ์ ์ ์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.๊ธฐ๋ณธ ๋ชฉ๋ก๋ถํฐ ๋ค์ฐจ์ ํ์ ํ๊ฒฝ๊น์ง ๋์ ์ด๊ณ ๋ฐ์์ด ๋น ๋ฅธ ๋ ์ด์์์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์.
๊ธฐ์กด UICollectionViewFlowLayout ๋ฐฉ์์ ๋ฌธ์ ์
- ๋จ์ํ ๊ทธ๋ฆฌ๋ ํ์์๋ ํฐ ๋์์ด ๋๋ค.
- Line based → ๋จ์ผ gird๋ง ์ง์ํ๋ค.
- ํ์ฌ๋ ์๋ง์ ๋ณต์กํ ์ปค์คํ ๋ ์ด์์์ ์ง์ํด์ผํ๋ค.
์ ํ์ ๊ธฐ์กด Collection Layout ๋ฐฉ์์ผ๋ก ์๋ก์ด "์ฑ ์คํ ์ด" ์ฑ์ ๋ง๋๋ ๊ฒ์ ํฌ๊ธฐํ๋ค...
๊ธฐ์กด ์ปค์คํ ๋ ์ด์์ ์ ์์ ๋ฌธ์ ์
- Boilerplate code
⇒ ๋จ์ ๋ฐ๋ณต๋๋ ์ฝ๋ - ํผํฌ๋จผ์ค ๊ณ ๋ ค์ฌํญ์ ์ฆ๊ฐ
- Supplementary and decoration view challenges
⇒ ์ ๋ฐ ์น์ ์ ์ถ๊ฐ๋๋ ๋ทฐ (์น์ ํค๋, ํธํฐ, ์์ดํ ๋ฑ์ง ๋ฑ๋ฑ…) ๋ง๋ค๊ธฐ ๋ณต์กํจ - Self-sizing challenges
⇒ ์ ๋ฐ ์น์ ์ด ์์ฒด์ ์ธ ์ฌ์ด์ฆ๋ฅผ ์ค์ ํ๊ฒ ๋ง๋๋ ๊ฒ์ ๋ํ ์ด๋ ค์
Compositional Layout์ ํน์ง
์ ์ ๋ชฉ์
- Composable (๊ตฌ์ฑ ๊ฐ๋ฅํจ) ⇒ ๊ฐ๊ฐ์ ์์ญ๋ณ๋ก ์์ฒด์ ์ธ (์: ์ฑ์คํ ์ด์ ์ถ์ฒ ์ฑ ๋ฆฌ์คํธ) ๋ ์ด์์ ๊ตฌ์ฑ ๊ฐ๋ฅ..?
- Flexible (์ ์ฐํจ) ⇒ ์ฑ์คํ ์ด ์ ๋์ ๋ค์ํ ๋ ์ด์์์ ์ ์ฐํ๊ฒ ์ ์ฉ ๊ฐ๋ฅ
- Fast (๋น ๋ฆ) ⇒ ๋ญ๊ฐ ๋น ๋ฅด๋ค๋ ๊ฒ์ธ์ง๋ ๋ชจ๋ฅด๊ฒ ๋ค.
๐ก ๊ธฐ์กด์๋ ๋ค์ํ ํํ์ CollectionView๋ฅผ ๋ง๋๋ ค๋ฉด WrapperCell์ ๋ง๋ค์ด์ WrapperCell ๋ด๋ถ์ CollectionView๋ฅผ ๋ค์ ์ ์ํ๋ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๊ฐ์ ธ์ผํ๋ค. ํ์ง๋ง Compoisional Layout์ ๊ฐ๋ ๊ณผ ๊ตฌ์กฐ๋ฅผ ์ด๋ฃจ๋ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋ค์ํ ๋ ์ด์์์ ํํํ๊ธฐ ์ํ WrapperCell๋ฅผ ๋ง๋ค ํ์๊ฐ ์๋ค..!
๊ธฐ์กด ๋ฐฉ์์ผ๋ก ์ฑ์คํ ์ด๋ฅผ ๋ง๋ค๋ฉด ๋ฐ์ํ๋ ๋ฌธ์ ๋ฅผ ํํํ๋ ์์ ์ฝ๋
class CollectionVC: UIViewController{
let collectionView = UICollectonView()
...
override func viewDidLoad(){
collectionView.register(BannerSectionWrapperCell.self)
...
}
}
class BannerSectionWrapperCell: UICollectionViewCell{
let bannerCollectionView = UICollectionView() // <- ์ฌ๊ธฐ๊ฐ ๋ฌธ์ ..!
// Why? ์ถ๊ฐ์ ์ธ Delegate ์ฝ๋์ DataSource ์ฝ๋ ์์ฑ ์ฑ๋ฅ ๋ฌธ์
// + ๋ฐ์ดํฐ๋ฅผ ViewController์ ๋๊ธฐ๋๋ฐ ๋ณต์กํ ๋ฌธ์ ๋ฑ๋ฑ...
...
func configureView(){
bannerCollectionView.register(BannerItemCell.self) // <- ์ฌ๊ธฐ๋ ๋ฌธ์ ..!
}
}
class BannerItemCell:UICollectionViewCell{
}
๊ตฌํ ํน์ง
- Composing small layout groups together
⇒ ์์ ๋ ์ด์์ ๊ทธ๋ฃน์ ํจ๊ป ๊ตฌ์ฑํ๋ค. - Layout groups are line-based
⇒ ํ๋์ ์์ง์ , ์ํ์ ๊ธฐ์ค์ผ๋ก ๊ทธ๋ฃน์ ํ์ํ๋ค. - Composition instead of subclassing
⇒ ์๋ธํด๋์ค ๋์ ์ฝ๋ ์ ๋ทฐ ๋ ์ด์์ ๊ตฌ์ฑ ๊ฐ๋ฅ
์ต์ ๊ตฌํ ๊ตฌ์ฑ ์์ 5๊ฐ์ง
- NSCollectionLayoutSize
- NSCollectionLayoutItem
- โญ NSCollectionLayoutGroup
- NSCollectionLayoutSection
- UICollectionViewCompositionalLayout
- ๊ตฌํ ์์ ์ฝ๋
func createBasicListLayout() -> NSCollectionViewLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .absolute(44))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
subitems: [item])
let section = NSCollectionLayoutSection(group: group)
let layout = NSCollectionViewCompositionalLayout(section: section)
return layout
}
๊ธฐ๋ณธ ๋งค์ปค๋์ฆ ์ดํด ๋ฐ ์ ๋ฆฌ
์ฌ๊ท์ ์ด๊ณ ๋ฐ๋ณต์ ์ธ ๊ตฌ์ฑ
1. ๊ณ์ธต ๊ตฌ์กฐ์ MainTree
- Layout์ ํฌ๊ธฐ๋ CollectionView์ ํฌ๊ธฐ๋ฅผ Bounds๋ก ๋ฐ๋๋ค.
- Section์ Layout์์ ์ค์ ํ ํฌ๊ธฐ์ Bounds๋ก ๊ฐ๋๋ค.
- Group์ Section์์ ์ค์ ํ ํฌ๊ธฐ๋ฅผ Bounds๋ก ๊ฐ๋๋ค.
- Item์ Group์์ ์ค์ ํ ํฌ๊ธฐ๋ฅผ Bounds๋ก ๊ฐ๋๋ค.
- NSCollectionLayoutSize๋ก ์ด๋ค์ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ ์ ์๋ค.
2. Supplementary & Configuration
- MainTree์ ์ง์ ๊ด์ฌํ์ง ์์ง๋ง MainTree์ ์ปดํฌ๋ํธ ์ธ์คํด์ค๋ค์ ๊พธ๋ฏธ๊ฑฐ๋ ์ปค์คํ
ํ๊ธฐ ์ํ ์์ฒด์ ์ธ Configuration์ ๊ฐ๊ณ ์๋ค.
- ์ด ์ปค์คํ ์ ์ฃผ๋ก MainTree์ ํ์ ์ปดํฌ๋ํธ๋ค ๊ฐ๊ฒฉ์ ์ฃผ๊ฑฐ๋, ์คํฌ๋กค ๋ฐฉํฅ์ ์ค์ ํ๋ ์ ๋
- MainTree ์ปดํฌ๋ํธ๊ฐ ์์ฒด์ ์ธ SubView์ ์์ญ์ ํ ๋นํ๊ธฐ ์ํด Supplementary ๊ฐ๋
์ ์ฌ์ฉํ๋ค.
- ์ด Supplementary๋ ์ฃผ๋ก ์ปดํฌ๋ํธ์ Header, Footer, Badge๋ฅผ ๋ด๋น
3. Provider with ElementKind & SubItems(Array)
ํ๋์ ์ปดํฌ๋ํธ์ ๋จ์ผ ํ์ ์ปดํฌ๋ํธ๊ฐ ์๋ ๋ค์ํ ํ์ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ๊ธฐ ์ํด์ ์ฌ์ฉํ๋ ๊ฐ๋