diff --git a/ToMeetToMe/ToMeetToMe.xcodeproj/project.pbxproj b/ToMeetToMe/ToMeetToMe.xcodeproj/project.pbxproj index 03bd54f..79d0994 100644 --- a/ToMeetToMe/ToMeetToMe.xcodeproj/project.pbxproj +++ b/ToMeetToMe/ToMeetToMe.xcodeproj/project.pbxproj @@ -59,6 +59,9 @@ 86C4FC7F2B137E7E006878F4 /* MeetingMemberView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86C4FC7E2B137E7E006878F4 /* MeetingMemberView.swift */; }; 86C4FC812B137E93006878F4 /* MeetingInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86C4FC802B137E93006878F4 /* MeetingInfoView.swift */; }; 86C4FC832B137F65006878F4 /* RecommendView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86C4FC822B137F65006878F4 /* RecommendView.swift */; }; + EDD8788B2B31B8E400BFDCDF /* PickPromiseDateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDD8788A2B31B8E400BFDCDF /* PickPromiseDateView.swift */; }; + EDD8788D2B31B93B00BFDCDF /* SettingPromiseInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDD8788C2B31B93B00BFDCDF /* SettingPromiseInfoView.swift */; }; + EDD8788F2B31C3F600BFDCDF /* PhotoPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDD8788E2B31C3F600BFDCDF /* PhotoPicker.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -113,6 +116,9 @@ 86C4FC7E2B137E7E006878F4 /* MeetingMemberView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingMemberView.swift; sourceTree = ""; }; 86C4FC802B137E93006878F4 /* MeetingInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingInfoView.swift; sourceTree = ""; }; 86C4FC822B137F65006878F4 /* RecommendView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendView.swift; sourceTree = ""; }; + EDD8788A2B31B8E400BFDCDF /* PickPromiseDateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickPromiseDateView.swift; sourceTree = ""; }; + EDD8788C2B31B93B00BFDCDF /* SettingPromiseInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingPromiseInfoView.swift; sourceTree = ""; }; + EDD8788E2B31C3F600BFDCDF /* PhotoPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoPicker.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -172,6 +178,7 @@ 619FADA92AE4F9DA00AB5511 /* String+extensions.swift */, 619FADAB2AE506D700AB5511 /* Date+extensions.swift */, 6187188C2AFDFAED0011480D /* Utilities.swift */, + EDD8788E2B31C3F600BFDCDF /* PhotoPicker.swift */, ); path = Extensions; sourceTree = ""; @@ -282,6 +289,8 @@ 61DF8C1C2B1DE05D008AEBF5 /* Group */ = { isa = PBXGroup; children = ( + EDD8788A2B31B8E400BFDCDF /* PickPromiseDateView.swift */, + EDD8788C2B31B93B00BFDCDF /* SettingPromiseInfoView.swift */, ); path = Group; sourceTree = ""; @@ -490,6 +499,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + EDD8788F2B31C3F600BFDCDF /* PhotoPicker.swift in Sources */, 618718822AFD3E710011480D /* UserAuthModel.swift in Sources */, 86AE6B022ADBD1130092A1FE /* AddGroupView.swift in Sources */, 86AE6AFA2ADBCE1E0092A1FE /* AddFriendListCell.swift in Sources */, @@ -510,6 +520,7 @@ 86C4FC832B137F65006878F4 /* RecommendView.swift in Sources */, 86C4FC7D2B137E65006878F4 /* MemberView.swift in Sources */, 61AF912C2AD4778A009563E3 /* PromiseView.swift in Sources */, + EDD8788B2B31B8E400BFDCDF /* PickPromiseDateView.swift in Sources */, 61AF91402AD6299D009563E3 /* FriendGridView.swift in Sources */, 86AE6B222AE5633F0092A1FE /* MyPageView.swift in Sources */, 61AF912E2AD477A4009563E3 /* ProfileView.swift in Sources */, @@ -518,6 +529,7 @@ 86AE6B1E2AE562E50092A1FE /* FriendListCell.swift in Sources */, 86AE6B2A2AE566D40092A1FE /* MainButtonView.swift in Sources */, 619FADAE2AE5126200AB5511 /* DetailDayScheduleView.swift in Sources */, + EDD8788D2B31B93B00BFDCDF /* SettingPromiseInfoView.swift in Sources */, 619FADB02AE51DD100AB5511 /* AddScheduleView.swift in Sources */, 616FF7602B0898F80011B7DB /* PromiseConfirmationView.swift in Sources */, 6187188D2AFDFAED0011480D /* Utilities.swift in Sources */, diff --git a/ToMeetToMe/ToMeetToMe/Other/Group/PickDateView.swift b/ToMeetToMe/ToMeetToMe/Other/Group/PickDateView.swift deleted file mode 100644 index 1a7ca80..0000000 --- a/ToMeetToMe/ToMeetToMe/Other/Group/PickDateView.swift +++ /dev/null @@ -1,357 +0,0 @@ -// -// PickDateView.swift -// ToMeetToMe -// -// Created by 이자민 on 2023/11/05. -// - -import SwiftUI - -struct PickDateView: View { - @State private var date = Date() - let dateRange: ClosedRange = { - let calendar = Calendar.current - let startComponents = DateComponents(hour: 22, minute: 59, second: 59) - let endComponents = DateComponents(hour: 23, minute: 00, second: 00) - return calendar.date(from:startComponents)! - ... - calendar.date(from:endComponents)! - }() - - @State private var vibrateOnRing = true - @State var month: Date // 현재 달 - @State var clickedCurrentMonthDates: Date? - @State - var scheduleArray = Schedule.scheduleArray - @State - var calendarScheduleArray: [Schedule] = [] - - @State var shouldShowDetailSchedule: Bool = false - - init(month: Date = Date(), clickedCurrentMonthDates: Date? = nil) { - _month = State(initialValue: month) - _clickedCurrentMonthDates = State(initialValue: clickedCurrentMonthDates) - } - var body: some View { - - - NavigationView{ - - VStack(){ - Text("약속을 생성할 기간을\n선택해주세요 :)") - .font(Font.custom("Pretendard", size: 16)) - .foregroundColor(Color.black) - .frame(maxWidth: .infinity, alignment: .leading) // 좌측 정렬 - - headerView - .padding(EdgeInsets(top: 20, leading: 0, bottom: 0, trailing: 0)) - calendarGridView - - Toggle("하루종일", isOn: $vibrateOnRing) - .toggleStyle(SwitchToggleStyle(tint: Color.primaryColor)) - .frame(maxWidth: .infinity, alignment: .topLeading) - .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 220)) - - Spacer() - - if !vibrateOnRing { // Toggle이 true일 때만 DatePicker를 표시 - Text("약속 시간대를 선택해주세요 !") - .font(Font.custom("Pretendard", size: 16)) - .foregroundColor(Color.black) - .frame(maxWidth: .infinity, alignment: .leading) - - HStack { - DatePicker("", selection: $date, in: dateRange, displayedComponents: [.hourAndMinute]) - DatePicker("", selection: $date, in: dateRange, displayedComponents: [.hourAndMinute]) - .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 140)) - Spacer() - } - } - - - - } - .padding(.horizontal, 024) - .navigationTitle("약속 생성") - .navigationBarTitleDisplayMode(.inline) - .navigationBarItems(trailing: Text("확인")) - - } - - } - - // < 2023년 10월 > - // 일 월 화 수 목 금 토 - // 날짜와 요일 표시 - private var headerView: some View { - VStack { - YearMonthView - .padding(.horizontal, 10) - .padding(.bottom, 16) - - HStack { - ForEach(Self.weekdaySymbols.indices, id: \.self) { symbol in - Text(Self.weekdaySymbols[symbol].uppercased()) - .foregroundColor(.black) - .frame(maxWidth: .infinity) - .font(.system(size: 14)) - } - }.padding(.bottom, 5) - } - } - - // MARK: - YYYY년 MM월 표시 - private var YearMonthView: some View { - HStack(alignment: .center, spacing: 10) { - // < 모양 버튼 - Button(action: {changeMonth(by: -1)}, label: { - Image(systemName: "chevron.left") - .font(.system(size: 16)) - .foregroundColor(canMoveToPreviousMonth() ? .black : . gray) // 이전 달로 이동할 수 있는 여부에 따라 배경색, 활성화 설정 - }) - .disabled(!canMoveToPreviousMonth()) - - Text(month, formatter: Self.calendarHeaderDateFormatter) - .font(.title2.bold()) // oooo년 oo월 텍스트 - - // > 모양 버튼 - Button(action: {changeMonth(by: 1)}, label: { - Image(systemName: "chevron.right") - .font(.system(size: 16)) - .foregroundColor(canMoveToNextMonth() ? .black : . gray) // // 다음 달로 이동할 수 있는 여부에 따라 배경색, 활성화 설정 - }) - .disabled(!canMoveToNextMonth()) - - Spacer() - } - } - - private var calendarGridView: some View { - let daysInMonth: Int = numberOfDays(in: month) // 해당 달의 일 수 - let firstWeekday: Int = firstWeekDayOfMonth(in: month) - 1 - let lastDayOfMonthBefore = numberOfDays(in: previousMonth()) - let numberOfRows = Int(ceil(Double(daysInMonth + firstWeekday) / 7.0)) // 해당 달이 몇주인지 - let visibleDaysOfNextMonth = numberOfRows * 7 - (daysInMonth + firstWeekday) - - return ScrollView{ LazyVGrid(columns: Array(repeating: GridItem(), count: 7), spacing: 4) { - ForEach(-firstWeekday ..< daysInMonth + visibleDaysOfNextMonth, id: \.self) { index in - Group { - if index > -1 && index < daysInMonth { // index : 0 ~ 해당 달의 일 수 - 1일 때 - let date = getDate(for: index) - - let schedules: [Schedule] = scheduleArray.filter { - $0.isSameDate(inDate: date) - } - - let day = Calendar.current.component(.day, from: date) // oo(일) - let clicked = clickedCurrentMonthDates == date - let isToday = date.formattedCalendarDayDate == today.formattedCalendarDayDate - - CellView(day: day, clicked: clicked, isToday: isToday, daySchedules: schedules) - } - else if let prevMonthDate = Calendar.current.date(byAdding: .day, value: index + lastDayOfMonthBefore, to: previousMonth()) { - let schedules: [Schedule] = scheduleArray.filter { - $0.isSameDate(inDate: prevMonthDate) - } - - let day = Calendar.current.component(.day, from: prevMonthDate) - - CellView(day: day, isCurrentMonthDay: false, daySchedules: schedules) - } - } - .padding(15) - .onTapGesture { - if 0 <= index && index < daysInMonth { - let date = getDate(for: index) - clickedCurrentMonthDates = date - } - } - } - }.padding(.horizontal, 8) - } - } - - struct CellView: View { - private var day: Int - private var clicked: Bool - private var isToday: Bool - private var isCurrentMonthDay: Bool - private var textColor: Color { - if clicked { - return Color.white - } else if isToday{ - return Color.mintColor - } else { - return Color.gray - } - } - private var backgroundColor: Color { - if clicked { - return Color.mint - } else if isToday { - return Color.lightGray - } else { - return Color.white - } - } - @State - var daySchedules: [Schedule] - - fileprivate init( // 동일한 소스 파일에서만 접근 가능 - day: Int, - clicked: Bool = false, - isToday: Bool = false, - isCurrentMonthDay: Bool = true, - daySchedules: [Schedule] = [] - ) { - self.day = day - self.clicked = clicked - self.isToday = isToday - self.isCurrentMonthDay = isCurrentMonthDay - self.daySchedules = daySchedules - } - - - - internal var body: some View { - VStack(spacing:-4) { - Circle() - .fill(backgroundColor) - .overlay(Text(String(day))).font(.system(size: 14)) // oo일 텍스트 - .foregroundColor(textColor) - .frame(width: 40, height: 40) - .padding(.vertical, 0) - - - //Spacer() - - } - .frame(width: 40,height: 40) - .background(clicked ? Color.lightMint : Color.clear) - - - - - } - } - -} - -private extension PickDateView { - var today: Date { - let now = Date() - let components = Calendar.current.dateComponents([.year, .month, .day], from: now) // 현재 시간을 년도, 월, 일 형식의 날짜로 - return Calendar.current.date(from: components)! - } - - // oooo년 oo월로 바꿔줄 포매터 - static let calendarHeaderDateFormatter: DateFormatter = { - let formatter = DateFormatter() - formatter.dateFormat = "YYYY년 MM월" - return formatter - }() - - // ["일", "월", "화", "수", "목", "금", "토"] - static let weekdaySymbols: [String] = Calendar.current.shortWeekdaySymbols -} - -private extension PickDateView { - // 특정 해당 날짜 (firstDayOfMonth = oooo년 oo월 1일 or 현재 날짜) - func getDate(for index: Int) -> Date { // oo일 - let calendar = Calendar.current - guard let firstDayOfMonth = calendar.date( - from: DateComponents( - year: calendar.component(.year, from: month), - month: calendar.component(.month, from: month), - day: 1 - ) - ) else { - return Date() - } - - var dateComponents = DateComponents() - dateComponents.day = index - - let timeZone = TimeZone.current - let offset = Double(timeZone.secondsFromGMT(for: firstDayOfMonth)) - dateComponents.second = Int(offset) - - // 특정 해당 oooo년 oo월 1일에서 index일 만큼 더한 날짜 구하기 - let date = calendar.date(byAdding: dateComponents, to: firstDayOfMonth) ?? Date() - - return date - } - - // 해당 월에 존재하는 일자 수 - func numberOfDays(in date: Date) -> Int { - return Calendar.current.range(of: .day, in: .month, for: date)?.count ?? 0 - } - - // 해당 월의 첫 날짜가 갖는 해당 주의 몇번째 요일 - // 특정 날짜를 입력으로 받아 그 달의 첫째 날의 요일을 정수로 반환 - func firstWeekDayOfMonth(in date: Date) -> Int { - let components = Calendar.current.dateComponents([.year,.month], from: date) - // 자동으로 월의 1일로 설정됨 - let firstDayOfMonth = Calendar.current.date(from: components)! - - // 일요일부터 1, ~.. 토요일은 7 - return Calendar.current.component(.weekday, from: firstDayOfMonth) - } - - // 이전 월 마지막 일자 - func previousMonth() -> Date { - let components = Calendar.current.dateComponents([.year, .month], from: month) - - // 해당 월의 1일 - let firstDayOfMoth = Calendar.current.date(from: components)! - let previousMonth = Calendar.current.date(byAdding: .month, value: -1, to: firstDayOfMoth)! - - return previousMonth - } - - // 월 변경 - func changeMonth(by value: Int) { - self.month = adjustedMonth(by: value) - } - - // 이전 월로 이동 가능한지 확인 - func canMoveToPreviousMonth() -> Bool { - let currentDate = Date() - let calendar = Calendar.current - // 현재 달의 -3달 - let targetDate = calendar.date(byAdding: .month, value: -3, to: currentDate) ?? currentDate - - // 변경하려는 달이 현재 달의 -3달보다 이전일 경우 이동 불가능 - if adjustedMonth(by: -1) < targetDate { - return false - } - return true - } - - // 다음 월로 이동 가능한지 확인 - func canMoveToNextMonth() -> Bool { - let currentDate = Date() - let calendar = Calendar.current - // 현재 달의 +3달 - let targetDate = calendar.date(byAdding: .month, value: 3, to: currentDate) ?? currentDate - - // 변경하려는 달이 현재 달의 +3달보다 이전일 경우 이동 불가능 - if adjustedMonth(by: 1) > targetDate { - return false - } - return true - } - - // 변경하려는 월 반환 - func adjustedMonth(by value: Int) -> Date { - if let newMonth = Calendar.current.date(byAdding: .month, value: value, to: month) { - return newMonth - } - return month - } -} -struct PickDateView_Previews: PreviewProvider { - static var previews: some View { - PickDateView() - } -} diff --git a/ToMeetToMe/ToMeetToMe/Other/Group/SetPromiseInfoView.swift b/ToMeetToMe/ToMeetToMe/Other/Group/SetPromiseInfoView.swift deleted file mode 100644 index 3545aaf..0000000 --- a/ToMeetToMe/ToMeetToMe/Other/Group/SetPromiseInfoView.swift +++ /dev/null @@ -1,120 +0,0 @@ -// -// PromiseInfoView.swift -// ToMeetToMe -// -// Created by 이자민 on 2023/11/26. -// - -import SwiftUI - -struct SetPromiseInfoView: View { - @State private var promiseTime: String = "" - - var body: some View { - VStack(alignment: .leading) { - Text("약속 소요시간을 \n선택해주세요 :)") - .padding(.top, 33) - - HStack() { - TextField( - "", - text: $promiseTime - - ) - .padding() - .frame(width: 112) - .overlay( - RoundedRectangle(cornerRadius: 8) - .stroke(Color.mint, lineWidth: 1) - ) - - Text("시간") - - Spacer() - } - - Text("선호 요일을 \n선택해주세요 :)") - .padding(.top, 52) - - HStack() { - Button(action: { - print("평일 선택") - }, label: { - Text("평일") - .fontWeight(.bold) - .foregroundColor(Color.black) - .padding(EdgeInsets(top: 23, leading: 40, bottom: 23, trailing: 40)) - .background(Color.lightGray) - .cornerRadius(8) - - }) - - Button(action: { - print("평일 선택") - }, label: { - Text("주말") - .fontWeight(.bold) - .foregroundColor(Color.white) - .padding(EdgeInsets(top: 23, leading: 40, bottom: 23, trailing: 40)) - .background(Color.primaryColor) - .cornerRadius(8) - - }) - - Button(action: { - print("평일 선택") - }, label: { - Text("선택") - .fontWeight(.bold) - .foregroundColor(Color.black) - .cornerRadius(8) - .padding(EdgeInsets(top: 23, leading: 40, bottom: 23, trailing: 40)) - - .background(Color.white) - .overlay( - RoundedRectangle(cornerRadius: 8) - .stroke(Color.gray, lineWidth: 2) - ) - - - - - }) - .cornerRadius(8) - - - - - - - - } - - Text("약속 장소를\n적어주세요 :)") - .padding(.top, 52) - - TextField( - "", - text: $promiseTime - - ) - .padding() - .overlay( - RoundedRectangle(cornerRadius: 8) - .stroke(Color.gray, lineWidth: 1) - ) - - Spacer() - } - .padding(.horizontal, 24) - - } - -} - - -struct SetPromiseInfoView_Previews: PreviewProvider { - static var previews: some View { - SetPromiseInfoView() - } -} diff --git a/ToMeetToMe/ToMeetToMe/Sources/Util/Extensions/PhotoPicker.swift b/ToMeetToMe/ToMeetToMe/Sources/Util/Extensions/PhotoPicker.swift new file mode 100644 index 0000000..b31211a --- /dev/null +++ b/ToMeetToMe/ToMeetToMe/Sources/Util/Extensions/PhotoPicker.swift @@ -0,0 +1,33 @@ +// +// PhotoPicker.swift +// ToMeetToMe +// +// Created by 이자민 on 12/19/23. +// + +import SwiftUI +import PhotosUI + +@MainActor +final class PhotoPicker: ObservableObject { + @Published private(set) var selectedImage: UIImage? = UIImage(named: "1") + @Published var imageSelection: PhotosPickerItem? = nil { + didSet { + setImage(from: imageSelection) + } + } + + private func setImage(from selection: PhotosPickerItem?) { + guard let selection = selection else { return } + + Task { + if let data = try? await selection.loadTransferable(type: Data.self) { + if let uiImage = UIImage(data: data) { + selectedImage = uiImage + return + } + } + } + } +} + diff --git a/ToMeetToMe/ToMeetToMe/Sources/View/MyProfile/SettingProfileView.swift b/ToMeetToMe/ToMeetToMe/Sources/View/MyProfile/SettingProfileView.swift index b6a8a43..9b00b22 100644 --- a/ToMeetToMe/ToMeetToMe/Sources/View/MyProfile/SettingProfileView.swift +++ b/ToMeetToMe/ToMeetToMe/Sources/View/MyProfile/SettingProfileView.swift @@ -9,32 +9,9 @@ import SwiftUI import PhotosUI -@MainActor -final class PhotoPickerViewModel: ObservableObject{ - @Published private(set) var selectedImage: UIImage? = UIImage(named: "1") - @Published var imageSelection: PhotosPickerItem? = nil{ - didSet{ - setImage(from: imageSelection) - } - } - private func setImage(from selection : PhotosPickerItem?){ - guard let selection else {return} - - Task{ - if let data = try? await selection.loadTransferable(type: Data.self){ - if let uiImage = UIImage(data: data){ - selectedImage = uiImage - return - } - } - } - } - -} - struct SettingProfileView: View { @State private var Name:String = "이자민" - @StateObject private var viewModel = PhotoPickerViewModel() + @StateObject private var photoPicker = PhotoPicker() @@ -42,9 +19,9 @@ struct SettingProfileView: View { NavigationView{ VStack{ - PhotosPicker(selection: $viewModel.imageSelection, matching: .images){ + PhotosPicker(selection: $photoPicker.imageSelection, matching: .images){ ZStack(alignment:.bottomTrailing){ - if let image = viewModel.selectedImage{ + if let image = photoPicker.selectedImage{ Image(uiImage: image) .resizable() .frame(width:104, height: 104) @@ -73,7 +50,8 @@ struct SettingProfileView: View { Rectangle() .foregroundColor(.clear) - .frame(width: 345, height: 1) + .frame(height: 1) + .padding(EdgeInsets(top: 0, leading: 24, bottom: 0, trailing: 24)) .background(.black) Text("\(Name.count) / 20") diff --git a/ToMeetToMe/ToMeetToMe/Sources/View/Promise/AddGroup/SettingGroupView.swift b/ToMeetToMe/ToMeetToMe/Sources/View/Promise/AddGroup/SettingGroupView.swift index a99e4f4..2dc1965 100644 --- a/ToMeetToMe/ToMeetToMe/Sources/View/Promise/AddGroup/SettingGroupView.swift +++ b/ToMeetToMe/ToMeetToMe/Sources/View/Promise/AddGroup/SettingGroupView.swift @@ -6,45 +6,53 @@ // import SwiftUI +import PhotosUI struct SettingGroupView: View { @State private var inputGroupName:String = "" + @StateObject private var photoPicker = PhotoPicker() var body: some View { NavigationView{ VStack{ - ZStack(alignment:.bottomTrailing){ - Image("1") - .resizable() - .frame(width:104, height: 104) - .cornerRadius(15) - Circle() - .frame(width:24, height: 24) - .foregroundColor(Color.gray) - .overlay( - Image(systemName: "camera") - .font(.system(size: 12)) - .foregroundColor(Color.white) - ) - .offset(x: 5, y: 5) + PhotosPicker(selection: $photoPicker.imageSelection, matching: .images){ + ZStack(alignment:.bottomTrailing){ + if let image = photoPicker.selectedImage{ + Image(uiImage: image) + .resizable() + .frame(width:104, height: 104) + .cornerRadius(15) + Circle() + .frame(width:24, height: 24) + .foregroundColor(Color.gray) + .overlay( + Image(systemName: "camera") + .font(.system(size: 12)) + .foregroundColor(Color.white) + ) + .offset(x: 5, y: 5) + } + + } } .padding(.top, 50) TextField("그룹이름은 무엇으로 할까요?",text: $inputGroupName) .padding(.top, 50) -// .padding(.leading, 24) + // .padding(.leading, 24) Rectangle() - .foregroundColor(.clear) - .frame(width: 345, height: 1) - .background(.black) + .foregroundColor(.clear) + .frame(height: 1) + .padding(EdgeInsets(top: 0, leading: 24, bottom: 0, trailing: 24)) + .background(.black) Text("ex) 건축학개론 팀플 / 프로미초 34기 졸업생") .font(Font.custom("Pretendard", size: 12)) .foregroundColor(Color.gray) .frame(maxWidth: .infinity, alignment: .leading) // 좌측 정렬 - //.padding(.leading, 24) - + //.padding(.leading, 24) + Spacer() } diff --git a/ToMeetToMe/ToMeetToMe/Sources/View/Promise/Group/PickPromiseDateView.swift b/ToMeetToMe/ToMeetToMe/Sources/View/Promise/Group/PickPromiseDateView.swift new file mode 100644 index 0000000..938e2cb --- /dev/null +++ b/ToMeetToMe/ToMeetToMe/Sources/View/Promise/Group/PickPromiseDateView.swift @@ -0,0 +1,74 @@ +// +// PickDateView.swift +// ToMeetToMe +// +// Created by 이자민 on 2023/11/05. +// + +import SwiftUI + +struct PickPromiseDateView: View { + @State private var date = Date() + let dateRange: ClosedRange = { + let calendar = Calendar.current + let startComponents = DateComponents(hour: 22, minute: 59, second: 59) + let endComponents = DateComponents(hour: 23, minute: 00, second: 00) + return calendar.date(from:startComponents)! + ... + calendar.date(from:endComponents)! + }() + + @State private var vibrateOnRing = true + + var body: some View { + + + NavigationView{ + + VStack(){ + Text("약속을 생성할 기간을\n선택해주세요 :)") + .font(Font.custom("Pretendard", size: 16)) + .foregroundColor(Color.black) + .frame(maxWidth: .infinity, alignment: .leading) // 좌측 정렬 + + Spacer() + + Toggle("하루종일", isOn: $vibrateOnRing) + .toggleStyle(SwitchToggleStyle(tint: Color.primaryColor)) + .frame(maxWidth: .infinity, alignment: .topLeading) + .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 220)) + + + if !vibrateOnRing { // Toggle이 true일 때만 DatePicker를 표시 + Text("약속 시간대를 선택해주세요 !") + .font(Font.custom("Pretendard", size: 16)) + .foregroundColor(Color.black) + .frame(maxWidth: .infinity, alignment: .leading) + + HStack { + DatePicker("", selection: $date, in: dateRange, displayedComponents: [.hourAndMinute]) + DatePicker("", selection: $date, in: dateRange, displayedComponents: [.hourAndMinute]) + .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 140)) + Spacer() + } + } + + + + } + .padding(.horizontal, 024) + .navigationTitle("약속 생성") + .navigationBarTitleDisplayMode(.inline) + .navigationBarItems(trailing: Text("확인")) + + } + + } + + +} +struct PickPromiseDateView_Previews: PreviewProvider { + static var previews: some View { + PickPromiseDateView() + } +} diff --git a/ToMeetToMe/ToMeetToMe/Sources/View/Promise/Group/SettingPromiseInfoView.swift b/ToMeetToMe/ToMeetToMe/Sources/View/Promise/Group/SettingPromiseInfoView.swift new file mode 100644 index 0000000..cd8dc6e --- /dev/null +++ b/ToMeetToMe/ToMeetToMe/Sources/View/Promise/Group/SettingPromiseInfoView.swift @@ -0,0 +1,113 @@ +// +// PromiseInfoView.swift +// ToMeetToMe +// +// Created by 이자민 on 2023/11/26. +// + +import SwiftUI + +struct SettingPromiseInfoView: View { + @State private var selectedDuration: String = "" + @State private var inputDuration: String = "" + @State private var selectedWeekdays: [String] = [] + @State private var promisePlace: String = "" + + let durations = ["1시간 이내", "1~3 시간", "3~6 시간"] + let weekdays = ["월", "화", "수", "목", "금", "토", "일"] + + var body: some View { + VStack(alignment: .leading) { + Text("약속 소요시간을 \n선택해주세요 :)") + .padding(.top, 33) + + HStack() { + ForEach(durations, id: \.self) { duration in + Button(action: { + print("\(duration) 선택") + selectedDuration = duration + }, label: { + Text(duration) + .fontWeight(.semibold) + .font(Font.system(size: 14)) + .foregroundColor(selectedDuration == duration ? .white : .black) + .frame(width: 82, height: 60) // 버튼의 가로, 세로 크기 지정 + .background(selectedDuration == duration ? Color.mint : Color.lightGray) + .cornerRadius(8) + + }) + + } + TextField( + "직접입력", + text: $inputDuration + + ) + .padding() + .frame(width: 82, height: 60) + .multilineTextAlignment(.center) + .font(Font.system(size: 14)) + .onTapGesture { + selectedDuration = inputDuration // 텍스트 필드를 탭하면 선택된 버튼을 취소 + } + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.gray, lineWidth: 1) + ) + } + + Text("선호 요일을 \n선택해주세요 :)") + .padding(.top, 52) + + HStack() { + ForEach(weekdays, id: \.self) { day in + Button(action: { + print("\(day) 선택") + + if selectedWeekdays.contains(day) { + selectedWeekdays.removeAll { $0 == day } + } else { + selectedWeekdays.append(day) + } + print("\(selectedWeekdays)") + }, label: { + Text(day) + .fontWeight(.semibold) + .foregroundColor(selectedWeekdays.contains(day) ? .white : .black) + .frame(width: 42, height: 54) // 버튼의 가로, 세로 크기 지정 + .background(selectedWeekdays.contains(day) ? Color.mint : Color.lightGray) + .cornerRadius(8) + + }) + + } + } + Text("약속 장소를\n적어주세요 :)") + .padding(.top, 52) + + TextField( + "구체적인 약속장소를 입력해주세요.", + text: $promisePlace + + ) + .padding() + .font(Font.system(size: 14)) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.gray, lineWidth: 1) + ) + + Spacer() + } + .padding(.horizontal, 24) + + } + +} + + +struct SettingPromiseInfoView_Previews: PreviewProvider { + static var previews: some View { + SettingPromiseInfoView() + } +}