UIKIT
이미지를 선택한 후에 배열에 저장하고 이를 컬렉션뷰로 불러올 때
밤새는 탐험가89
2024. 11. 23. 19:25
순서
- 사용자가 이미지를 선택.
- 선택된 이미지를 selectedImages 배열에 append 또는 덮어쓰기 등으로 저장.
- 데이터가 변경되었으니 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() // 컬렉션뷰 새로고침
}
}
}
}
}
}
}
중요 포인트
- 비동기 작업 처리:
- PHPickerResult에서 이미지를 로드하는 작업은 비동기적으로 실행됩니다.
- 모든 이미지 로드가 끝난 후, 배열 업데이트와 reloadData() 호출을 보장해야 합니다.
- 배열 관리:
- 새로 선택된 이미지로 덮어쓰기(replace)하거나, 기존 배열에 추가(append)하는 방식을 명확히 정의하세요.
- 메인 스레드에서 UI 작업:
- reloadData()는 UI 작업이므로 반드시 메인 스레드에서 호출해야 합니다.