-
내가 필요한 다이어리2Swift/다이어리 2024. 4. 14. 21:28
가보자고~
갤러리에서 이미지 추가를 위해 작성된 ImagePicker 파일
// 'UIViewControllerRepresentable' 프로토콜을 준수하는 구조체로 // SwiftUI 뷰에서 UIKit의 View Controller를 표시하기 위해 사용 struct ImagePicker: UIViewControllerRepresentable { // 바인딩된 UIImage - 선택된 이미지 표시 @Binding var selectedImage: UIImage? // SwiftUI에서 제공하는 환경 값으로, 모달로 표시된 뷰를 닫는데 사용 @Environment(\.presentationMode) private var presentationMode // 선택된 이미지가 없는 경우 기본 이미지로 설정 var defaultImage: UIImage? = UIImage(named: "이미지추가") // UIImagePickerController에서 사용할 이미지 소스의 타입을 지정(.photoLibrary, .camera 등) var sourceType: UIImagePickerController.SourceType // ImagePicker의 초기화 메서드 init(selectedImage: Binding<UIImage?>, sourceType: UIImagePickerController.SourceType, defaultImage: UIImage? = nil) { _selectedImage = selectedImage self.sourceType = sourceType self.defaultImage = defaultImage } // UIViewControllerRepresentable 프로토콜에서 요구되는 메서드 // UIImagePickerController를 생성하고 설정 func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController { let imagePicker = UIImagePickerController() imagePicker.allowsEditing = true imagePicker.sourceType = sourceType imagePicker.delegate = context.coordinator return imagePicker } // UIViewControllerRepresentable 프로토콜에서 요구되는 메서드 // 이미지 피커가 업데이트될 때 호출 func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) { } // UIImagePickerController의 delegate를 처리하는 클래스 // 이미지가 선택되면 해당 이미지를 selectedImage에 할당하고 이미지 피커를 닫음 func makeCoordinator() -> Coordinator { Coordinator(self) } final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { var parent: ImagePicker init(_ parent: ImagePicker) { self.parent = parent } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage { parent.selectedImage = image } parent.presentationMode.wrappedValue.dismiss() } } }
이미지를 추가하려면 따로 파일 파서 이런 메서드들을 작성해야 하는 듯
기본 이미지도 넣으려고 조금 코드를 변경함
// 캘린더 생성 DatePicker( "Start Date", selection: $date, displayedComponents: [.date] ) .datePickerStyle(.graphical) // 뷰가 나타날 때 dateFormat 설정 .onAppear { dateFormat = dateFormatter.string(from: date) } // 날짜를 선택할 때 dateFormat 변경 .onChange(of: date) { newValue in dateFormat = dateFormatter.string(from: newValue) }
캘린더 부분도 조금 변경을 줌
선택된 날짜를 다음 화면으로 넘겨줘야하기때문에 .onAppear과 .onChange를 사용했는데
.onAppear은 뷰 나타날 때 한번 보여주고
.onChange는 값이 변경될 때마다 보여주는 거
// 내비게이션 설정 .navigationBarTitle("일기 작성하기", displayMode: .inline) .navigationBarItems(trailing: Button("다음") { print("다음") })
내비게이션 바도 설정해 줌
중간에 이름은 "일기 작성하기" 로하고
오른쪽에 "다음" 버튼도 만들어줌
// TextEditor에 작성될 문자열 @State var diary: String = "" let placeholder: String = "오늘의 일기를 작성해보세요!" var body: some View { ZStack { TextEditor(text: $diary) .lineSpacing(10) .border(Color.gray, width: 3) // TextEditor에 placeholder기능이 없어서 따로 조건문으로 생성 if diary.isEmpty { Text(placeholder) .foregroundColor(Color.primary.opacity(0.25)) } } }
이런 커스텀 같은 것도 해봤지요
ZStack으로 겹치게 해서 아무것도 안 적혀있으면 placeholder기능이 있는 것처럼 구현
// ImagePicker 표시 .sheet(isPresented: $openPhoto) { ImagePicker(selectedImage: self.$image, sourceType: .photoLibrary) }
마지막으로 .sheet을 사용해서 모달로 표시되는 이미지 선택기 구현
$openPhoto 바인딩을 사용해서 모달이 열리거나 닫히는지 제어
사용자가 '이미지 선택기 오픈 -> 이미지 선택 -> 해당 이미지 $image에 할당 -> 모달이 닫힘' 순으로 사용
일단 틀만 만들어 보기~
이미지 추가하는 거 넣었으니까 다음은 할만하겠지..?
'Swift > 다이어리' 카테고리의 다른 글
내가 필요한 다이어리5 (0) 2024.04.18 내가 필요한 다이어리4 (1) 2024.04.16 내가 필요한 다이어리3 (1) 2024.04.15 내가 필요한 다이어리1 (0) 2024.04.13