티스토리 뷰
오늘은 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에 대해 읽어보면 좋을 거 같은 블로그를 참고해 두었으니 도움이 되었으면 좋겠다 ㅎ. ㅎ
'iOS > SwiftUI' 카테고리의 다른 글
[iOS/SwiftUI] Preview Crashed 해결방법 (0) | 2024.03.30 |
---|---|
[iOS/SwiftUI] DatePicker를 이용한 TaskEditor 만들기 (1) | 2024.02.29 |
[iOS/SwiftUI] LazyVGrid를 활용하여 뷰 만들기 (1) | 2024.02.25 |
[iOS/SwiftUI] List를 활용한 TodoList 만들기 (1) | 2024.02.07 |
[iOS/SwiftUI] stopwatch 구현하기 (0) | 2024.01.22 |
- Total
- Today
- Yesterday
- foundation models
- CoreData
- securefield
- rxswift
- XCTest
- swiftUI
- mergeconflict
- Xcode
- asyne-let
- imagepicker
- UIKit
- mlmodel
- 16173
- closure
- 백준
- Fastlane
- 스위프트
- ios
- group tasks
- SWIFT
- 클로저
- combine
- Task
- detached task
- wwdc25
- unstructed task
- ObservableObject
- 병합충돌
- 프로그래머스
- 코딩테스트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |