목록을 더 읽어와 하단에 추가하는 경우엔 스크롤 관련 이벤트에 따라 그냥 읽어서 붙이면 간단한데..
채팅이나 메신저와 같이 이전 목록을 불러와 기족 목록 상단에 추가하는 경우 스크롤 관련 설정이 조금 더 필요.
스크롤 위치에 따라 더 읽기 작업 시작
연속으로 호출되면 안되므로, 플래그를 두어서 한번만 호출되도록 처리
func scrollViewdidScroll(_ scrollView: UIScrollView) {
guard scrollView.contentSize.height > scrollView.bounds.height else { return }
if scrollView.contentOffset.y <= 0 {
if isRunningLoadMore {
return
}
isRunningLoadMore = true
viewModel.loadMore()
}
}
뷰모델에서 추가 데이터를 읽어와 dataSource 를 업데이트
뷰컨트롤러에 reload 이벤트 전달
enum ReloadType {
case .normal
case .loadMore
}
var reloadAction: PublishRelay<ReloadType> = .init()
.
.
.
func loadMore() {
// 데이터 로딩 루틴
.
.
insert(data: data)
}
func insert(data: [MyData]) {
guard !data.isEmpty else { return }
dataSource = data + dataSource
reloadAction.accept(.loadMore)
}
뷰컨트롤러에서 reload 처리
스크롤이 튀는 것을 막기위해 현재 offset 을 저장하고, 강제로 layoutSubviews를 호출해 사이즈가 변경되도록 한다.
viewModel.reloadAction
.subscribe(onNext: { [weak self] type in
guard let self = self else { return }
switch type {
case .normal:
UIView.performWithoutAnimation {
self.collectionView.reloadData()
}
case .loadMore:
let currentOffsetY = self.collectionView.contentSize.height - self.collectionView.contentOffset.y
UIView.performWithoutAnimation {
self.collectionView.reloadData()
}
self.collectionView.layoutIfNeeded()
let offsetY = self.collectionView.contentSize.height - currentOffsetY
self.collectionView.contentOffset.y = offsetY
self.isRunningLoadMore = false
}
})
.disposed(by: disposeBag)
'프로그래밍 > iOS,macOS' 카테고리의 다른 글
[SwiftUI] 오디오 레벨 에니메이션, Shape (0) | 2022.01.06 |
---|---|
dataTaskPublisher 재시도 및 출력 타입 변경 (0) | 2021.10.16 |
Framework SPM 배포 (0) | 2021.09.24 |
URLSession.DataTaskPublisher (0) | 2021.09.17 |
카메라 데이터 수신을 위한 AVCaptureSession (0) | 2021.08.02 |
UIPanGestureRecognizer 슬라이드 다운 뷰 (0) | 2021.07.01 |
UITextView 사이즈 조정 및 글자 제한, placeholder (0) | 2021.06.30 |
UITextView 자동 높이 (0) | 2021.06.03 |
오디오유닛 레벨 계산 (0) | 2021.05.01 |
Image, PixelBuffer (0) | 2021.04.13 |