Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] tableView refresh (상단, 하단 새로고침) 본문

iOS 응용 (swift)

[iOS - swift] tableView refresh (상단, 하단 새로고침)

jake-kim 2021. 3. 13. 19:26

cf)  오른쪽 스크롤 바 표출, flashScrollIndicators(): ios-development.tistory.com/341

flashScrollIndicators()

상단 refresh (with RxCocoa) - UIRefreshControl 사용 (상단에 시스템에서 뿌려주는 로딩 UI 생성)

  • 사용: 사용자 입장에서 tableView를 볼 때, 상단 refresh를 사용하는 경우는 tableView의 내용이 변한 경우에 사용
    cf) 하단 refresh 사용: tableView를 밑으로 내려서 api로 부터 내용을 더 load하고 싶은 경우 사용
  • 사용 방법: `UIRefreshControl` 객체를 선언한 후 이 객체를 tableView의 refreshControl로 등록 후 객체의 isRefreshing 값에 업데이트
  • UIRefreshControl() 선언
let refreshControl = UIRefreshControl()
  • tableView에 refreshControl객체 등록
refreshControl.endRefreshing() // 초기화 - refresh 종료
tableView.refreshControl = refreshControl
  • refreshControl 값이 변경된 경우 (상단 스크롤 한 경우) 이벤트가 들어갈 변수 선언 및 바인딩
let refreshLoading = PublishRelay<Bool>() // ViewModel에 있다고 가정
refreshControl.rx.controlEvent(.valueChanged)
    .bind(onNext: { [weak self] _ in
        // viewModel.updateDataSource()
        
        // 아래코드: viewModel에서 발생한다고 가정
        DispatchQueue.main.asyncAfter(wallDeadline: .now() + 3) { [weak self] in
            self?.refreshLoading.accept(true) // viewModel에서 dataSource업데이트 끝난 경우
        }
    }).disposed(by: bag)
  • refreshLoading이 이벤트를 받은 경우 - refershControl의 isRefreshing에 반영
refreshLoading
    .bind(to: refreshControl.rx.isRefreshing)
    .disposed(by: bag)

하단 Refresh -  scrollViewWillBeginDecelerating 델리게이트 이용

하단- 로딩 UI는 JGProgressHUD 이용

 

scrollViewWillBeginDecelerating

  • 의미: 스크롤뷰를 상속받은 tableView는 급격히 스크롤을 할때 잠깐 멈춘다음에 다시 스크롤 되는데, 이 때 scrollViewWillBeginDecelerating 델리게이트 함수가 실행

UITableView는 UIScrollView를 상속받아서 구현된 형태
decerlerating 이벤트 예시

contentOffset 개념

  • contentOffset: UITableView는 UIScrollView를 상속받은것
    - content, frame영역 중 frame 영역의 origin과 비교했을때의 content view의 현재 위치

  • tableView.contentOffset.y = 100 한 경우, content view의 origin이 100만큼 아래로 이동

버튼을 탭한 경우  contentOffset.y = 100 설정한 예시

  • scroll이 dercelerrating될 때 scrollViewWillBeginDecelerating 델리게이트와 contentOffset의 위치를 계산하여 refresh
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
    let currentOffset = scrollView.contentOffset.y // frame영역의 origin에 비교했을때의 content view의 현재 origin 위치
    let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height // 화면에는 frame만큼 가득 찰 수 있기때문에 frame의 height를 빼준 것

    // 스크롤 할 수 있는 영역보다 더 스크롤된 경우 (하단에서 스크롤이 더 된 경우)
    if maximumOffset < currentOffset {
        // viewModel.loadNextPage()
        showLoading() // 데이터 로딩 중 표시
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
            self?.hideLoading()
        }
    }
}

* source code: github.com/JK0369/table_view_refresh

 

* 참고

- developer.apple.com/documentation/uikit/uiscrollview/1619404-contentoffset

Comments