- Published on
๐ฑ iOS - CollectionView์ Cell/View์์์ subscribe ๋ฌธ์
- Authors
- Name
- ์ด์ฐฝ์ค
โ CollectionView์ HeaderView๋ฅผ ๊ตฌ๋ ํ๋ ๊ณผ์ ์์ ๋ฌธ์ ๋ฐ์
HeaderView
์ ๋ฒํผ์ tap
ํ๋ฉด ๋ฐ์ธ๋ฉ๋ Action
์ด ์ฌ๋ฌ๋ฒ ๋ฐ์ํ๋ ๋ฌธ์ ๋ฐ์
configureSupplementaryView: { dataSource, collectionView, kind, indexPath in
let sectionItem = dataSource[indexPath.section]
let header = collectionView.dequeueReusableSupplementaryView(
ofKind: kind,
for: indexPath) as HeaderView
header.reactor = HeaderViewReactor(section: sectionItem.model)
header.rx.rightButtonDidTap
.map { Reactor.Action.rightButtonDidTap(sectionItem.model) }
.bind(to: self.reactor!.action)
.disposed(by: self.disposeBag)
return header
}
ํด๋น HeaderView
๋ ์์ ๊ฐ์ด ํ ๋น๋์ด ์์ต๋๋ค.
DashboardFlow
์ ๋ณต์ ?
์์ฌ 1.ํด๋น ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์์ ์ด DashboardFlow
๋ฅผ ๊ฑด๋๋ฆด ๋์๊ณ , ํ์ ์ ๊ฐ์ง ๋ชปํ ์ํ์์ ์์
์ ํ๊ณ ์์๊ธฐ ๋๋ฌธ์ ์ฐ์ ์ ์ผ๋ก ์์ฌํ์์ต๋๋ค.
์ค์ ๋ก ๋ค๋ฅธ Flow
๋ก ์ด๋ ํ์ ๋ค์ ๋์์ ๊ฐ์ ์์
์ ์ํํ๋ฉด ํ์๊ฐ ์ฆ๊ฐํ๋ ํ์์ ๋ฐ๊ฒฌํ์๊ธฐ์ ์์ฌ์ ํค์๊ฐ๊ณ ์์์ง๋งโฆ
๋ฉ๋ชจ๋ฆฌ ์ค๋
์ท์ ์ดํด๋ณธ ๊ฒฐ๊ณผ DashboardFlow
๋ ๋จ ํ ๊ฐ๋ง ์์ฑ๋์ด์๋ค..
์ถ๊ฐ์ ์ผ๋ก ์์ฌ๋๋ ๋ถ๋ถ์ธ .contribute(withNext: self.rootViewController)
๋ถ๋ถ์ ์ฃผ์์ฒ๋ฆฌํ๊ณ ์ฑ์ ์คํํด๋ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๋ณด์ ์ด ๋ถ๋ถ์ ๋ฌธ์ ๊ฐ ์๋ ๊ฒ์ผ๋ก ๋ณด์..!
HeaderView
์ Action
์ด ํธ๋ฆฌ๊ฑฐ๋์๋ค..?
์์ฌ 2. ๋ชจ๋ HomeViewReactor
์ ํด๋น Action
์ ๋ฐ๋ ๋ถ๋ถ์์ ๋ก๊น
์ ํด๋ณด์๋ค.
case .rightButtonDidTap(let sectionType):
let type = "\(sectionType)"
os_log(.debug, "\(type)")
switch sectionType {
case .upcoming:
self.steps.accept(AppStep.reminderIsRequired)
case .timeline:
self.steps.accept(AppStep.filterIsRequired(self.currentSortType.value))
}
return .empty()
}
๊ทธ๋ฌ๋๋ ๋ ๊ฐ์ ์น์
(timeline
, upcoming
)์์ ๊ฐ ๋ ๋ฒ์ฉ ๋ก๊น
์ด ๋๊ณ ์๋ ๊ฒ์ ๋ฐ๊ฒฌํ์๋ค.
์๋ ๊ทธ๋ฐ๋ฐ..
configureSupplementaryView: { dataSource, collectionView, kind, indexPath in
let sectionItem = dataSource[indexPath.section]
let header = collectionView.dequeueReusableSupplementaryView(
ofKind: kind,
for: indexPath) as HeaderView
header.reactor = HeaderViewReactor(section: sectionItem.model)
header.rx.rightButtonDidTap
.map { Reactor.Action.rightButtonDidTap(sectionItem.model) }
.bind(to: self.reactor!.action)
.disposed(by: self.disposeBag)
return header
}
drive
๋ก ๊ตฌ๋
ํ๊ณ ์๋ ๊ฒ๋ ์๋๊ณ bind
๋ก ๊ตฌ๋
ํ๊ณ ์์ด์ ์คํธ๋ฆผ์ด ๊ณต์ ๋๋ ๊ฒ๋ ์๋๋ฐ ์ ๋ชจ๋ ํค๋์์ Action
์ด ํธ๋ฆฌ๊ฑฐ ๋๋๊ฑฐ์ง..?
โ ์ค๋ง๋ฆฌ ๋ฐ๊ฒฌ
๊ทธ๋ฌ๋ ์ค ํฌํ๋ฅผ ์์ฒญํ ํ์์๊ฒ ๋ฐ์ ๋๊ธโฆ!
์ ์ด์ ๊ตฌ๋ ์ด ์ฌ๋ฌ๋ฒ ๋๊ณ ์๋ค๋ ์ ๋ณดโฆ!
๋ฐ๋ก ํ ์คํธ ๋์ ..
self.collectionView.rx.didEndDisplayingSupplementaryView
.asDriver(onErrorRecover: { _ in return .empty()})
.drive(with: self, onNext: { _, endDisplayingView in
print(endDisplayingView)
.disposed(by: self.disposeBag)
์ ์ฒ๋ผ HeaderView
๊ฐ ํ๋ฉด์์ ์ฌ๋ผ์ง ๋๋ง๋ค ๋ก๊น
์ ํ๊ณ ์คํ์ ํด๋ณด์๋ค.
์ฐ์ HomeVC
๊ฐ ๋ก๋ ๋๋ฉฐ ๋ ๋ฒ์ฉ ์ถ๋ ฅ์ด ๋๊ณ ..
๊ธฐ๋ณธ 2ํ +
endDisplaying
1ํ โ 3ํ
๊ธฐ๋ณธ 2ํ +
endDisplaying
3ํ โ 5ํ
HeaderView
๋ฅผ didEndDisplaying
์ํฌ ๋๋ง๋ค ํด๋น ํ์์ ํ์๊ฐ ์ฆ๊ฐํ๋ ๊ฒ์ ํ์ธํ๋ค..
์ด๋ป๊ฒ ์ฐพ์๋โฆ
๊ทธ๋์ ์์ธ์ ์์๋๋ฐ ์ด๋ป๊ฒ ํด๊ฒฐํ์ง..?
ํด๊ฒฐ
ํน์๋ ์ถ์ด์ HeaderView
์์ฒด๋ ๋ช๊ฐ์ธ์ง ํ์ธํด๋ณด์์ต๋๋ค.
์ฌ๋ฌ๋ฒ endDisplaying
์์ผ์ค ๋ค ํ์ธํด๋ณด์์ง๋ง ์ ์์ ์ผ๋ก ๋ ๊ฐ๋ง ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ผ๊ฐ์๋ ์ํฉ์ด๋ค์โฆ
View
์์ฒด๋ ๋ฌธ์ ๊ฐ ์์ง๋ง subscribe
๋ง ์ฌ๋ฌ๋ฒ ๋๊ณ ์๊ณ , ๊ทธ๊ฒ๋ค์ด ์ ์ง๋๊ณ ์๋ค๋ ์ํฉ์
๋๋ค..
ํด๊ฒฐ ์๋ #1
๊ฒฐ๊ตญ ๋ฌธ์ ๋ HeaderView
๋ ์ฌ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ didEndDisplaying
๋ ํ ๋ค์ willDisplay
๋ ๋๋ง๋ค configureSupplementaryView
๊ฐ ์คํ๋์ด์ ์๋ก์ด ๊ตฌ๋
์ด ๋์ด๋๊ณ ์๋ ๊ฒ์ด์์ต๋๋ค.
๊ทธ๋ฌ๋ฉด didEndDisplaying
์ด๋ willDisplay
๊ฐ ๋ ๋๋ง๋ค ๊ตฌ๋
์ ํด์ ํด์ฃผ๋ฉด ๋๋ ๊ฒ์ด ์๋๊ฐ..?
self.collectionView.rx.didEndDisplayingSupplementaryView
.asDriver(onErrorRecover: { _ in return .empty()})
.drive(with: self, onNext: { _, endDisplayingView in
let (view, _, _) = endDisplayingView
guard let view = view as? HeaderView else { return }
print(view)
view.disposeBag = DisposeBag()
})
.disposed(by: self.disposeBag)
๊ทธ๋์ ์์ ๊ฐ์ด ๊ณ ์ณ๋ณด์๋ค.
ํ์ง๋ง ์ด๋ฆผ๋ ์์ง..
์๋ก์ด DisposeBag
์ผ๋ก ๊ฐ์ ๋ผ์์ฃผ๋ ๊ฒ ๋ง์ผ๋ก๋ ๊ตฌ๋
์ด ํด์ ๋์ง ์๊ณ ์๊ตฐ์..
ํด๊ฒฐ ์๋ #2
ํด๊ฒฐ ์๋ #2 ์ด๊ธด ํ์ง๋ง ๋์ค์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฐพ์๋ฒ๋ ธ์ต๋๋ค.
header.rx.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didEndDisplayingSupplementaryView:forElementOfKind:at:)))
.subscribe(onNext: {
})
.disposed(by: <#T##DisposeBag#>)
์ฌ๊ธฐ๊น์ง ์์ฑ์ ํ๋๋ฐ์.. diseposed(by:)
๋ฅผ ์์ฑํ๋ ๋์ค์ ๊ฐ์๊ธฐ ์๋ฌธ์ด ๋ค์์ต๋๋ค.
์์ด ๊ฐ๋๋๋ก disposed(by: self.disposeBag)
๋ฅผ ์น๋ ์ฐฐ๋โฆ
๋จธ๋ฆฟ์ ์ ์ฌ์์์ด ์ ๋ฅผ ํ ๋ ์ณค์ต๋๋ค..
header.rx.rightButtonDidTap
.map { Reactor.Action.rightButtonDidTap(sectionItem.model) }
.subscribe(onNext: {
self.reactor!.action.onNext($0)
})
.disposed(by: self.disposeBag)
๋ค์ subscribe
๋ฅผ ํ๋ ์ฝ๋๋ก ๋์๊ฐ๋ด
์๋ค.
์ฌ๊ธฐ์ self
๋ HeaderView
๊ฐ ์๋๋ผ HomeViewController
์
๋๋ค.
HeaderView
์ ๊ตฌ๋
์ HeaderView
์ dequeueReusable
์ ๋ฐ๋ผ ๋์ํด์ผํ๋๋ฐ ๋ง์ด์ฃ โฆ
๊ทธ๋์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์์ฃผ ๊ฐ๋จํฉ๋๋ค.
header.rx.rightButtonDidTap
.map { Reactor.Action.rightButtonDidTap(sectionItem.model) }
.subscribe(onNext: {
self.reactor!.action.onNext($0)
})
.disposed(by: header.disposeBag) // ๐ ์ด ๋ถ๋ถ
self.dispseBag
์ header.disposeBag
์ผ๋ก ๋ฐ๊ฟ์ฃผ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค..
์ค๋๋ ๋ ํ ๋ฒ ์๊ฐ์์ด ํ๋ ์ฝ๋ฉ์ ์ํํ๋ค๋ ๊ฒ์ ๋๋ผ๊ณ ์ง๋๊ฐ๋๋ค..
๐ ํด๊ฒฐ!
์ํธ..!
ํด.. ๋ฐ์ฑํด๋ผ ๋ ์์ ..