콜렉션뷰 Refresh (pull-down refresher)

이세진·2022년 6월 24일
0

iOS

목록 보기
28/46

생성일: 2022년 2월 3일 오후 11:20

사용자가 feed화면에서 스크롤을 하면 새롭게 post들을 firebase에서 받아와서 화면에 보여주도록 한다.

FeedController.swift

//MARK: - Helpers
    
    func configureUI() {
        collectionView.backgroundColor = .white
        // 콜렉션 뷰에 cell 등록
        collectionView.register(FeedCell.self, forCellWithReuseIdentifier: reuseIdentifier)
        
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(handleLogout))
        
        navigationItem.title = "Feed"
        
        // 화면 스크롤을 하면 새롭게 posts들 fetch하기 위한 refresher 생성
        let refresher = UIRefreshControl()
        refresher.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
        collectionView.refreshControl = refresher
    }

UIKit에서 제공하는 UIRefreshControl 클래스를 이용하여 refresher 객체를 생성한다.

refresher에 addTarget으로 selector를 설정해주고 콜렉션뷰의 refreshController를 생성한 refresher로 지정한다.

//MARK: - Actions
    
	  @objc func handleRefresh() {
	      print("DEBUG: handle Refresh...")
	      fetchPosts()
	  }

//MARK: - API
    
    func fetchPosts() {
        PostService.fetchPosts { posts in
            self.posts = posts
            print("DEBUG: Did fetch Posts")
            self.collectionView.refreshControl?.endRefreshing()
            self.collectionView.reloadData()
        }
    }

handleRefresh 함수는 새롭게 post들을 가져오기 위해 fetchPosts 함수를 호출하도록 한다.

실행 화면

화면을 스크롤하면 로딩 인디케이터가 보이면서 refresh된다.

새 post를 올렸을 때에도 feed화면이 refresh되도록 적용

  • 사용자가 새로운 사진을 업로드 했을 때 자동으로 refresh되어서 화면에 방금 올린 사진 post가 보이도록 한다.

UploadPostController.swift

protocol UploadPostsControllerDelegate: AnyObject {
    func controllerDidFinishUploadingPost(_ controller: UploadPostsController)
}

class UploadPostsController: UIViewController {
    
    //MARK: - Properties
    
    weak var delegate: UploadPostsControllerDelegate?

		@objc func didTapDone() {
        guard let image = selectedImage else { return }
        guard let caption = captionTextView.text else { return }
        guard let user = currentUser else { return }
        
        showLoader(true)    // 로딩 화면 보여주기
        
        PostService.uploadPost(caption: caption, image: image, user: user) { error in
            
            self.showLoader(false)  // 로딩 화면 사라지게 하기
            if let error = error {
                print("DEBUG: Failed to upload post with error \(error.localizedDescription)")
                return
            }
            
            self.delegate?.controllerDidFinishUploadingPost(self)
            
        }
    }

}

MainTabController.swift

//MARK: - UploadPostsControllerDelegate
extension MainTabController: UploadPostsControllerDelegate {
    
    // Post를 업로드 한 후에 Feed화면으로 돌아가도록 하는 함수 => delegate 패턴 사용
    func controllerDidFinishUploadingPost(_ controller: UploadPostsController) {
        selectedIndex = 0
        controller.dismiss(animated: true, completion: nil)
        
        // feedController에 접근하여 post들을 refresh(다시 fetch)하기
        guard let feedNav = viewControllers?.first as? UINavigationController else { return }
        guard let feed = feedNav.viewControllers.first as? FeedController else { return }
        feed.handleRefresh()
    }
    
}

해당 기능을 구현하기 위해 post 업로드를 담당하는 UploadPostController와 MainTabController와의 연결이 필요하다 ⇒ 프로토콜, delegate 사용

사용자가 새로운 post를 업로드하면 MainTabController에서 controllerDidFinishUploadingPost 함수를 실행하도록 한다.

해당 함수는 포스트를 업로드하는 화면을 dismiss하고 feed화면을 띄워준 다음에 feedController에 접근하여 앞서 만든 handleRefresh함수를 호출하는 구조이다.

profile
나중은 결코 오지 않는다.

0개의 댓글