https://developer.apple.com/documentation/photokit/phpickerconfiguration
PHPickerConfiguration | Apple Developer Documentation
An object that contains information about how to configure a picker view controller.
developer.apple.com
https://zeddios.tistory.com/1052
iOS 14+ ) PHPicker
안녕하세요 :) Zedd입니다, WWDC를 보다가 정말정말..새로운것을 보게되어서 이렇게 공부하게 되었어요 :D 너무 재밌당 developer.apple.com/videos/play/wwdc2020/10652/ Meet the new Photos picker - WWDC 2020 - Videos - Appl
zeddios.tistory.com
https://developer.apple.com/documentation/photokit/phpickerviewcontroller
PHPickerViewController | Apple Developer Documentation
A view controller that provides the user interface for choosing assets from the photo library.
developer.apple.com
// MARK: - Actions
/// 이미지 선택 버튼을 누르면 동작하는 함수
@objc private func didTappedSelectedImages() {
print("didTappedSelectedImages - called()")
// PHPickerConfiguration 설정
var configuration = PHPickerConfiguration()
configuration.selectionLimit = 5 // 선택 가능한 이미지 또는 영상 개수
configuration.filter = .any(of: [.images]) // 이미지 선택 가능
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
present(picker, animated: true)
}
extension FeedViewController: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)
let imageItems = results.prefix(5)
for item in imageItems {
item.itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in
if let image = image as? UIImage {
DispatchQueue.main.async {
print("Selected image: \(image)")
}
}
}
}
}
}
델리게이트 패턴을 적용
- 역할 분리: FeedView는 버튼 클릭 이벤트를 발생시키는 역할만, 실제 처리는 FeedViewController가 담당.
- 확장성: FeedView를 다른 화면에서도 재사용 가능.
- 코드 구조 간결화: addTarget을 뷰 외부에서 중복적으로 호출할 필요 없음.
import UIKit
// 1. 델리게이트 패턴을 위한 프로토콜 설정
protocol FeedViewDelegate: AnyObject {
func didTapSelectedImageButton()
}
class FeedView: UIView {
// MARK: - Variables
// 2. FeedViewDelegate를 채택한 delegate 변수 선언
weak var delegate: FeedViewDelegate?
// MARK: - UI Components
let selectedButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("이미지 선택", for: .normal)
button.backgroundColor = .systemBlue
button.tintColor = .white
button.layer.cornerRadius = 5
button.addTarget(self, action: #selector(selectedButtonTapped), for: .touchUpInside)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupView() {
addSubview(selectedButton)
selectedButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
selectedButton.centerXAnchor.constraint(equalTo: centerXAnchor),
selectedButton.centerYAnchor.constraint(equalTo: centerYAnchor),
selectedButton.widthAnchor.constraint(equalToConstant: 120),
selectedButton.heightAnchor.constraint(equalToConstant: 50)
])
}
@objc private func selectedButtonTapped() {
delegate?.didTapSelectedImageButton()
}
}
import UIKit
import PhotosUI
class FeedViewController: UIViewController {
// MARK: - Variables
var selectedImages: [UIImage?] = [UIImage(named: "new"), UIImage(named: "Stroll"), UIImage(named: "Tastes")]
let feedView: FeedView = {
let feedView = FeedView()
return feedView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemOrange
configureConstraints()
// 3. 대리자 선언 (대리자 = FeedViewController)
feedView.delegate = self
configureCollectionView()
}
private func configureConstraints() {
view.addSubview(feedView)
feedView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
feedView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 5),
feedView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -5),
feedView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 5),
feedView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -5)
])
}
func configureCollectionView() {
feedView.selectedImageCollectionView.delegate = self
feedView.selectedImageCollectionView.dataSource = self
feedView.selectedImageCollectionView.register(SelectedImageCollectionViewCell.self, forCellWithReuseIdentifier: SelectedImageCollectionViewCell.identifier)
}
}
// 4. 델리게이틒 패턴에 따른, 함수를 구체적으로 생성
extension FeedViewController: FeedViewDelegate {
func didTapSelectedImageButton() {
print("Delegate called: Button tapped.")
presentImagePicker()
}
}
// MARK: - PHPicker 관련 기능
extension FeedViewController: PHPickerViewControllerDelegate {
private func presentImagePicker() {
var configuration = PHPickerConfiguration()
configuration.selectionLimit = 5
configuration.filter = .images
configuration.preferredAssetRepresentationMode = .automatic
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
present(picker, animated: true)
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)
let imageItems = results.prefix(5)
for item in imageItems {
item.itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in
if let image = image as? UIImage {
DispatchQueue.main.async {
print("Selected image: \(image)")
}
}
}
}
}
}
언제 addTarget을 쓰고, 언제 델리게이트를 써야 할까?
상황 | 적합한 선택 |
View 내부에서만 이벤트를 처리할 때 | addTarget 사용 |
버튼 동작이 단순하고 Controller와 무관할 때 | addTarget 사용 |
View와 Controller 간 역할을 명확히 분리할 때 | 델리게이트 사용 |
View를 여러 Controller에서 재사용할 때 | 델리게이트 사용 |
이벤트 처리 로직이 복잡하거나 확장이 필요할 때 | 델리게이트 사용 |
🔥 preferredAssetRepresentationMode
preferredAssetRepresentationMode는 **PHPickerConfiguration**에서 제공되는 속성으로, 사용자가 선택한 이미지 또는 동영상 파일을 어떤 형태로 앱에 전달할지 결정합니다. 이 속성을 사용하면 이미지나 동영상의 원본 데이터, 편집된 데이터, 또는 자동으로 적절한 데이터를 가져오는 방식을 지정할 수 있습니다.
설정값 (PHPickerConfiguration.AssetRepresentationMode)
- .automatic (기본값)
- 시스템이 가장 적절한 형태로 데이터를 제공합니다.
- 예: 사용자가 사진 앱에서 이미지를 편집한 경우, 편집된 이미지를 반환. 편집되지 않았다면 원본 이미지를 반환.
- .current
- 사용자가 선택한 현재 상태의 데이터를 반환합니다.
- 예: 편집된 이미지를 반환하며, 편집되지 않았다면 원본 이미지를 반환.
- 주의: 데이터가 원본과 동일한 형식일 수도, 아닐 수도 있습니다.
- .compatible
- 항상 가장 호환성이 높은 포맷으로 데이터를 반환합니다.
- 예: 원본 이미지가 특정 형식(예: RAW)일 경우, JPEG와 같은 범용 포맷으로 변환하여 제공.
주요 사용 사례
- 편집 여부를 신경 쓰지 않을 때 (.automatic)
- 기본값이며, 사용자가 사진 앱에서 이미지를 편집했는지 여부를 자동으로 처리.
- 일반적인 앱에서 적합.
- 항상 편집된 결과를 필요로 할 때 (.current)
- 사용자가 사진 앱에서 편집한 이미지를 그대로 사용하고 싶을 때.
- 원본 포맷의 호환성이 걱정될 때 (.compatible)
- RAW 이미지 또는 비표준 포맷의 동영상이 포함될 수 있는 경우, JPEG나 MP4로 변환된 데이터를 사용.
'UIKIT' 카테고리의 다른 글
이미지 선택한 갯수 표시 및 최대치 도달시 알림창 띄우기 (0) | 2024.11.25 |
---|---|
이미지를 선택한 후에 배열에 저장하고 이를 컬렉션뷰로 불러올 때 (0) | 2024.11.23 |
TextView에서 줄 수 제한 (0) | 2024.11.22 |
동일한 조건 분기를 재사용하는 방법 (1) | 2024.11.22 |
UINavigationBarAppearance() 에 대해서 (0) | 2024.11.21 |