UIKIT

이미지를 선택한 후에 배열에 저장하고 이를 컬렉션뷰로 불러올 때

밤새는 탐험가89 2024. 11. 23. 19:25

순서

 

  1. 사용자가 이미지를 선택.
  2. 선택된 이미지를 selectedImages 배열에 append 또는 덮어쓰기 등으로 저장.
  3. 데이터가 변경되었으니 collectionView.reloadData()를 호출하여 UI를 업데이트.

 

왜 이 순서가 필요한가?

  • 데이터 동기화: UICollectionView는 dataSource로부터 데이터를 가져와 셀을 구성합니다. 따라서 데이터를 먼저 업데이트하지 않고 reloadData()를 호출하면, 변경 사항이 반영되지 않은 상태로 UI가 다시 그려지게 됩니다.
  • 명확한 흐름: 배열을 먼저 업데이트하고, 그에 따라 UI를 새로고침하면 코드의 가독성이 높아지고, 예기치 않은 버그를 예방할 수 있습니다.
// MARK: - extension PHPickerViewControllerDelegate
extension FeedViewController: PHPickerViewControllerDelegate {
    
    /// 갤러리 창을 띄워 이미지를 선택할 수 있도록 해주는 함수
    private func presentImagePicker() {
        var configuration = PHPickerConfiguration()
        configuration.selectionLimit = 10   // 선택 가능한 이미지 또는 영상 개수
        configuration.filter = .any(of: [.images])   // 이미지 선택 가능
        
        let picker = PHPickerViewController(configuration: configuration)
        picker.delegate = self
        present(picker, animated: true)
    }
    
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true)
        
        // 선택한 이미지를 저장할 임시 배열
        var newImages: [UIImage] = []
        
        // 최대 5개의 이미지를 가져오는 imageItems
        let imageItems = results.prefix(10)
        
        for item in imageItems {
            item.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] (image, error) in
                
                guard let self = self else { return }
                
                if let image = image as? UIImage {
                    
                    // UI 업데이트는 메인 스레드에서 실행
                    DispatchQueue.main.async {
                        print("Selected image: \(image)")
                        newImages.append(image)
                        
                        // 모든 이미지를 로드한 후 업데이트
                        if newImages.count == imageItems.count {
                            self.selectedImages = newImages // 기존 배열 업데이트
                            self.feedView.selectedImageCollectionView.reloadData()   // 컬렉션뷰 새로고침
                        }
                    }
                }
            }
        }
    }
}

 

 

 

중요 포인트

  1. 비동기 작업 처리:
    • PHPickerResult에서 이미지를 로드하는 작업은 비동기적으로 실행됩니다.
    • 모든 이미지 로드가 끝난 후, 배열 업데이트와 reloadData() 호출을 보장해야 합니다.
  2. 배열 관리:
    • 새로 선택된 이미지로 덮어쓰기(replace)하거나, 기존 배열에 추가(append)하는 방식을 명확히 정의하세요.
  3. 메인 스레드에서 UI 작업:
    • reloadData()는 UI 작업이므로 반드시 메인 스레드에서 호출해야 합니다.