Published on

๐Ÿ“ฑ iOS - CompositionalLayout.01

Authors
  • avatar
    Name
    ์ด์ฐฝ์ค€
    Twitter

Compositional Layout

๋†’์€ ๋ฐ˜์‘์„ฑ์„ ๊ฐ–๊ณ  ์œ ์—ฐํ•œ UI ์กฐ์ •์ด ๊ฐ€๋Šฅํ•œ item๋“ค์„ ์กฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ์ž…๋‹ˆ๋‹ค.

์• ํ”Œ์ด Compositional Layout์„ ์†Œ๊ฐœํ•˜๋ฉด์„œ ๋Œ€ํ‘œ์ ์œผ๋กœ ์˜ˆ์‹œ๋ฅผ ๋“  ์•ฑ์ด App Store์™€ ์‚ฌ์ง„ ์•ฑ์ž…๋‹ˆ๋‹ค.

Appstore

์—ฌ๋Ÿฌ๊ฐ€์ง€ ํ˜•ํƒœ์˜ ๋ ˆ์ด์•„์›ƒ๋“ค์ด ์ค„์ง€์–ด ์žˆ์ง€๋งŒ, ์ด ํ™”๋ฉด์€ ๋‹จ ํ•˜๋‚˜์˜ CollectionView๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ์กด์˜ FlowLayout์„ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด ๊ฐ๊ธฐ ๋‹ค๋ฅธ ๋ ˆ์ด์•„์›ƒ์— ๋”ฐ๋ผ ์—ฌ๋Ÿฌ๊ฐœ์˜ CollectionView๋ฅผ ์‚ฌ์šฉํ–ˆ์–ด์•ผ ํ–ˆ์ง€๋งŒ CompositionalLayout์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•˜๋‚˜์˜ CollectionView๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด์ฃ .

๊ทธ๋Ÿฌ๋ฉด์„œ๋„ ์ด์ „๋ณด๋‹ค ์‰ฌ์šด API๋กœ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๊ณ , ๋น ๋ฅด๊ณ  ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™”์— ๋” ์šฐ์ˆ˜ํ•˜๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ๊ฐœ๋…

CompositionalLayout์€ ์„ธ ๊ฐ€์ง€์˜ ํ•ต์‹ฌ ์š”์†Œ์— ์ง‘์ค‘ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

ItemtoLayout

๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„์ธ Item์ด ๋ชจ์—ฌ์„œ Group ์ด ๋˜๊ณ , ํ•˜๋‚˜์˜ ์ค„(row)๋ฅผ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ด Group๋“ค์€ ๋‹ค์‹œ ํ•œ๋ฒˆ ๋ชจ์—ฌ์„œ Section ์„ ์ด๋ฃน๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ๋ชจ๋“  Section์„ Layout์ด ๋‹ด๊ณ  ์žˆ๋Š” ๊ฒƒ์ด์ฃ .

Size

CompositionalLayout์ด ๊ฐ–๊ณ  ์žˆ๋Š” ์ด ๋ชจ๋“  ์š”์†Œ๋“ค์€ ๊ฐ๊ฐ์˜ size๋ฅผ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  size๋Š” ๋ชจ๋‘๊ฐ€ ์•Œ๊ณ ์žˆ๋“ฏ์ด width์™€ height, ๋‘ ๊ฐ€์ง€ ์†์„ฑ์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

class NSCollectionLayoutSize {
	init(
		widthDimension: NSCollectionLayoutDimension,
		heightDimension: NSCollectionLayoutDimension
	)
}

ํ•˜์ง€๋งŒ ์ฃผ์˜ํ•  ์ ์€ ์ด width์™€ height๋Š” ์Šค์นผ๋ผ ๊ฐ’์ด ์•„๋‹™๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ Float์™€ ๊ฐ™์€ ํƒ€์ž…์ด ์•„๋‹ˆ๋ผ NSCollectionLayoutDimension ํƒ€์ž…์˜ ๊ฐ’์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ทจํ•ฉ๋‹ˆ๋‹ค.

class NSCollectionLayoutDimension {
	class func fractionalWidth(_ fractionalWidth: CGFloat) -> Self
	class func fractionalHeight(_ fractionalHeight: CGFloat) -> Self
	class func absolute(_ absoluteDimension: CGFloat) -> Self
	class func estimated(_ estimatedDimension: CGFloat) -> Self
}

์ด ๋„ค ๊ฐ€์ง€ ํƒ€์ž…์œผ๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๊ณ , ๊ฐ๊ฐ์„ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • fractional: ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ(์ปจํ…Œ์ด๋„ˆ)์˜ ํฌ๊ธฐ์— ๋น„๋ก€ํ•˜์—ฌ ํฌ๊ธฐ๋ฅผ ๊ฐ€์งˆ ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
    • .fractionalWidth(0.5), .fractionalHeight(0.3)
  • absolute: ๊ณ ์ •๋œ ๊ฐ’์˜ ํฌ๊ธฐ๋ฅผ ๊ฐ€์งˆ ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
    • .absolute(200)
  • estimated: ๊ณ ์ •๋œ ๊ฐ’์œผ๋กœ ์‹œ์ž‘๋˜์ง€๋งŒ ํฌ๊ธฐ๊ฐ€ ๋ณ€๋™๋  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
    • .estimated(200)

Item

Item์€ ํ™”๋ฉด์— ๋ Œ๋”๋ง๋˜๋Š” ์š”์†Œ์ž…๋‹ˆ๋‹ค.

cell์ด๋‚˜ supplementary view๊ฐ€ ์—ฌ๊ธฐ์— ํ•ด๋‹น๋ฉ๋‹ˆ๋‹ค.

class NSCollectionLayoutItem {
	convenience init(layoutSize: NSCollectionLayoutSize)
	var contentInsets: NSDirectionalEdgeInsets
}

์ดˆ๊ธฐํ™”ํ•  ๋•Œ size๋ฅผ ์ •ํ•ด์ค˜์•ผํ•˜๊ณ , contentInsets๋ฅผ ํ†ตํ•ด inset๋„ ์ •ํ•ด์ค„ ์ˆ˜๊ฐ€ ์žˆ๋„ค์š”.

Group

Group์€ ๋ ˆ์ด์•„์›ƒ์œผ๋กœ์„œ์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋‹จ์œ„๊ฐ€ ๋˜๋Š” ์š”์†Œ์ž…๋‹ˆ๋‹ค.

Group์€ .horizontal, .vertical, .custom์˜ ์„ธ๊ฐ€์ง€ ํ˜•ํƒœ๋กœ ์ •์˜ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ๊ฐ์˜ Group์„ ํ•˜๋‚˜์˜ ์ž‘์€ FlowLayout์ด๋ผ๊ณ  ์ƒ๊ฐํ•ด๋ณด๋ฉด ์ดํ•ด๊ฐ€ ์‰ฝ์Šต๋‹ˆ๋‹ค.

๊ฐ€๋กœ ํ˜น์€ ์„ธ๋กœ ํ•œ์ชฝ ๋ฐฉํ–ฅ์œผ๋กœ ์ญ‰ ์ด์–ด์ง€๋Š” ๋ ˆ์ด์•„์›ƒ์ด๋‹ˆ๊นŒ์š”.

ํ•œ ์ชฝ ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ์ง„ํ–‰๋˜๋Š” Group์ด ์‹ซ๋‹ค๋ฉด .custom์„ ์‚ฌ์šฉํ•ด ์ง์ ‘ ๊ตฌํ˜„ํ•ด์ค„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

class NSCollectionLayoutGroup: NSCollectionLayoutItem {
	class func horizontal(
		layoutSize: NSCollectionLayoutSize,
		subitems: [NSCollectionLayoutItem]) -> Self
	class func vertical(
		layoutSize: NSCollectionLayoutSize,
		subitems: [NSCollectionLayoutItem]) -> Self
	class func custom(
		layoutSize: NSCollectionLayoutSize,
		itemProvider: NSCollectionLayoutGroupCustomItemProvider) -> Self
}

Section

Section์€ ๋ง ๊ทธ๋Œ€๋กœ Section์„ ๊ธฐ์ค€์œผ๋กœ ๋‚˜์—ด๋˜๋Š” CollectionView์˜ Section์ž…๋‹ˆ๋‹ค.

๊ธฐ์กด์— ์‚ฌ์šฉํ•˜๋˜ Layout๋“ค์˜ Section๊ณผ ๋™์ผํ•œ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค.

dataSource๋กœ๋ถ€ํ„ฐ Item์˜ ๊ฐœ์ˆ˜๋ฅผ ๋ฐ›์•„์™€ Section์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

class NSCollectionLayoutSection {
	convenience init(layoutGroup: NSCollectionLayoutGroup)
	var contentInsets: NSDirectionalEdgeInsets
}

Layout

๊ทธ๋ ‡๋‹ค๋ฉด ๋ ˆ์ด์•„์›ƒ์„ ์ดˆ๊ธฐํ™”ํ•ด์ค„๋•Œ๋Š” ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋ ๊นŒ์š”?

์• ํ”Œ์€ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

class UICollectionViewCompositionalLayout: UICollectionViewLayout {
	init(section: NSCollectionLayoutSection)
	init(sectionProvider: @escaping SectionProvider)
}
  • init(section: NSCollectionLayoutSection)

๋ ˆ์ด์•„์›ƒ์˜ ์„น์…˜์„ ์ง์ ‘ ์ง€์ •ํ•ด์ฃผ๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

์‰ฝ๊ณ  ๊ฐ„๋‹จํ•˜์ง€๋งŒ ํ˜„์žฌ ์‚ฌ์šฉ๋˜๋Š” ๋ ˆ์ด์•„์›ƒ ๋ฐฉ์‹๊ณผ ์ฐจ๋ณ„์„ฑ์ด ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค.

  • init(sectionProvider: @escaping SectionProvider)

Compositionalํ•˜๊ฒŒ Section๋“ค์„ ๊ตฌ์„ฑํ•ด์ฃผ๋ ค๋ฉด ์ด ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@escaping ํด๋กœ์ €๊ฐ€ ๋ณด์ด์‹œ์ฃ ?

์ด ํด๋กœ์ € ์•ˆ์—์„œ ๊ฐ Section๋งˆ๋‹ค์˜ ๋…๋ฆฝ์ ์ธ ์„ค์ •์„ ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ •ํ™•ํžˆ ํ•ด๋‹น ๊ณผ์ •์ด ์–ด๋–ป๊ฒŒ ์ด๋ฃจ์–ด์ง€๋Š”๊ฐ€๋Š” ํ™œ์šฉ ์˜ˆ์‹œ์—์„œ ๋‹ค์‹œ ํ•œ๋ฒˆ ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ™œ์šฉ ์˜ˆ์‹œ

๊ฐ„๋‹จํ•œ ํ…Œ์ด๋ธ” ๋ฆฌ์ŠคํŠธ

private func configureLayout() -> UICollectionViewLayout {
	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 = UICollectionViewCompositionalLayout(section: section)
	return layout
}

TableList

๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ํ˜•ํƒœ์˜ Layout์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•œ๊ฐ€์ง€ ์ฃผ๋ชฉํ•  ์ ์€ ์ด ๊ฒฝ์šฐ์— ๊ฐ cell์˜ size๋ฅผ Item์ด ์•„๋‹ˆ๋ผ Group์„ ํ™œ์šฉํ•ด์„œ ์ •ํ•ด์ฃผ์—ˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

.horizontal ๋ฐฉํ–ฅ์˜ Group์—๋Š” ๊ฐ๊ฐ ํ•˜๋‚˜์˜ Item๋งŒ์„ ๊ฐ–๊ณ  ์žˆ๋Š” ํ˜•ํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ itemSize์˜ ํฌ๊ธฐ๋Š” width, height ๋ชจ๋‘ .fractional(1.0)์œผ๋กœ ๊ทธ๋ฃน์„ ๊ฝ‰ ์ฑ„์›Œ์ฃผ์—ˆ์ฃ .

๋Œ€์‹  groupSize์˜ ํฌ๊ธฐ๋ฅผ width๋Š” .fractional(1.0), height๋ฅผ .absolute(44)๋กœ ์ง€์ •ํ•ด์ฃผ์–ด ๊ฐ€๋กœ๋ฅผ ๊ฝ‰ ์ฑ„์šฐ์ง€๋งŒ ๋†’์ด๋Š” 44๋กœ ๊ณ ์ •์‹œ์ผœ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•œ ์ค„์˜ ๊ฐœ์ˆ˜๊ฐ€ 5๊ฐœ๋กœ ๊ณ ์ •๋œ ๊ทธ๋ฆฌ๋“œ

VerticalGrid

HorizontalGrid

์ด๋ฒˆ์—๋Š” ๋ฌด์กฐ๊ฑด ํ•œ ์ค„์— ๋ฌด์กฐ๊ฑด 5๊ฐœ์˜ cell์ด ๋“ค์–ด๊ฐ€๊ณ , ์ •์‚ฌ๊ฐํ˜•์˜ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ ธ์•ผ ํ•˜๋Š” ๊ทธ๋ฆฌ๋“œ ํ˜•์‹์˜ ์ปฌ๋ ‰์…˜๋ทฐ์ž…๋‹ˆ๋‹ค.

์ด ๊ฒฝ์šฐ๋Š” ์œ„์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ ์ฝ”๋“œ์—์„œ size ๊ฐ’๋งŒ ๋ณ€๊ฒฝํ•ด์ฃผ๋Š” ๊ฒƒ ๋งŒ์œผ๋กœ๋„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

private func configureLayout() -> UICollectionViewLayout {
	let itemSize = NSCollectionLayoutSize(
		widthDimension: .fractionalWidth(0.2),
		heightDimension: .fractionalHeight(1.0)
	)
	let item = NSCollectionLayoutItem(layoutSize: itemSize)

	let groupSize = NSCollectionLayoutSize(
		widthDimension: .fractionalWidth(1.0),
		heightDimension: .fractionalWidth(0.2)
	)
	let group = NSCollectionLayoutGroup.horizontal(
		layoutSize: groupSize,
		subItems: [item]
	)

	let section = NSCollectionLayoutSection(group: group)

	let layout = UICollectionViewCompositionalLayout(section: section)
	return layout
}

๊ฐ ์•„์ดํ…œ๋“ค์˜ width๋Š” ๊ทธ๋ฃน ๋„“์ด์˜ 20% (.fractionalWidth(0.2))๋กœ, ๊ฐ ๊ทธ๋ฃน๋“ค์˜ height๋Š” ์„น์…˜ ๋„“์ด์˜ 20% (.fractionalWidth(0.2))๋กœ ์ง€์ •ํ•ด์ฃผ์–ด ์ •์‚ฌ๊ฐํ˜•์˜ ํ˜•ํƒœ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

GridInset

private func configureLayout() -> UICollectionViewLayout {
	let itemSize = NSCollectionLayoutSize(
		widthDimension: .fractionalWidth(0.2),
		heightDimension: .fractionalHeight(1.0)
	)
	let item = NSCollectionLayoutItem(layoutSize: itemSize)
	item.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5)

	let groupSize = NSCollectionLayoutSize(
		widthDimension: .fractionalWidth(1.0),
		heightDimension: .fractionalWidth(0.2)
	)
	let group = NSCollectionLayoutGroup.horizontal(
		layoutSize: groupSize,
		subItems: [item]
	)

	let section = NSCollectionLayoutSection(group: group)

	let layout = UICollectionViewCompositionalLayout(section: section)
	return layout
}

item.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5) ์ด ๋ถ€๋ถ„๋งŒ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค!

inset์˜ ์žฅ์ ์€ Layout์˜ ๋ณ€ํ™” ์—†์ด๋„ ์‹ค์ œ๋กœ ๋ณด์—ฌ์ง€๋Š” ๊ฐ cell์˜ ํฌ๊ธฐ๋ฅผ ๋ณ€๊ฒฝํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š” ๋น„์Šทํ•˜์ง€๋งŒ ๊ทธ๋ฆฌ๋“œ ํ˜•ํƒœ์ง€๋งŒ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•ด๋ด…์‹œ๋‹ค.

private func configureLayout() -> UICollectionViewLayout {
	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,
		repeatingSubItem: item,
		count: 2
	)
	let spacing: CGFloat = 10.0
	group.interItemSpacing = .fixed(spacing)

	let section = NSCollectionLayoutSection(group: group)
	section.interGroupSpacing = spacing
	section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)

	let layout = UICollectionViewCompositionalLayout(section: section)
	return layout
}

์ด ๊ฒฝ์šฐ์— itemSize์˜ width์™€ height๋ฅผ ๋ชจ๋‘ .fractional(1.0)์œผ๋กœ ์ฃผ์—ˆ์ง€๋งŒ, ์ด ๊ฐ’์€ ์•„๋ž˜์˜ Group ์„ค์ •์—์„œ override๋ฉ๋‹ˆ๋‹ค.

let group = NSCollectionLayoutGroup.horizontal(
	layoutSize: groupSize,
	subItem: item,
	count: 2
)

์ด๋ ‡๊ฒŒ Item์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ทธ๋ฃน๋ณ„๋กœ ์ง€์ •ํ•ด์ฃผ๋ฉด, CompositionalLayout์ด ์•Œ์•„์„œ Item์˜ ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ •ํ•ด์ค๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๊ฐœ์˜ Section์„ ๊ฐ–๋Š” ๊ฒฝ์šฐ

์ง€๊ธˆ๊นŒ์ง€๋Š” Section์ด ํ•˜๋‚˜์ธ ๊ฒฝ์šฐ, ์ฆ‰ FlowLayout์œผ๋กœ๋„ ๋ณ„ ์–ด๋ ค์›€ ์—†์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฒฝ์šฐ๋“ค์ด์˜€์Šต๋‹ˆ๋‹ค.

CompositionalLayout์ด ์ด๊ฑธ ์œ„ํ•ด์„œ ๋“ฑ์žฅํ•œ ๊ฑด ์•„๋‹ˆ์˜€์ฃ .

์—ฌ๋Ÿฌ๊ฐœ์˜ Section์„ ๊ฐ–๊ณ , ๊ฐ๊ฐ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค.

Compositional

func createLayout() -> UICollectionViewLayout {
	let layout = UICOllectionViewCompositionalLayout { sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment -> NSCollectionLayoutSection? in
		guard let sectionLayoutKind = SectionLayoutKind(rawValue: sectionIndex) else { return nil }
		let columns = sectionLayoutKind.columnCount

		// ์œ„ ๊ฒฝ์šฐ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์•„๋ž˜ group ์„ค์ •์—์„œ override๋จ
		let itemSize = NSCollectionLayoutSize(
			widthDimension: .fractionalWidth(1.0),
			heightDimension: .fractionalHeight(1.0)
		)
		let item = NSCollectionLayoutItem(layoutSize: itemSize)
		item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)

		let groupHeight = columns == 1 ?
			NSCollectionLayoutDimension.absolute(44) :
			NSCollectionLayoutDimension.fractionalWidth(0.2)
		let groupSize = NSCollectionLayoutSize(
			widthDimension: .fractionalWidth(1.0),
			heightDimension: groupHeight
		)
		let group = NSCollectionLayoutGroup.horizontal(
			layoutSize: groupSize,
			subitem: item,
			count: columns
		)
	}
}

๊ต‰์žฅํžˆ ๊ต‰์žฅํžˆ ๊ธธ์–ด ๋ณด์ด์ง€๋งŒ ํ•ต์‹ฌ์€ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

let layout = UICollectionViewCompositionalLayout { sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment -> NSCollectionLayoutSection? in
	// 
}

์ด ๋ถ€๋ถ„์ด์ฃ .

์ด ๋ชจ๋“  ์„ค์ •๋“ค์€ SectionProvider ํด๋กœ์ € ์•ˆ์— ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋‘ ๊ฐœ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

sectionIndex๋Š” ๋ง ๊ทธ๋Œ€๋กœ Section์˜ index๊ณ , layoutEnvironment๋Š” size๋‚˜ display scale๊ณผ ๊ฐ™์€ container์˜ ํ”„๋กœํผํ‹ฐ๋“ค์„ ์ œ๊ณตํ•ด์ฃผ๋Š” ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค.

SectionLayoutKind๋Š” sectionIndex ๊ฐ’์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์•„ Section์˜ ์ข…๋ฅ˜๋ฅผ ๊ฒฐ์ •ํ•ด์ฃผ๊ณ , ํ•˜๋‚˜์˜ column์— ๋ช‡๊ฐœ์˜ Item์ด ๋“ค์–ด๊ฐ€๋Š”์ง€๋ฅผ ์ •ํ•ด์ฃผ๋Š” enum ํƒ€์ž…์ž…๋‹ˆ๋‹ค.

enum SectionLayoutKind: Int, CaseIterable {
	case list, grid5, grid3

	var columnCount: Int {
		switch self {
		case .grid3:
			return 3
		case .grid5:
			return 5
		case .list:
			return 1
		}
	}
}

์ด๋ ‡๊ฒŒ Section์˜ index์— ๋”ฐ๋ผ์„œ ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ Layout์„ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.