티스토리 뷰

 

 

 

 

오늘은 ImagePicker를 사용해서 프로필 화면을 바꿔보자!

 

 


 

 

 

UI

 

 

 

대충 이런 view를 상상했지만 ㅎ... 

 

 

 

 

너무 부실한 내 UI이다. . ㅋㅋ 하지만 아직 SwiftUI를 시작한 지 얼마 안 됐으니 UI는 대충 하고

기능적인 부분에 집중해보자!

 

 

 

 

우선 내 프로필 변경에서는 변경할 사진을 누르고, 이름을 입력한 후 저장을 누르게 되면

"저장되었습니다."라는 팝업창이 나오게 구현하였다.

 

 

ImagePicker 사용기

 

우선 프로필 속 사진을 바꾸고 싶다면 이미지를 갤러리에서 사진을 가져와야 한다. 그 역할을 해주는 게 UIImagePickerController이다.

공식문서 링크를 걸어뒀으니 더 자세한 기능들이 궁금하다면 클릭해서 읽어보시길!

 

UIImagePickerController는 UIKit에 사용되는 라이브러리이다. swiftUI에는 없기 때문에 가져와서 써야 한다.. 

그렇기 때문에 UIViewControllerRepresentable 를 사용해서 선언을 해줘야 한다. 말이 갑자기 복잡해지는 거 같은데 . .

공식문서를 보면 필수로 작성해야 하는 메서드들, 선언들이 있다. 

 

func makeUIViewController(context: Context) -> UIImagePickerController {
        
        let picker = UIImagePickerController()
        
        picker.delegate = context.coordinator
        
        return picker
        
    }
    
 func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {
        
}

 

  • makeUIViewController : 뷰 컨트롤러를 생성하고 초기 상태를 지정해 준다. 이 메서드가 리턴할 때 swiftUI view로 넘어온다.
  • updateUIViewController : SwiftUI의 상태값이 변경될 때  지정된 뷰 컨트롤러의 상태를 업데이트한다.

아무튼 위의 코드를 활용해서 imagePicker를 불러오는 코드는 아래와 같이 구성하였다.

 

struct UImagePicker: UIViewControllerRepresentable {
    
    typealias UIViewControllerType = UIImagePickerController
    
    @Environment(\.presentationMode)
    private var presentationMode // 해당 뷰컨트롤러의 노출 여부
    let sourceType: UIImagePickerController.SourceType
    let imagePicked: (UIImage) -> () // 이미지가 선택됐을때 결과 호출
    

    
    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
        
        let parent: UImagePicker
        
        init(parent: UImagePicker) {
            self.parent = parent
        }
        
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            
            if let image = info[.originalImage] as? UIImage {
                parent.imagePicked(image)
                parent.presentationMode.wrappedValue.dismiss()
            }
            
        }
        
        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            parent.presentationMode.wrappedValue.dismiss()
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }
    
    
    func makeUIViewController(context: Context) -> UIImagePickerController {
        
        let picker = UIImagePickerController()
        
        picker.delegate = context.coordinator
        
        return picker
        
    }
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {
        
    }

}

 

 

  • Coordinator :  UIkit에서 swiftUI로의 데이터 전달

 

View

버튼 2개랑 텍스트 필드 하나를 구성해 주었다.

struct ContentView: View {
    @State var openPhoto = false
    @State var image: UIImage?
    @State var name = ""
    @State private var showing = false
    
    var body: some View {
            VStack {
                
                Button("저장") {
                    showing = true
                }
                .alert(isPresented: $showing) {
                    Alert(title: Text("저장"), message: Text("저장 되었습니다!"))
                }
                .frame(width: 350, height: 50, alignment: .trailing)
                .padding()
                
                Button(action: {
                    self.openPhoto.toggle()
                }, label: {
                    let selected = image == nil ? Image("Image") : Image(uiImage: image!)
                    selected
                        .resizable()
                        .frame(width: 200, height: 200)
                })
                
                .clipShape(Circle())
                .overlay {
                    Circle().stroke(.black, lineWidth: 4)
                }
                .sheet(isPresented: $openPhoto) {
                    UImagePicker(sourceType: .photoLibrary) { (image) in
                        self.image = image
                    }
                }
                
                TextField("이름", text: $name)
                    .frame(width: 300, height: 70, alignment: .center)
                    .padding()
                
            }
            Spacer()
    }
    
}

 

 

이미지를 불러오는 버튼만 자세하게 보자면 삼항연산자로 이미지가 아무것도 선택되지 않는다면, 내가 설정한 기본 이미지가 뜨게 하고 이미지가 선택된다면 선택된 이미지를 띄우도록 하였다.

 

그리고 sheet를 사용하여  sheet가 true가 됐을 때 사용자가 선택한 사진이 표시되도록 하는 시트 수정자를 버튼에 추가해 주었다.

 

처음에 블로그를 참고하다가 Coordinator패턴으로 구현을 했다는데 이게 뭐지라는 생각이 제일 많이 들었고 다른 블로그들을 참고해 봐도 이해가 잘 가지 않았다. 공부하면 할수록 더 복잡해지는 거 같기도 하고 . .

 

그래서 Coordinator에 대해 읽어보면 좋을 거 같은 블로그를 참고해 두었으니 도움이 되었으면 좋겠다 ㅎ. ㅎ

 

https://ally10.tistory.com/44

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
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
글 보관함