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

View File

@ -10,42 +10,53 @@ import SwiftUI
struct CustomTabBarView: View { struct CustomTabBarView: View {
var isActiveForeground: Color = .white var isActiveForeground: Color = .white
var isActiveBackground: Color = Color("blueColor") var isActiveBackground: Color = Color("blueColor")
@Binding var isActiveTabBar: TabModel @Binding var selectedTab: TabModel
// @NameSpace private var animation // @NameSpace private var animation
var body: some View { var body: some View {
HStack(spacing: 0) { VStack {
ForEach(TabModel.allCases, id: \.rawValue) { tab in Spacer()
Button { HStack(spacing: 0) {
isActiveTabBar = tab content
} label: { }
HStack(spacing: 5) { .animation(.smooth(duration: 0.3, extraBounce: 0), value: selectedTab)
Image(systemName: tab.rawValue) .padding(6)
.font(.title) .background(.clear)
.frame(width: 80, height: 35) .mask(RoundedRectangle(cornerRadius: 24, style: .continuous))
}
.foregroundStyle(isActiveTabBar == tab ? isActiveForeground : Color("blueColor")) // .background(
.padding(.vertical, 7) // background
.padding(.leading, 15) // .shadow(.drop(color: .black.opacity(0.08), radius: 5, x: 5, y: 5))
.padding(.trailing, 15) // .shadow(.drop(color: .black.opacity(0.08), radius: 5, x: 5, y: -5)),
.background { // in: .capsule
if isActiveTabBar == tab { // )
Capsule() }
.fill(isActiveBackground) .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) // .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 { struct ScheduleView: View {
@State private var searchText: String = "" @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 { var body: some View {
VStack { VStack {
SearchBarView(text: $searchText) SearchBarView(text: $searchText)
HeaderView()
Spacer() 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 import SwiftUI
struct SearchBarView: View { struct SearchBarView: View {
@ -13,34 +6,41 @@ struct SearchBarView: View {
var body: some View { var body: some View {
HStack { HStack {
TextField("Ввести номер группы", text: $text) HStack {
.padding(7) Image(systemName: "magnifyingglass")
.padding(.horizontal, 25) .foregroundColor(Color.gray)
.background(.white) .padding(.leading, 10)
.cornerRadius(8) TextField("Ввести номер группы", text: $text)
.overlay( .disableAutocorrection(true)
HStack { .frame(width: 270, height: 45)
Image(systemName: "magnifyingglass") .overlay(
.foregroundColor(.gray) Group {
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) if isEditing {
.padding(.leading, 8) Button {
self.text = ""
if isEditing { self.isEditing = false
Button(action: { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
self.text = "" } label: {
self.isEditing = false Image(systemName: "xmark.circle.fill")
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) .padding(.trailing, 30)
}) { .offset(x: 10)
Image(systemName: "multiply.circle.fill") .foregroundColor(.gray)
.foregroundColor(.gray) }
.padding(.trailing, 8) }
} }, alignment: .trailing
} )
.onTapGesture {
self.isEditing = true
} }
) .onSubmit {
.onTapGesture { self.isEditing = false
self.isEditing = true }
} }
.background(
RoundedRectangle(cornerRadius: 10)
.fill(.white)
)
Spacer()
Button { Button {
} label: { } label: {
@ -54,8 +54,8 @@ struct SearchBarView: View {
.foregroundStyle(.white) .foregroundStyle(.white)
.scaledToFit() .scaledToFit()
.frame(width: 16) .frame(width: 16)
}
} }
}
} }
.padding(.horizontal) .padding(.horizontal)
} }