From 3670a0b01fdf2168d46c6f5f592f17252b20a580 Mon Sep 17 00:00:00 2001 From: Vladimir Dubovik Date: Fri, 15 Nov 2024 18:36:51 +0300 Subject: [PATCH] q --- .../customGray1.colorset/Contents.json | 38 ++++++++ .../customGray2.colorset/Contents.json | 38 ++++++++ .../customGray3.colorset/Contents.json | 38 ++++++++ .../grayForDate.colorset/Contents.json | 38 ++++++++ Schedule ICTIS/ContentView.swift | 2 +- Schedule ICTIS/Helpers/Date+Extensions.swift | 42 ++++++++- Schedule ICTIS/Helpers/View+Extensions.swift | 14 +++ Schedule ICTIS/ScheduleView.swift | 88 ++++++++++++++----- Schedule ICTIS/SearchBarView.swift | 6 +- ...ustomTabBarView.swift => TabBarView.swift} | 10 +-- 10 files changed, 279 insertions(+), 35 deletions(-) create mode 100644 Schedule ICTIS/Assets.xcassets/customGray1.colorset/Contents.json create mode 100644 Schedule ICTIS/Assets.xcassets/customGray2.colorset/Contents.json create mode 100644 Schedule ICTIS/Assets.xcassets/customGray3.colorset/Contents.json create mode 100644 Schedule ICTIS/Assets.xcassets/grayForDate.colorset/Contents.json create mode 100644 Schedule ICTIS/Helpers/View+Extensions.swift rename Schedule ICTIS/{CustomTabBarView.swift => TabBarView.swift} (90%) diff --git a/Schedule ICTIS/Assets.xcassets/customGray1.colorset/Contents.json b/Schedule ICTIS/Assets.xcassets/customGray1.colorset/Contents.json new file mode 100644 index 0000000..ea75ab6 --- /dev/null +++ b/Schedule ICTIS/Assets.xcassets/customGray1.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD9", + "green" : "0xD9", + "red" : "0xD9" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD9", + "green" : "0xD9", + "red" : "0xD9" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Schedule ICTIS/Assets.xcassets/customGray2.colorset/Contents.json b/Schedule ICTIS/Assets.xcassets/customGray2.colorset/Contents.json new file mode 100644 index 0000000..80b1768 --- /dev/null +++ b/Schedule ICTIS/Assets.xcassets/customGray2.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x7D", + "green" : "0x7D", + "red" : "0x7D" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x7D", + "green" : "0x7D", + "red" : "0x7D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Schedule ICTIS/Assets.xcassets/customGray3.colorset/Contents.json b/Schedule ICTIS/Assets.xcassets/customGray3.colorset/Contents.json new file mode 100644 index 0000000..80b1768 --- /dev/null +++ b/Schedule ICTIS/Assets.xcassets/customGray3.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x7D", + "green" : "0x7D", + "red" : "0x7D" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x7D", + "green" : "0x7D", + "red" : "0x7D" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Schedule ICTIS/Assets.xcassets/grayForDate.colorset/Contents.json b/Schedule ICTIS/Assets.xcassets/grayForDate.colorset/Contents.json new file mode 100644 index 0000000..a039c0b --- /dev/null +++ b/Schedule ICTIS/Assets.xcassets/grayForDate.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x7A", + "green" : "0x7A", + "red" : "0x7A" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x7A", + "green" : "0x7A", + "red" : "0x7A" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Schedule ICTIS/ContentView.swift b/Schedule ICTIS/ContentView.swift index dc78bb7..35b11dd 100644 --- a/Schedule ICTIS/ContentView.swift +++ b/Schedule ICTIS/ContentView.swift @@ -19,7 +19,7 @@ struct ContentView: View { case .settings: Text("Settings") } - CustomTabBarView(selectedTab: $selectedTab) + TabBarView(selectedTab: $selectedTab) } .background(.secondary.opacity(0.15)) } diff --git a/Schedule ICTIS/Helpers/Date+Extensions.swift b/Schedule ICTIS/Helpers/Date+Extensions.swift index b08d964..6f7608b 100644 --- a/Schedule ICTIS/Helpers/Date+Extensions.swift +++ b/Schedule ICTIS/Helpers/Date+Extensions.swift @@ -10,12 +10,28 @@ import SwiftUI extension Date { func format(_ format: String, locale: Locale = Locale(identifier: "ru_RU")) -> String { - let formatter = DateFormatter() - formatter.dateFormat = format - formatter.locale = locale - return formatter.string(from: self) + let formatter = DateFormatter() + formatter.dateFormat = format + formatter.locale = locale + let formattedString = formatter.string(from: self) + + if format == "EEEE" { + return formattedString.prefix(1).capitalized + formattedString.dropFirst() + } + + return formattedString + } + + var isToday: Bool { + return Calendar.current.isDateInToday(self) } + private func isSameDate(_ date1: Date?, _ date2: Date?) -> Bool { + guard let date1 = date1, let date2 = date2 else { return false } + let calendar = Calendar.current + return calendar.isDate(date1, inSameDayAs: date2) + } + func fetchWeek(_ date: Date = .init()) -> [WeekDay] { let calendar = Calendar.current let startOfDate = calendar.startOfDay(for: date) @@ -36,6 +52,24 @@ extension Date { return week } + func createNextWeek() -> [WeekDay] { + let calendar = Calendar.current + let startOfLastDate = calendar.startOfDay(for: self) + guard let nextDate = calendar.date(byAdding: .day, value: 1, to: startOfLastDate) else { + return [] + } + return fetchWeek(nextDate) + } + + func createPrevioustWeek() -> [WeekDay] { + let calendar = Calendar.current + let startOfFirstDate = calendar.startOfDay(for: self) + guard let previousDate = calendar.date(byAdding: .day, value: -1, to: startOfFirstDate) else { + return [] + } + return fetchWeek(previousDate) + } + struct WeekDay: Identifiable { var id: UUID = .init() var date: Date diff --git a/Schedule ICTIS/Helpers/View+Extensions.swift b/Schedule ICTIS/Helpers/View+Extensions.swift new file mode 100644 index 0000000..6f15aae --- /dev/null +++ b/Schedule ICTIS/Helpers/View+Extensions.swift @@ -0,0 +1,14 @@ +// +// View+Extensions.swift +// Schedule ICTIS +// +// Created by G412 on 15.11.2024. +// + +import SwiftUI + +extension View { + func isSameDate(_ date1: Date, _ date2: Date) -> Bool { + return Calendar.current.isDate(date1, inSameDayAs: date2) + } +} diff --git a/Schedule ICTIS/ScheduleView.swift b/Schedule ICTIS/ScheduleView.swift index ca7ce55..ebcbaa8 100644 --- a/Schedule ICTIS/ScheduleView.swift +++ b/Schedule ICTIS/ScheduleView.swift @@ -11,7 +11,7 @@ struct ScheduleView: View { @State private var searchText: String = "" @State private var currentDate: Date = .init() @State private var weekSlider: [[Date.WeekDay]] = [] - @State private var currentWeekIndex: Int = 0 + @State private var currentWeekIndex: Int = 1 var body: some View { VStack { SearchBarView(text: $searchText) @@ -22,7 +22,16 @@ struct ScheduleView: View { .onAppear(perform: { if weekSlider.isEmpty { let currentWeek = Date().fetchWeek() + + if let firstDate = currentWeek.first?.date { + weekSlider.append(firstDate.createPrevioustWeek()) + } + weekSlider.append(currentWeek) + + if let lastDate = currentWeek.last?.date { + weekSlider.append(lastDate.createNextWeek()) + } } }) @@ -31,15 +40,28 @@ struct ScheduleView: View { @ViewBuilder func HeaderView() -> some View { VStack (alignment: .leading, spacing: 6) { - HStack (spacing: 5) { - Text(currentDate.format("YYYY")) - .foregroundStyle(.blue) - Text(currentDate.format("MMMM")) - .foregroundStyle(.blue) + HStack { + VStack (alignment: .leading, spacing: 0) { + Text(currentDate.format("EEEE")) + .font(.system(size: 40, weight: .semibold)) + .foregroundStyle(.black) +// .background(Color.green) + HStack (spacing: 5) { + Text(currentDate.format("dd")) + .font(.system(size: 20, weight: .bold)) + .foregroundStyle(Color("grayForDate")) + Text(currentDate.format("MMMM")) + .font(.system(size: 20, weight: .bold)) + .foregroundStyle(Color("grayForDate")) + } +// .background(.red) + } + .padding(.top, 8) + .padding(.leading, 20) +// .background(Color.brown) + Spacer() } - .font(.title.bold()) -// Text(currentDate.formatted(date: .complete, time: .omitted)) -// .font(.title.bold()) + .frame(maxWidth: .infinity) TabView(selection: $currentWeekIndex) { ForEach(weekSlider.indices, id: \.self) { index in @@ -55,24 +77,46 @@ struct ScheduleView: View { @ViewBuilder func WeekView(_ week: [Date.WeekDay]) -> some View { - HStack (spacing: 14) { + HStack (spacing: 10) { ForEach(week) { day in - VStack (spacing: 4) { + VStack (spacing: 1) { Text(day.date.format("E")) - .font(.callout) - .fontWeight(.medium) - .textScale(.secondary) - .padding(.top, 6) + .font(.system(size: 15, weight: .semibold)) + .foregroundColor(day.date.format("E") == "Вс" ? Color(.red) : isSameDate(day.date, currentDate) ? Color("customGray1") : Color("customGray3")) + .padding(.top, 13) .foregroundColor(.gray) Text(day.date.format("dd")) - .font(.callout) - .fontWeight(.bold) - .textScale(.secondary) - .padding(.bottom, 6) + .font(.system(size: 15, weight: .bold)) + .foregroundStyle(isSameDate(day.date, currentDate) ? .white : .black) + .padding(.bottom, 13) + } + .frame(width: 43, height: 55, alignment: .center) + .background( content: { + Group { + if isSameDate(day.date, currentDate) { + Color("blueColor") + } + else { + Color(.white) + } + if day.date.isToday && isSameDate(day.date, currentDate) { + Color("blueColor") + } + } + } + ) + .overlay ( + Group { + if day.date.isToday && !isSameDate(day.date, currentDate) { + RoundedRectangle(cornerRadius: 15) + .stroke(Color("blueColor"), lineWidth: 2) + } + } + ) + .cornerRadius(15) + .onTapGesture { + currentDate = day.date } - .frame(maxWidth: 40, maxHeight: 55, alignment: .center) - .background(Color.white) - .cornerRadius(10) } } } diff --git a/Schedule ICTIS/SearchBarView.swift b/Schedule ICTIS/SearchBarView.swift index aacf58e..4f8da9a 100644 --- a/Schedule ICTIS/SearchBarView.swift +++ b/Schedule ICTIS/SearchBarView.swift @@ -10,7 +10,7 @@ struct SearchBarView: View { Image(systemName: "magnifyingglass") .foregroundColor(Color.gray) .padding(.leading, 10) - TextField("Ввести номер группы", text: $text) + TextField("Поиск группы", text: $text) .disableAutocorrection(true) .frame(width: 270, height: 45) .overlay( @@ -22,7 +22,7 @@ struct SearchBarView: View { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) } label: { Image(systemName: "xmark.circle.fill") - .padding(.trailing, 30) + .padding(.trailing, 20) .offset(x: 10) .foregroundColor(.gray) } @@ -46,7 +46,7 @@ struct SearchBarView: View { } label: { ZStack { Rectangle() - .frame(width: 35, height: 35) + .frame(width: 40, height: 40) .foregroundStyle(Color("blueColor")) .cornerRadius(10) Image(systemName: "plus") diff --git a/Schedule ICTIS/CustomTabBarView.swift b/Schedule ICTIS/TabBarView.swift similarity index 90% rename from Schedule ICTIS/CustomTabBarView.swift rename to Schedule ICTIS/TabBarView.swift index 9326ef9..5dd17f6 100644 --- a/Schedule ICTIS/CustomTabBarView.swift +++ b/Schedule ICTIS/TabBarView.swift @@ -7,7 +7,7 @@ import SwiftUI -struct CustomTabBarView: View { +struct TabBarView: View { var isActiveForeground: Color = .white var isActiveBackground: Color = Color("blueColor") @Binding var selectedTab: TabModel @@ -20,7 +20,7 @@ struct CustomTabBarView: View { } .animation(.smooth(duration: 0.3, extraBounce: 0), value: selectedTab) .padding(6) - .background(.clear) + .background(.white) .mask(RoundedRectangle(cornerRadius: 24, style: .continuous)) // .background( @@ -41,12 +41,12 @@ struct CustomTabBarView: View { VStack { Image(systemName: tab.rawValue) .font(.title) - .frame(width: 80, height: 35) + .frame(width: 70, height: 30) } .foregroundStyle(selectedTab == tab ? isActiveForeground : Color("blueColor")) .padding(.vertical, 7) - .padding(.leading, 15) - .padding(.trailing, 15) + .padding(.leading, 13) + .padding(.trailing, 13) .background { if selectedTab == tab { Capsule()