티스토리 뷰

그동안 Multiselect 구현하느라 힘들었는데, 새로나온 PHPicker는 검색도 되고, zoom in - zoom out도 가능하다...! 앨범에서도 선택 가능하고, 기존의 UIImagePickerController의 상위 호환정도로 생각하면 된다.

struct PhotoPicker: UIViewControllerRepresentable {
  let configuration: PHPickerConfiguration
  @Binding var isPresented: Bool
  func makeUIViewController(context: Context) -> PHPickerViewController {
    let controller = PHPickerViewController(configuration: configuration)
    controller.delegate = context.coordinator
    return controller
  }

  func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {}
  func makeCoordinator() -> Coordinator {
    Coordinator(self)
  }

  // Use a Coordinator to act as your PHPickerViewControllerDelegate
  class Coordinator: PHPickerViewControllerDelegate {
    private let parent: PhotoPicker

    init(_ parent: PhotoPicker) {
      self.parent = parent
    }

    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
      print(results)
      parent.isPresented = false // Set isPresented to false because picking has finished.
    }
  }
}
struct HoneyTipWriteView: View {
  @State var showImagePicker: Bool = false

  var body: some View {
    ZStack {
      VStack {
        // 이미지, 위치 버튼
        HStack {
          Button(action: {
            self.showImagePicker = true
          }, label: {
            Image("safetymapIc")
          })
          Button(action: {}, label: {
            Image("safetymapPlaceIc")
          })
          Spacer()
        }
      }
    }.sheet(isPresented: $showImagePicker, content: {
      let configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
      PhotoPicker(configuration: configuration, isPresented: $showImagePicker)
    })
  }
}

 

권한을 요청하고, 확인하는 과정은 다음과 같다. 

 

 

PHAuthorizationStatus를 보면, 

 

Info.plist도 당연히 추가해준다. 

 

 

최근에 몇몇 앱에서 적용한 사례를 봤는데, limited로 선택시 그 사진들만 보이는 뷰로 바뀌는걸 봤다. 

developer.apple.com/documentation/photokit/phphotolibrary/3616113-presentlimitedlibrarypicker?changes=_6%20%20출처%3A%20https%3A%2F%2Fzeddios.tistory.com%2F1052%20%5BZeddiOS%5D

 

Apple Developer Documentation

 

developer.apple.com

이걸 이용해서 구현한다고 한다. 

 

 

+) 기존의 UIImagePickerController를 UIViewControllerRepresentable을 사용해서 쓰는 방식도 추가한다. 

struct ImagePicker: UIViewControllerRepresentable {

    @Environment(\.presentationMode)
    private var presentationMode

    let sourceType: UIImagePickerController.SourceType
    let onImagePicked: (UIImage) -> Void

    final class Coordinator: NSObject,
    UINavigationControllerDelegate,
    UIImagePickerControllerDelegate {

        @Binding
        private var presentationMode: PresentationMode
        private let sourceType: UIImagePickerController.SourceType
        private let onImagePicked: (UIImage) -> Void

        init(presentationMode: Binding<PresentationMode>,
             sourceType: UIImagePickerController.SourceType,
             onImagePicked: @escaping (UIImage) -> Void) {
            _presentationMode = presentationMode
            self.sourceType = sourceType
            self.onImagePicked = onImagePicked
        }

        func imagePickerController(_ picker: UIImagePickerController,
                                   didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
            onImagePicked(uiImage)
            presentationMode.dismiss()

        }

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            presentationMode.dismiss()
        }

    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(presentationMode: presentationMode,
                           sourceType: sourceType,
                           onImagePicked: onImagePicked)
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.sourceType = sourceType
        picker.delegate = context.coordinator
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController,
                                context: UIViewControllerRepresentableContext<ImagePicker>) {

    }

}

 

사용할때는 이렇게!!

struct ContentView: View {

    @State var showImagePicker: Bool = false
    @State var image: Image? = nil

    var body: some View {
        ZStack {
            VStack {
                Button(action: {
                    self.showImagePicker.toggle()
                }) {
                    Text("Show image picker")
                }
                image?.resizable().frame(width: 100, height: 100)
            }
            .sheet(isPresented: $showImagePicker) {
                ImagePicker(sourceType: .photoLibrary) { image in
                    self.image = Image(uiImage: image)
                }
            }
        }
    }
}

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함