🏞ImagePicker 사용하기

sanghee·2021년 8월 18일
0

🚩iOS

목록 보기
8/18
post-thumbnail

목표

뷰에서 버튼을 누르면 이미지 피커를 띄우고 이미지 피커에서 선택된 이미지가 저장되도록 한다.

🏞ImagePicker

Utilities 폴더에 아래의 ImagePicker 코드를 추가한다. 이 코드를 간략하게 설명하자면, ImagePicker를 보여주고 사용자가 하나의 이미지를 선택하면 바인딩된 image 상태값에 해당 이미지를 저장하고 화면이 닫힌다.

import SwiftUI

struct ImagePicker: UIViewControllerRepresentable {
    @Binding var image: UIImage?
    @Environment(\.presentationMode) var mode
    
    func makeUIViewController(context: Context) -> some UIViewController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        return picker
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }
    
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
    }
    
    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
        let parent: ImagePicker
        
        init(_ parent: ImagePicker) {
            self.parent = parent
        }
        
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            guard let image = info[.originalImage] as? UIImage else { return }
            self.parent.image = image
            self.parent.mode.wrappedValue.dismiss()
        }
    }
}

상태값 추가하기

  • imagePickerPresented: 이미지 피커를 띄우는지에 대한 변수이다. true일 경우 이미지 피커가 보여진다.
  • selectedImage: 이미지 피커에서 선택한 이미지를 저장한다. UIImage 타입이다.
  • profileImage: selectedImage를 Image 타입으로 저장한다.
@State private var imagePickerPresented = false
@State private var selectedImage: UIImage?
@State private var profileImage: Image?

버튼

플러스 버튼을 누르면 imagePicker를 띄우고 싶다. 이 버튼의 action에서 imagePickerPresented 토글을 추가한다.

imagePickerPresented.toggle()

버튼의 label은 프로필 이미지가 없으면 plus 이미지를, 있으면 프로필 이미지를 보여준다.

Button(action: {
    imagePickerPresented.toggle()
}, label: {
    let image = profileImage == nil ? Image(systemName: "plus.circle") : channelImage ?? Image(systemName: "plus.circle")
    image
        .resizable()
        .scaledToFill()
        .frame(width: 64, height: 64)
        .clipShape(Circle())
})

sheet(isPresented:onDismiss:content:)?

Apple Developer Documentation - sheet(isPresented:onDismiss:content:)

Presents a sheet when a binding to a Boolean value that you provide is true.

제공한 바인딩된 불린값이 true일 경우 sheet를 보여준다.

버튼 sheet

버튼 코드의 뒤에 sheet를 연결한다.

  • isPresented: imagePickerPresented → 값이 true일 때 content를 보여준다.
  • onDismiss: loadImage → 이미지피커가 사라질 때 loadImage 함수를 실행한다.
  • content → 보여주려는 Content를 넣는다. 우리의 ImagePicker의 image에 selectedImage를 넣어 선택된 이미지가 selectedImage에 저장되도록 한다.
.sheet(isPresented: $imagePickerPresented,
       onDismiss: loadImage,
       content: { ImagePicker(image: $selectedImage) })

onDismiss 함수에는 loadImage 함수를 넣는다. selectedImage가 UIImage타입이므로 Image 타입으로 변환해 profileImage에 저장하는 함수이다.

func loadImage() {
        guard let selectedImage = selectedImage else { return }
        profileImage = Image(uiImage: selectedImage)
    }

완성된 모습

깃허브 커밋 주소

GitHub - Commit

profile
👩‍💻

0개의 댓글