Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Greedy
- 그래프
- ReLU
- sigmoid
- 백트래킹
- dp
- dfs
- 그리디
- 캡스톤정리
- Blockchain
- Node.js
- NeuralNetwork
- ios
- 실버쥐
- Docker
- 프로그래머스
- 탐색
- 풀이
- Algorithm
- 부르트포스
- C++
- mysql
- BFS
- 백준
- 알고리즘
- Stack
- 문제풀이
- Swift
- 플로이드와샬
- DeepLearning
Archives
- Today
- Total
개발아 담하자
[iOS/Swift] tableView를 사용해 Infinite scroll 만들기 본문
Infinite scroll 을 tableview 를 사용해 만들어보자~!
API Caller
class APICaller {
var isPaginating = false
func fetchData(pagination:Bool = false, completion: @escaping (Result<[String], Error>) -> Void){
if pagination {
isPaginating = true
}
DispatchQueue.global().asyncAfter(deadline: .now() + (pagination ? 3 : 2) , execute: {
let originalData = [
"Apple",
"Google", ...
]
let newData = ["dam", "mbti","cute"]
completion(.success(pagination ? newData : originalData))
if pagination {
self.isPaginating = false
}
})
}
}
지금 예시는 실제 API 와 연결하지 않아 샘플 데이터를 넣었다.
isPaginating 은 현재 지금 데이터가 로드 중인지 여부를 의미한다.
fetchdata 에서 매개변수로 받는 pagination 이 true 면 newData 를, false 인 경우는 originalData 를 전달하도록 했다.
ViewDidLayoutSubviews
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.frame = view.bounds
apiCaller.fetchData(pagination: false, completion: { [weak self] result in
switch result {
case .success(let data):
self?.data.append(contentsOf: data)
DispatchQueue.main.async {
self?.tableView.reloadData()
}
case .failure(_):
break
}
})
}
ViewDidLayoutSubviews() 는 ViewWillAppear() 와 ViewDidAppear() 사이에 호출된다. (상황에 따라 반복적으로 호출 된다.) 자세한 설명은 여기
레이아웃이 결정되는 과정
- ViewWillLayoutSubViews() 메소드를 호출한다.
- 뷰컨의 contentView 가 layoutSubviews() 를 호출한다.
- 이 메서드는 현재 레이아웃 정보들을 바탕으로 새로운 레이아웃 정보를 계산한다. 이후 뷰 계층구조를 순회하면서 모든 하위 뷰들이 동일한 메서드를 호출하게 한다.
- 레이아웃 정보의 변경 사항들을 뷰들에 반영한다.
- ViewDidLayoutSubviews() 메소드를 호출한다.
Spinner
private func createSpinnerFooter() -> UIView {
let footerView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 100))
let spinner = UIActivityIndicatorView()
spinner.center = footerView.center
footerView.addSubview(spinner)
spinner.startAnimating()
return footerView
}
로딩창을 미리 만들어둔다.
scrollViewDidScroll
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let position = scrollView.contentOffset.y
if position > (tableView.contentSize.height - 100 - scrollView.frame.size.height) {
guard !apiCaller.isPaginating else {
// we are already fetching more data
return
}
self.tableView.tableFooterView = createSpinnerFooter()
// fetch more data
apiCaller.fetchData(pagination: true){ [weak self] result in
DispatchQueue.main.async {
self?.tableView.tableFooterView = nil
}
switch result {
case .success(let moreData):
self?.data.append(contentsOf: moreData)
DispatchQueue.main.async {
self?.tableView.reloadData()
}
case .failure(_):
break
}
}
}
}
tableView.contentSize.height - scrollView.frame.size.height - 100 인 경우 (아래로 스크롤을 했을 경우) 데이터를 불러온다.
데이터를 불러오는 동안은 tableView footer 에 spinner 를 붙이고 로드가 끝나면 footer에 nil처리를 한다.
완성 screenshot 📱
'📱 iOS' 카테고리의 다른 글
[iOS/Swift] Apple Login 구현하기 (1) | 2020.09.11 |
---|---|
[iOS/Swift] 카카오톡 소셜 로그인 구현하기 (0) | 2020.09.04 |
[iOS/RxSwift] RxSwift 시작하기 (Observable, Subject, Operator) (0) | 2020.08.08 |
[iOS/Swift] Apple Map 사용하기 (CLLocation으로 내 위치 이동하기, 원하는 지역으로 이동하기) (1) | 2020.06.26 |
[iOS/Swift] NavigationBar with Gradient Color , 네비게이션 바 커스텀하기 (0) | 2020.06.08 |