
https://developer.apple.com/documentation/photokit/phpickerviewcontroller
사진첩으로부터 사진들을 선택할 수 있도록 유저 인터페이스를 제공하는 뷰 컨트롤러
아래 화면과 같이 이미지 클릭시 사진첩을 열어 사진을 선택할 수 있도록 한다

구현된 프로젝트 링크 ->
https://github.com/sang9984/PHPickerViewController-test
PHPickerViewController를 사용하기 위해서는 PhotosUI를 import 해야 한다
import PhotosUI
UITapGestureRecognizer는 제스쳐를 인식할 수 있도록 도와주는 도구다
해당 객체를 가져와 대상을 지정하고 화면 내에 존재하는 객체(image 등)에 대한 제스쳐 인식을 활성화 해야 한다
func setupTapGesture() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(touchUpImageView))
image.isUserInteractionEnabled = true
image.addGestureRecognizer(tapGesture)
}
또한 #selector()를 통해 제스쳐를 인식할 경우 수행할 기능에 대해 함수로 정의해야 한다
제스쳐가 인식되면 아래 @objc 함수를 실행시켜 함수 내 기능을 수행한다
setupImagePicker()에 대해서는 3번에서 설명
@objc func touchUpImageView() {
setupImagePicker()
}
여기서 필요한 객체가 2가지가 있다
func setupImagePicker() {
// PHPickerConfiguration() -> PHPickerViewController의 동작 등을 구성하는데 사용되는 객체
// 해당 객체를 통해 선택되는 사진의 개수나 파일 종류를 지정할 수 있다
var configuration = PHPickerConfiguration()
// 사진 선택 개수 제한: 0이면 제한없음, 0이외의 수 -> 해당 개수만큼 제한
configuration.selectionLimit = 0
// 선택할 수 있는 파일의 종류
configuration.filter = .any(of: [.images, .videos])
// 기본설정을 바탕으로, 피커뷰컨트롤러 생성
let picker = PHPickerViewController(configuration: configuration)
// 피커뷰 컨트롤러의 대리자 설정
picker.delegate = self
// 피커뷰 띄우기
self.present(picker, animated: true, completion: nil)
}
피커뷰에 대한 기본적인 설정이 완료된 경우 delegate를 통해 실질적인 기능을 수행할 수 있도록 해야 한다
extension ViewController: PHPickerViewControllerDelegate {
// 사진이 선택이 된 후에 호출되는 메서드
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
// 피커뷰 dismiss
picker.dismiss(animated: true)
let itemProvider = results.first?.itemProvider
if let itemProvider = itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) {
itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in
DispatchQueue.main.async {
// 이미지뷰에 표시
self.image.image = image as? UIImage
}
}
} else {
print("이미지 불러오기 실패")
}
}
}
import UIKit
import PhotosUI
class ViewController: UIViewController {
// 이미지 생성
let image: UIImageView = {
let image = UIImageView()
image.image = UIImage(named: "swift-og")
image.layer.cornerRadius = 100
image.clipsToBounds = true
return image
}()
override func viewDidLoad() {
super.viewDidLoad()
setupTapGesture()
setupAutolayout()
}
func setupAutolayout() {
image.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(image)
NSLayoutConstraint.activate([
image.centerXAnchor.constraint(equalTo: view.centerXAnchor),
image.centerYAnchor.constraint(equalTo: view.centerYAnchor),
image.heightAnchor.constraint(equalToConstant: 200),
image.widthAnchor.constraint(equalToConstant: 200)
])
}
//MARK: - pickerViewController 기본 설정
func setupTapGesture() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(touchUpImageView))
image.isUserInteractionEnabled = true
image.addGestureRecognizer(tapGesture)
}
// 제스쳐에서 addTarget을 통해 지정한 함수
// 제스쳐 발생시 어떤 기능을 수행해야 하는지 정의하는 함수
@objc func touchUpImageView() {
setupImagePicker()
}
func setupImagePicker() {
// PHPickerConfiguration() -> PHPickerViewController의 동작 등을 구성하는데 사용되는 객체
// 해당 객체를 통해 선택되는 사진의 개수나 파일 종류를 지정할 수 있다
var configuration = PHPickerConfiguration()
// 사진 선택 개수 제한: 0이면 제한없음, 0이외의 수 -> 해당 개수만큼 제한
configuration.selectionLimit = 0
// 선택할 수 있는 파일의 종류
configuration.filter = .any(of: [.images, .videos])
// 기본설정을 바탕으로, 피커뷰컨트롤러 생성
let picker = PHPickerViewController(configuration: configuration)
// 피커뷰 컨트롤러의 대리자 설정
picker.delegate = self
// 피커뷰 띄우기
self.present(picker, animated: true, completion: nil)
}
}
//MARK: - 피커뷰 델리게이트 설정
extension ViewController: PHPickerViewControllerDelegate {
// 사진이 선택이 된 후에 호출되는 메서드
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
// 피커뷰 dismiss
picker.dismiss(animated: true)
let itemProvider = results.first?.itemProvider
if let itemProvider = itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) {
itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in
DispatchQueue.main.async {
// 이미지뷰에 표시
self.image.image = image as? UIImage
}
}
} else {
print("이미지 불러오기 실패")
}
}
}