This commit is contained in:
Vladimir Dubovik 2024-11-14 19:50:14 +03:00
parent d3f448e288
commit b65b061d95
5 changed files with 186 additions and 74 deletions

View File

@ -8,20 +8,18 @@
import SwiftUI
struct ContentView: View {
@State private var isActiveTabBar: TabModel = .schedule
@State private var isTabBarHidden: Bool = false
@State private var selectedTab: TabModel = .schedule
var body: some View {
VStack {
TabView(selection: $isActiveTabBar) {
ZStack {
switch selectedTab {
case .schedule:
ScheduleView()
.tag(TabModel.schedule)
case .tasks:
Text("Tasks")
.tag(TabModel.tasks)
case .settings:
Text("Settings")
.tag(TabModel.settings)
}
CustomTabBarView(isActiveTabBar: $isActiveTabBar)
.padding(.bottom, 10)
CustomTabBarView(selectedTab: $selectedTab)
}
.background(.secondary.opacity(0.15))
}

View File

@ -10,42 +10,53 @@ import SwiftUI
struct CustomTabBarView: View {
var isActiveForeground: Color = .white
var isActiveBackground: Color = Color("blueColor")
@Binding var isActiveTabBar: TabModel
@Binding var selectedTab: TabModel
// @NameSpace private var animation
var body: some View {
HStack(spacing: 0) {
ForEach(TabModel.allCases, id: \.rawValue) { tab in
Button {
isActiveTabBar = tab
} label: {
HStack(spacing: 5) {
Image(systemName: tab.rawValue)
.font(.title)
.frame(width: 80, height: 35)
}
.foregroundStyle(isActiveTabBar == tab ? isActiveForeground : Color("blueColor"))
.padding(.vertical, 7)
.padding(.leading, 15)
.padding(.trailing, 15)
.background {
if isActiveTabBar == tab {
Capsule()
.fill(isActiveBackground)
VStack {
Spacer()
HStack(spacing: 0) {
content
}
.animation(.smooth(duration: 0.3, extraBounce: 0), value: selectedTab)
.padding(6)
.background(.clear)
.mask(RoundedRectangle(cornerRadius: 24, style: .continuous))
// .background(
// background
// .shadow(.drop(color: .black.opacity(0.08), radius: 5, x: 5, y: 5))
// .shadow(.drop(color: .black.opacity(0.08), radius: 5, x: 5, y: -5)),
// in: .capsule
// )
}
.ignoresSafeArea(.keyboard, edges: .bottom)
}
var content: some View {
ForEach(TabModel.allCases, id: \.rawValue) { tab in
Button {
selectedTab = tab
} label: {
VStack {
Image(systemName: tab.rawValue)
.font(.title)
.frame(width: 80, height: 35)
}
.foregroundStyle(selectedTab == tab ? isActiveForeground : Color("blueColor"))
.padding(.vertical, 7)
.padding(.leading, 15)
.padding(.trailing, 15)
.background {
if selectedTab == tab {
Capsule()
.fill(isActiveBackground)
// .matchedGeometryEffect(id: "ACTIVETAB", in: animation)
}
}
}
.buttonStyle(.plain)
}
.buttonStyle(.plain)
}
.padding(.horizontal, 5)
.animation(.smooth(duration: 0.3, extraBounce: 0), value: isActiveTabBar)
// .background(
// background
// .shadow(.drop(color: .black.opacity(0.08), radius: 5, x: 5, y: 5))
// .shadow(.drop(color: .black.opacity(0.08), radius: 5, x: 5, y: -5)),
// in: .capsule
// )
}
}

View File

@ -0,0 +1,43 @@
//
// Date+Extensions.swift
// Schedule ICTIS
//
// Created by G412 on 14.11.2024.
//
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)
}
func fetchWeek(_ date: Date = .init()) -> [WeekDay] {
let calendar = Calendar.current
let startOfDate = calendar.startOfDay(for: date)
var week: [WeekDay] = []
let weekForDate = calendar.dateInterval(of: .weekOfMonth, for: startOfDate)
guard let startOfWeek = weekForDate?.start else {
return []
}
(0..<7).forEach { index in
if let weekDay = calendar.date(byAdding: .day, value: index, to: startOfWeek) {
week.append(.init(date: weekDay))
}
}
return week
}
struct WeekDay: Identifiable {
var id: UUID = .init()
var date: Date
}
}

View File

@ -9,12 +9,72 @@ import SwiftUI
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
var body: some View {
VStack {
SearchBarView(text: $searchText)
HeaderView()
Spacer()
}
.background(.secondary.opacity(0.15))
.background(.secondary.opacity(0.1))
.onAppear(perform: {
if weekSlider.isEmpty {
let currentWeek = Date().fetchWeek()
weekSlider.append(currentWeek)
}
})
}
@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)
}
.font(.title.bold())
// Text(currentDate.formatted(date: .complete, time: .omitted))
// .font(.title.bold())
TabView(selection: $currentWeekIndex) {
ForEach(weekSlider.indices, id: \.self) { index in
let week = weekSlider[index]
WeekView(week)
.tag(index)
}
}
.tabViewStyle(.page(indexDisplayMode: .never))
.frame(height: 90)
}
}
@ViewBuilder
func WeekView(_ week: [Date.WeekDay]) -> some View {
HStack (spacing: 14) {
ForEach(week) { day in
VStack (spacing: 4) {
Text(day.date.format("E"))
.font(.callout)
.fontWeight(.medium)
.textScale(.secondary)
.padding(.top, 6)
.foregroundColor(.gray)
Text(day.date.format("dd"))
.font(.callout)
.fontWeight(.bold)
.textScale(.secondary)
.padding(.bottom, 6)
}
.frame(maxWidth: 40, maxHeight: 55, alignment: .center)
.background(Color.white)
.cornerRadius(10)
}
}
}
}

View File

@ -1,10 +1,3 @@
//
// SearchBarView.swift
// Schedule ICTIS
//
// Created by G412 on 13.11.2024.
//
import SwiftUI
struct SearchBarView: View {
@ -13,34 +6,41 @@ struct SearchBarView: View {
var body: some View {
HStack {
TextField("Ввести номер группы", text: $text)
.padding(7)
.padding(.horizontal, 25)
.background(.white)
.cornerRadius(8)
.overlay(
HStack {
Image(systemName: "magnifyingglass")
.foregroundColor(.gray)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.padding(.leading, 8)
if isEditing {
Button(action: {
self.text = ""
self.isEditing = false
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}) {
Image(systemName: "multiply.circle.fill")
.foregroundColor(.gray)
.padding(.trailing, 8)
}
}
HStack {
Image(systemName: "magnifyingglass")
.foregroundColor(Color.gray)
.padding(.leading, 10)
TextField("Ввести номер группы", text: $text)
.disableAutocorrection(true)
.frame(width: 270, height: 45)
.overlay(
Group {
if isEditing {
Button {
self.text = ""
self.isEditing = false
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
} label: {
Image(systemName: "xmark.circle.fill")
.padding(.trailing, 30)
.offset(x: 10)
.foregroundColor(.gray)
}
}
}, alignment: .trailing
)
.onTapGesture {
self.isEditing = true
}
)
.onTapGesture {
self.isEditing = true
}
.onSubmit {
self.isEditing = false
}
}
.background(
RoundedRectangle(cornerRadius: 10)
.fill(.white)
)
Spacer()
Button {
} label: {
@ -54,8 +54,8 @@ struct SearchBarView: View {
.foregroundStyle(.white)
.scaledToFit()
.frame(width: 16)
}
}
}
}
.padding(.horizontal)
}