TIL
🌱 난 오늘 무엇을 공부했을까?
📌 UIImagePickerController - 공식문서
- 사진을 찍고, 동영상을 녹화하고, 사용자의 미디어 라이브러리에서 항목을 선택하기 위한 시스템 인터페이스를 관리하는 View controller입니다.
📍 Declaration
@MainActor class UIImagePickerController : UINavigationController
📍 Overview
- image picker controller는 사용자 상호 작용을 관리하고 이러한 상호 작용의 결과를 delegate 개체에 전달합니다.
- image picker controller의 역할과 모양은 프레젠테이션하기 전에 할당한 소스 유형에 따라 다릅니다.
- UIImagePickerController.SourceType.camera의 sourceType은 (미디어 캡처를 지원하는 장치에서) 새로운 사진이나 영화를 찍기 위한 사용자 인터페이스를 제공합니다.
- UIImagePickerController.SourceType.photoLibrary 또는 UIImagePickerController.SourceType.savedPhotosAlbum의 sourceType은 저장된 사진과 동영상 중에서 선택하기 위한 사용자 인터페이스를 제공합니다.
- 기본 컨트롤이 포함된 image picker controller를 사용하려면 다음 단계를 수행하십시오.
1. 장치가 원하는 소스에서 콘텐츠를 선택할 수 있는지 확인합니다. isSourceTypeAvailable(:) 클래스 메서드를 호출하여 UIImagePickerController.SourceType 열거에서 상수를 제공하여 이를 수행합니다.
2. availableMediaTypes(for:) 클래스 메서드를 호출하여 사용 중인 소스 유형에 사용할 수 있는 미디어 유형을 확인합니다. 이를 통해 비디오 녹화에 사용할 수 있는 카메라와 정지 image에만 사용할 수 있는 카메라를 구별할 수 있습니다.
3. mediaTypes 속성을 설정하여 image picker controller에서 사용을 가능하게 하려는 미디어 유형(정지 image, 동영상 또는 둘 다)에 따라 UI를 조정하도록 지시합니다.
4. 사용자 인터페이스를 표시합니다. iPhone 또는 iPod touch에서 현재 활성 뷰 controller의 present(:animated:completion:) 메서드를 호출하여 모달(전체 화면)로 이 작업을 수행합니다, 구성된 image Picker controller를 새 View controller로 전달합니다.
5. 사용자가 새로 캡처하거나 저장된 image 또는 동영상을 선택하기 위해 버튼을 탭하거나 작업을 취소할 때 delegate 개체를 사용하여 image picker 닫습니다. 새로 캡처한 미디어의 경우 대리인은 해당 미디어를 장치의 카메라 롤에 저장할 수 있습니다. 이전에 저장된 미디어의 경우 대리인이 앱의 목적에 따라 image 데이터를 사용할 수 있습니다.
UIImagePickerController 클래스는 세로 모드만 지원합니다. 이 클래스는 있는 그대로 사용하기 위한 것이며 서브클래싱을 지원하지 않습니다. 이 클래스의 View 계층 구조는 비공개이며 한 가지 예외를 제외하고 수정해서는 안 됩니다. 사용자 정의 View를 cameraOverlayView 속성에 할당하고 해당 View를 사용하여 추가 정보를 제공하거나 카메라 인터페이스와 대구 간의 상호 작용을 관리할 수 있습니다.
📍 Providing a Delegate Object
- image picker controller를 사용하려면 UIImagePickerControllerDelegate 프로토콜을 준수하는 delegate를 제공해야 합니다.
- iOS 4.1부터 델리게이트를 사용하여 스틸 image 메타데이터를 image와 함께 카메라 롤에 저장할 수 있습니다. UIImagePickerControllerDelegate를 참조하세요.
📍 Adjusting Flash Mode
- iOS 4.0 이상에서는 사용자가 플래시 모드를 조정하고(플래시 LED가 있는 기기에서), 사용할 카메라를 선택하고(전면 및 후면 카메라가 있는 기기에서), 정지 image 간에 전환과 그리고 영상 캡쳐를 위한 사용자 정의 컨트롤을 제공할 수 있습니다. 이러한 설정을 프로그래밍 방식으로 관리할 수도 있습니다.
- 플래시를 직접 조작하여 스트로보 라이트와 같은 효과를 제공할 수도 있습니다.
- 비디오 캡처 모드를 사용하도록 설정된 picker 인터페이스를 제시합니다.
- 그런 다음 cameraFlashMode 속성을 UIImagePickerController.CameraFlashMode.on 또는 UIImagePickerController.CameraFlashMode.off로 설정하여 플래시 LED를 켜거나 끕니다.
📍 Working with Movies
- 동영상 캡처의 기본 지속 시간 제한은 10분이지만 videoMaximumDuration 속성을 사용하여 조정할 수 있습니다.
- 사용자가 MMS, YouTube 또는 다른 대상으로 영화를 보내기 위해 공유 버튼을 탭하면 적절한 지속 시간 제한과 적절한 비디오 품질이 적용됩니다.
- 기본 카메라 인터페이스는 이전에 저장한 동영상 편집을 지원합니다.
- 편집에는 동영상의 시작 또는 끝 부분부터 트리밍한 다음 트리밍된 동영상을 저장하는 작업이 포함됩니다.
- 새로운 동영상 녹화를 지원하는 것보다 동영상 편집 전용 인터페이스를 표시하려면 UIVideoEditorController 클래스를 사용하십시오.
📍 Working with Live Photos
- Live Photos는 지원되는 장치의 카메라 앱 기능으로, 사진에 한 순간이 아니라 캡처 직전과 직후의 움직임과 소리를 포함할 수 있습니다.
- PHLivePhoto 개체는 Live Photo를 나타내고 PHLivePhotoView 클래스는 Live Photo를 표시하고 해당 콘텐츠를 재생하기 위한 시스템 표준 대화형 사용자 인터페이스를 제공합니다.
- Live Photo에는 소리와 움직임이 포함되지만 사진으로 남아 있습니다.
- image picker controller를 사용하여 정지 image를 캡처하거나 선택하면(mediaTypes 배열에 kUTTypeImage 유형만 포함하여) Live Photos로 캡처된 assets이 계속해서 picker에 나타납니다.
- 그러나 사용자가 assets을 선택하면 delegate 객체는 Live Photo의 정지 image 표현이 포함된 UIImage 객체만 받습니다.
- 사용자가 image picker로 라이브 포토를 선택할 때 풀 모션 및 사운드 콘텐츠를 얻으려면 mediaTypes 배열에 kUTTypeImage 및 kUTTypeLivePhoto 유형을 모두 포함해야 합니다. 자세한 내용은 UIImagePickerControllerDelegate의 livePhoto를 참조하세요.
- 완전히 사용자 정의된 image 또는 동영상 캡처를 수행하려면 스틸 및 비디오 미디어 캡처에 설명된 대로 AVFoundation 프레임워크를 대신 사용하십시오. AVFoundation 프레임워크를 사용한 카메라 액세스는 iOS 4.0부터 사용할 수 있습니다.
- 사진 라이브러리 탐색을 위한 완전히 사용자 정의된 image picker를 만들려면 사진 프레임워크의 클래스를 사용하십시오.
- 예를 들어 iOS에서 생성 및 캐시된 더 큰 축소판 image를 표시하는 사용자 지정 image picker를 만들 수 있습니다. 타임스탬프 및 위치 정보를 포함한 image 메타데이터를 사용하거나 MapKit 및 iCloud 사진 공유와 같은 다른 기능과 통합됩니다. 사진 프레임워크를 사용한 미디어 탐색은 iOS 8.0부터 사용할 수 있습니다.
UIImagePickerController - 공식문서
📌 PHPickerViewController - 공식문서
- 사진 라이브러리에서 assets을 선택하기 위한 사용자 인터페이스를 제공하는 View controller입니다.
📍 Declaration
- iOS, iPadOS, Mac Catalyst
class PHPickerViewController : UIViewController
class PHPickerViewController : NSViewController
📍 Overview
- PHPickerViewController 클래스는 UIImagePickerController의 대안입니다.
- PHPickerViewController는 안정성과 안정성을 개선하고 다음과 같은 개발자와 사용자에게 여러 가지 이점을 제공합니다.
- 지연된 image 로딩 및 복구
- UI RAW 및 파노라마 image와 같은 크고 복잡한 assets의 안정적인 처리
- UIImagePickerController에 사용할 수 없는 사용자 선택 가능한 assets
- Live Photos만 표시하도록 Picker 구성
- 라이브러리 액세스 없이 PHLivePhoto 개체 사용 가능
- 유효하지 않은 입력에 대한 더 엄격한 검증
- Picker 개체는 한 번만 표시할 수 있습니다.
- 세션 간에 재사용할 수 없습니다.
뷰 계층 구조가 비공개이고 공개 API를 통해 액세스할 수 없기 때문에 PHPickerViewController를 하위 클래스로 분류할 수 없습니다.
PHPickerViewController - 공식문서
📌 PHPickerViewControllerDelegate - 공식문서
- Picker가 사용자 선택을 전달하는 데 사용하는 프로토콜입니다.
📍 Handling User Selection
func picker(PHPickerViewController, didFinishPicking: [PHPickerResult])
- 사용자가 취소 버튼을 사용하여 선택을 완료했거나 Picker를 닫았음을 대리인에게 알립니다.
- picker
- 현재 표시된 Picker View controller입니다.
- results
PHPickerViewControllerDelegate - 공식문서
📌 오픈마켓 - PHPickerViewController 방식으로 리팩토링
private let pickerController: PHPickerViewController = {
var configuration = PHPickerConfiguration()
configuration.selectionLimit = 5
configuration.filter = .images
let controller = PHPickerViewController(configuration: configuration)
return controller
}()
extension ProductRegistrationView: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true,completion: nil)
results.forEach { self.insertImages($0.itemProvider) }
}
private func insertImages(_ itemProvider: NSItemProvider) {
guard itemProvider.canLoadObject(ofClass: UIImage.self) else { return }
itemProvider.loadObject(ofClass: UIImage.self) { image, error in
DispatchQueue.main.sync {
guard let image = image as? UIImage else { return }
let imageView = self.setupPickerImageView(image: image)
self.imageStackView.insertArrangedSubview(imageView, at: .zero)
}
}
}
private func setupPickerImageView(image: UIImage?) -> UIImageView {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.image = image
NSLayoutConstraint.activate(
[
imageView.widthAnchor.constraint(equalToConstant: pickerView.frame.width),
imageView.heightAnchor.constraint(equalToConstant: pickerView.frame.height)
]
)
return imageView
}
}
- 구현화면
참고 블로그