iOS 相機與相簿整合功能教學
讓使用者上傳頭像或分享照片是常見的功能。在 iOS 16+,我們使用 PhotosPicker 來存取相簿,這不需要使用者授權即可使用(因為是 Out-of-process 執行的)。
選擇照片 (PhotosPicker)
單張照片選擇
import PhotosUI
struct PhotoView: View {
@State private var selectedItem: PhotosPickerItem?
@State private var selectedImage: Image?
var body: some View {
VStack {
if let selectedImage {
selectedImage
.resizable()
.scaledToFit()
.frame(width: 300, height: 300)
}
PhotosPicker(selection: $selectedItem, matching: .images) {
Label("選擇照片", systemImage: "photo")
}
.onChange(of: selectedItem) { newItem in
Task {
// 將選中的 Item 轉換成 Data 再轉成 Image
if let data = try? await newItem?.loadTransferable(type: Data.self),
let uiImage = UIImage(data: data) {
selectedImage = Image(uiImage: uiImage)
}
}
}
}
}
}
拍照 (Camera)
SwiftUI 目前沒有內建的 Camera View。我們必須使用 UIViewControllerRepresentable 來包裝 UIKit 的 UIImagePickerController。
struct CameraView: UIViewControllerRepresentable {
@Binding var image: UIImage?
@Environment(\.dismiss) var dismiss
func makeUIViewController(context: Context) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.sourceType = .camera // 設定來源為相機
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
func makeCoordinator() -> Coordinator { Coordinator(self) }
class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let parent: CameraView
init(_ parent: CameraView) { self.parent = parent }
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.originalImage] as? UIImage {
parent.image = image
}
parent.dismiss()
}
}
}
儲存照片到相簿
如果你有生成圖片或濾鏡功能,可能需要將結果存回相簿。這需要 Privacy - Photo Library Additions Usage Description 權限。
func saveToAlbum(image: UIImage) {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
權限設定 (Info.plist)
使用相機或存取相簿時,必須在 Info.plist 中宣告對應的 Privacy Key,否則 App 會直接崩潰。
| 功能 | Key (Info.plist) | 說明 |
|---|---|---|
| 相機 | Privacy - Camera Usage Description | 拍攝照片或錄影 |
| 儲存照片 | Privacy - Photo Library Additions Usage Description | 僅寫入權限 (存照片到相簿) |
| 讀取相簿 | Privacy - Photo Library Usage Description | 舊版 API 讀取照片 (PhotosPicker 不需要此權限) |