SwiftUI와 함께 PHPickerViewController를 사용하여 이미지를 선택하는 방법

14899 단어 swiftuiimagesiosswift
프로필 사진을 변경하거나 업데이트를 게시하거나 애완 동물의 사진을 공유할 때 iPhone 라이브러리에서 이미지를 선택해야 합니다. 이번 포스트에서는 PHPickerViewController를 SwiftUI와 함께 사용하는 방법을 알아보겠습니다. Apple은 WWDC2020에서 이 뷰 컨트롤러를 발표했습니다.

PHPickerViewController란 무엇입니까?


PHPickerViewController는 앱 사용자가 사진 라이브러리에서 자산을 선택할 수 있는 방법을 제공하는 보기 컨트롤러입니다. 그것은 잘 알려진 사용자 인터페이스를 제공하며 우리는 그것을 구축하는 데 신경 쓸 필요가 없습니다.

이 접근 방식의 장점 중 하나는 Info.plist 파일에서 사용자의 사진 라이브러리에 액세스하기 위해 정보를 추가하는 것에 대해 걱정할 필요가 없다는 것입니다. 사용자는 모든 사진 라이브러리에 대한 액세스를 허용하거나 특정 사진에 대한 액세스를 선택적으로 허용하도록 결정할 수 있습니다. 이는 앱이 전체 라이브러리와 심지어 track people를 읽을 수 있는 개인 정보 보호 문제를 해결합니다.

PHPickerViewController 만들기


PHPickerViewController를 생성하려면 PHPickerConfiguration 의 인스턴스인 구성을 전달하여 초기화해야 합니다. 구성을 위해 원하는 사진 유형을 지정하고 선택 제한을 설정해야 합니다.
PHPickerViewController 자체에 대해 PHPickerViewControllerDelegate 프로토콜을 구현해야 하는 대리자를 설정합니다. 사용자가 사진을 선택했을 때 신호를 보내는 방법은 단 하나뿐입니다.

SwiftUI와 통합



SwiftUI 앱에서 PHPickerViewController를 사용하려면 UIViewControllerRepresentable를 사용하여 UIKit 뷰 컨트롤러를 나타내야 합니다. 이를 수행하는 데 필요한 모든 단계를 살펴보겠습니다.

UIKit 뷰 컨트롤러 설정


UIViewControllerRepresentable는 프로토콜이며 두 가지 방법을 구현해야 합니다.
  • makeUIViewController - 보기 컨트롤러를 만들고 구성합니다.
  • updateUIViewControoler - 뷰 컨트롤러의 상태를 업데이트합니다.
  • PHPickerViewController 메소드에서 makeUIViewController를 생성하고 설정해 보겠습니다. 업데이트할 필요가 없으므로 updateUIViewControoler를 비워 둘 수 있습니다.

    struct PhotoPicker: UIViewControllerRepresentable {
      @Binding var pickerResult: [UIImage] // pass images back to the SwiftUI view
      @Binding var isPresented: Bool // close the modal view
    
      func makeUIViewController(context: Context) -> some UIViewController {
        var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
        configuration.filter = .images // filter only to images
        configuration.selectionLimit = 0 // ignore limit
    
        let photoPickerViewController = PHPickerViewController(configuration: configuration)
        photoPickerViewController.delegate = context.coordinator // Use Coordinator for delegation
        return photoPickerViewController
      }
    
      func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }
    }
    


    조정자



    이제 PHPickerViewController를 표시할 수 있지만 선택한 이미지를 다시 전송할 수 있는 방법은 무엇입니까? makeCoordinator 메서드를 사용하고 Coordinator 프로토콜을 구현하는 PHPickerViewControllerDelegate 클래스를 만들어야 합니다. SwiftUI가 UIKit 위임 패턴 아이디어와 통신하는 방법에 대한 사려 깊은 접근 방식입니다.

    struct PhotoPicker: UIViewControllerRepresentable {
    
      // ...
    
      func makeCoordinator() -> Coordinator {
        Coordinator(self)
      }
    
      // Create the Coordinator, in this case it is a way to communicate with the PHPickerViewController
      class Coordinator: PHPickerViewControllerDelegate {
        private let parent: PhotoPicker
    
        init(_ parent: PhotoPicker) {
          self.parent = parent
        }
    
        func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        }
      }
    }
    


    SwiftUI와 함께 UIKit 사용하기



    모두 함께 넣어 봅시다. 사진 선택기 보기를 표시하고 모달로 표시하려면 SwiftUI 보기를 만들어야 합니다. 내 .NET에서 SwiftUI에서 모달 보기를 표시하는 방법에 대해 자세히 알아볼 수 있습니다.

    .sheet(isPresented: $photoPickerIsPresented) {
      // Present the photo picker view modally
      PhotoPicker(pickerResult: $pickerResult,
                  isPresented: $photoPickerIsPresented)
    }
    


    UIKit에서 SwiftUI로 데이터 전달



    사용자가 선택한 사진을 가져오려면 @State 변수를 사용하고 PhotoPicker property wrapper 을 사용하여 @Binding 보기에 전달합니다.

    이제 PHPickerViewControllerDelegate 클래스에 대한 Coordinator 프로토콜을 완전히 완료할 수 있습니다.

    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
      parent.pickerResult.removeAll() // remove previous pictures from the main view
    
      // unpack the selected items
      for image in results {
        if image.itemProvider.canLoadObject(ofClass: UIImage.self) {
          image.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] newImage, error in
            if let error = error {
              print("Can't load image \(error.localizedDescription)")
            } else if let image = newImage as? UIImage {
              // Add new image and pass it back to the main view
              self?.parent.pickerResult.append(image)
            }
          }
        } else {
          print("Can't load asset")
        }
      }
    
      // close the modal view
      parent.isPresented = false
    }
    


    여기서 우리가 하는 일은 사진 라이브러리에서 선택한 항목의 압축을 풀고 상위 변수@Binding로 설정하는 것입니다. 이렇게 하면 데이터를 다시 기본 보기로 전송합니다.

    선택한 이미지 제시



    선택한 사진을 표시하기 위해 반복하여 ScrollView 에 표시할 수 있습니다.

    ScrollView {
      ForEach(pickerResult, id: \.self) { uiImage in
        ImageView(uiImage: uiImage)
      }
    }
    


    중요한 사실은 이미지 유형이 UIImage 이지만 다행히도 SwiftUI는 Image 유형을 전달하는 UIImage 보기에 대한 멋진 초기화 프로그램을 제공합니다.

    전체 구현here을 확인할 수 있습니다.

    TL;DR



    이미지를 선택하고 앱에서 사용하는 것은 최신 iOS 애플리케이션의 필수 기능입니다. Apple은 WWDC2020에서 보다 안전하고 세분화된 방식으로 이를 수행하는 새로운 방법을 발표했습니다 - PHPickerViewController . iOS14 이상 버전에서만 사용할 수 있습니다.
    PHPickerViewController를 SwiftUI와 함께 사용하려면 UIViewControllerRepresentable 프로토콜을 구현해야 합니다. UIKit 뷰 컨트롤러와 완벽하게 통신할 수 있습니다.

    연결


  • Sample code
  • PHPickerViewController documentation
  • iOS Privacy: detect.location - An easy way to access the user's iOS location data without actually having access
  • Adopting the new PHPicker
  • Checking out the new PHPickerViewController in iOS 14
  • Replacing UIImagePickerController with PHPickerViewController
  • Using PHPickerViewController Images in a Memory-Efficient Way
  • 좋은 웹페이지 즐겨찾기