iOS/SwiftUI
PhotoPicker
Hamp
2025. 11. 2. 14:22
반응형

📷 PhotoPicker
🧩 역할
SwiftUI에서 시스템 갤러리를 쉽게 띄울수 있게 제공되는 뷰
🧱 구조
생성자에 쓰이는 파라미터를 살펴보자.
- selection:
- Binding<PhotosPickerItem?> 또는 Binding<[PhotosPickerItem]>
- 갤러리에서 선택한 결과를 바인딩하는 파라미터
- maxSelectionCount
- Int?
- 한번에 고를 수 있는 최대 항목 수, nil = 무제한
- selectionBehavior
- PhotosPickerSelectionBehavior
- 선택 처리에 대한 행동
| Behavior | 순서 보존 여부연속 | 선택 제약 | 여부설명 |
| .default | ❌ | ❌ | 시스템 기본. 순서 관계 없음, 자유롭게 선택/해제 가능 |
| .ordered | ✅ | ❌ | 사용자가 선택한 순서를 유지. “1, 2, 3…” 번호가 붙음 |
| .continuous | ❌ | ✅ | 연속된 구간만 선택 가능. 떨어진 항목끼리는 동시에 선택 불가 |
| .continuousAndOrdered | ✅ | ✅ | 연속 선택만 허용하면서, 그 선택 순서를 유지 |
- matching
- PHPickerFilter 또는 PHPickerFilter.any(0f: [...])
- 보여줄 미디어 타입을 제어
- preferredItemEncoding
- PhotosPickerItem.EncodingDisambiguationPolicy
- 선택한 미디어 데이터를 전달할 떄, 어떤 인코딩이된 상태로 전달될 지를 결정
| EncodingDisambiguationPolicy | 의미 | 장점 | 단점 |
| .automatic (기본값) | 시스템이 가장 적절한 형식 결저정 | 무난함 | |
| .current | 현재 인코딩 그대로 사용 | 원본 품질 유지 | 앱이 해당 포맷을 처리할 수 있어야함 |
| .compatible | 가장 호환성이 높은 형식 | 대부분의 앱에서 별도 처리 없이 바로 사용 | 변환 과정에서 품질 손실 발생 가능 |
- photoLibrary
- PhotoLibrary
- 어느 PhotoLibrary 인스턴스에서 피커를 열지 지정, 보통 .shared()
🤖 사용 예시
실제 파라미터 내용들이 파악됐다면, 넣어주는거는 어렵지 않으므로 대충 사용하는 형태만 살펴보자.
viewModifier로도 똑같이 제공된다.
이 때는 isPresented 플래그 변수를 사용해, 열리고 닫힘을 컨트롤
VStack {
PhotosPicker(selection: .constant(nil)) {
Text("Hello")
}
}
// 또는
VStack {
Text("Hello").onTapGesture {
trigger.toggle()
}
}
.photosPicker(isPresented: $trigger, selection: .constant(nil))
🖨️ 가져온 데이터를 UIImage로 변환
loadTransferable함수를 이용하여, Transferable를 채택한 객체, 여기선 Data로 전환할 수 있음
enum PhotosPickerItemTransferError: Error {
case failedToLoadData
case missingSelf
}
final class PhotosPickerItemTransfer {
func transform(_ items: [PhotosPickerItem]) async throws -> [UIImage] {
try await withThrowingTaskGroup(of: (Int, Data).self) { group in
for (index, item) in items.enumerated() {
group.addTask { [weak self] in
// self가 이미 해제된 경우 작업을 취소하기 위해 에러 반환
guard let self
else {
throw PhotosPickerItemTransferError.missingSelf
}
let data = try await self.transform(from: item)
return (index, data)
}
}
var results: [(Int, Data)] = []
for try await result in group {
results.append(result)
}
return results.sorted { $0.0 < $1.0 }.compactMap { UIImage(data: $0.1) }
}
}
private func transform(from item: PhotosPickerItem) async throws(PhotosPickerItemTransferError) -> Data {
guard let data = try? await item.loadTransferable(type: Data.self)
else {
throw PhotosPickerItemTransferError.failedToLoadData
}
return data
}
}
출처
init(selection:matching:preferredItemEncoding:photoLibrary:label:) | Apple Developer Documentation
Creates a picker that selects an item from the photo library you specify and optionally configures the types of items to show, item encoding, and label behavior.
developer.apple.com
반응형