iOS/UIKIT

갤러리에서 선택한 내용을 컬렉션 뷰에 보이는 방법

밤새는 탐험가89 2024. 11. 8. 14:15

구현 목표

 

selectedImages를 PhotoAddCell의 CollectionView에 전달하려면, 다음 단계를 통해 이미지를 효율적으로 관리할 수 있습니다.

 

 

  • FeedViewController에 selectedImages 배열 저장
    FeedViewController에서 selectedImages 배열을 속성으로 만들어서, 다른 곳에서도 사용할 수 있도록 설정합니다.
  • PhotoAddCellDelegate 프로토콜 설정
    PhotoAddCell에 이미지를 전달하려면, FeedViewController가 PhotoAddCell의 델리게이트로 동작하도록 설정합니다. 이를 통해 이미지 선택 시 FeedViewController에 전달된 이미지를 PhotoAddCell에 업데이트할 수 있습니다.
  • 이미지 배열 전달 및 PhotoAddCell 업데이트
    FeedViewController가 selectedImages를 PhotoAddCell에 직접 전달하여, PhotoAddCell 내부 CollectionView에서 이미지를 보여줄 수 있도록 합니다.

 

var selectedImages: [UIImage] = []     // 선택된 이미지를 담는 배열

 

extension FeedViewController: PhotoAddCellDelegate {
    
    func didTapAddPhotoButton(in cell: PhotoAddCell) {
        var configuration = PHPickerConfiguration()
        configuration.filter = .images
        configuration.selectionLimit = 10 // 최대 선택 개수 설정
        
        let picker = PHPickerViewController(configuration: configuration)
        picker.delegate = self
        present(picker, animated: true, completion: nil)
    }
    
    func photoAddCell(_ cell: PhotoAddCell, didSelectImages images: [UIImage]) {
        // 선택된 이미지를 PhotoAddCell에 전달하여 UI 업데이트
        cell.updateImage(images)
        
    }
}

extension FeedViewController: PHPickerViewControllerDelegate {
    
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true, completion: nil)
        
        let imageItems = results.prefix(10)
        selectedImages = []
        
        let group = DispatchGroup()
        
        for item in imageItems {
            group.enter()
            item.itemProvider.loadObject(ofClass: UIImage.self) { (object, error) in
                if let image = object as? UIImage {
                    self.selectedImages.append(image)
                }
                group.leave()
            }
        }
        
        group.notify(queue: .main) {
            if let cell = self.feedTableView.cellForRow(at: IndexPath(row: 0, section: 0)) as? PhotoAddCell {
                self.photoAddCell(cell, didSelectImages: self.selectedImages)
            }
        }
    }
}

 

 

import UIKit

class PhotoAddCell: UITableViewCell {
    
    ...
    
    var images: [UIImage] = [] {
        didSet {
            showImageCollectionView.reloadData()
        }
    }
    
    ...
    
    let showImageCollectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.minimumLineSpacing = 10
        layout.itemSize = CGSize(width: 140, height: 180)
        
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        
        collectionView.layer.cornerRadius = 10
        collectionView.clipsToBounds = true
        collectionView.showsHorizontalScrollIndicator = false
        return collectionView
    }()
    
    
    
    ...
    
    func configureCollectionView() {
        showImageCollectionView.dataSource = self
        showImageCollectionView.delegate = self
        showImageCollectionView.register(SelectedPhotoCollectionViewCell.self, forCellWithReuseIdentifier: SelectedPhotoCollectionViewCell.identifier)
    }
    
    
    func updateImage(_ images: [UIImage]) {
        self.images = images
    }
    
    
    ...
}


// MARK: - Protocol
/// 버튼 액션을 전달하기 위해 Delegate 프로토콜 생성
protocol PhotoAddCellDelegate: AnyObject {
    func didTapAddPhotoButton(in cell: PhotoAddCell)
    func photoAddCell(_ cell: PhotoAddCell, didSelectImages images: [UIImage])
}


extension PhotoAddCell: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return images.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SelectedPhotoCollectionViewCell.identifier, for: indexPath) as? SelectedPhotoCollectionViewCell else { return UICollectionViewCell() }
        
        let image = images[indexPath.item]
        cell.selectedImage.image = image
        
        return cell
    }
}

 

 

import UIKit

class SelectedPhotoCollectionViewCell: UICollectionViewCell {
    
    // MARK: - Variables
    static let identifier = "SelectedPhotoCollectionViewCell"
    
    // MARK: - UI Components
    let basicView: UIView = {
        let view = UIView()
        view.layer.cornerRadius = 10
        view.clipsToBounds = true
        return view
    }()
    
    var selectedImage: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "korea")
        imageView.contentMode = .scaleAspectFill
        return imageView
    }()
    
    let removeImageButton: UIButton = {
        let button = UIButton()
        let configure = UIImage.SymbolConfiguration(pointSize: 20)
        let image = UIImage(systemName: "x.circle", withConfiguration: configure)
        button.setImage(image, for: .normal)
        button.tintColor = .black
        return button
    }()
    
    // MARK: - Initializations
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        contentView.backgroundColor = .systemBackground
        configureConstraints()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - Layouts
    private func configureConstraints() {
        contentView.addSubview(basicView)
        basicView.addSubview(selectedImage)
        basicView.addSubview(removeImageButton)
        
        basicView.translatesAutoresizingMaskIntoConstraints = false
        selectedImage.translatesAutoresizingMaskIntoConstraints = false
        removeImageButton.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            
            basicView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            basicView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            basicView.topAnchor.constraint(equalTo: contentView.topAnchor),
            basicView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            
            selectedImage.leadingAnchor.constraint(equalTo: basicView.leadingAnchor),
            selectedImage.trailingAnchor.constraint(equalTo: basicView.trailingAnchor),
            selectedImage.topAnchor.constraint(equalTo: basicView.topAnchor),
            selectedImage.bottomAnchor.constraint(equalTo: basicView.bottomAnchor),
            
            removeImageButton.trailingAnchor.constraint(equalTo: selectedImage.trailingAnchor),
            removeImageButton.topAnchor.constraint(equalTo: selectedImage.topAnchor)
        ])
    }
}

 

 

 

  • selectedImages 관리:
    • FeedViewController에서 선택한 이미지를 selectedImages에 저장하고, PhotoAddCell에 직접 전달합니다.
  • updateImages(_:) 메서드:
    • updateImages(_:)를 통해 PhotoAddCell의 images 배열을 업데이트하고, collectionView.reloadData()를 통해 이미지를 즉시 업데이트합니다.
  • CollectionView 설정:
    • PhotoAddCell의 collectionView에서 UICollectionViewDataSource를 통해 이미지를 표시합니다.