diff --git a/FreeSubject.xcodeproj/project.pbxproj b/FreeSubject.xcodeproj/project.pbxproj index ed4688f..def66a8 100644 --- a/FreeSubject.xcodeproj/project.pbxproj +++ b/FreeSubject.xcodeproj/project.pbxproj @@ -11,22 +11,34 @@ 690DDC9A28B7D5C100C278E1 /* Then in Frameworks */ = {isa = PBXBuildFile; productRef = 690DDC9928B7D5C100C278E1 /* Then */; }; 690DDC9D28B7D5FB00C278E1 /* Realm in Frameworks */ = {isa = PBXBuildFile; productRef = 690DDC9C28B7D5FB00C278E1 /* Realm */; }; 690DDC9F28B7D5FB00C278E1 /* RealmSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 690DDC9E28B7D5FB00C278E1 /* RealmSwift */; }; + 911A171B28C1ABDB009B4376 /* CustomModalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 911A171A28C1ABDB009B4376 /* CustomModalViewController.swift */; }; + 914E2F5F28C4D2A9009242A1 /* TemporaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 914E2F5E28C4D2A9009242A1 /* TemporaryViewController.swift */; }; + 9191481A28BB52710006BFC7 /* CustomTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9191481928BB52710006BFC7 /* CustomTabBarController.swift */; }; + 91B45FCB28C098B200BFF72D /* Charts in Frameworks */ = {isa = PBXBuildFile; productRef = 91B45FCA28C098B200BFF72D /* Charts */; }; + 91BED6D528C86BAD00837AFF /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 91BED6D428C86BAD00837AFF /* Launch Screen.storyboard */; }; + 91BED6DB28C880ED00837AFF /* LineChartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91BED6DA28C880ED00837AFF /* LineChartViewController.swift */; }; + 91BED6E128C8901B00837AFF /* LineChartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91BED6E028C8901B00837AFF /* LineChartView.swift */; }; + 91D85F1728BA4C9B009AAFDA /* CalendarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91D85F1628BA4C9A009AAFDA /* CalendarViewController.swift */; }; + 91D85F1A28BA7993009AAFDA /* FSCalendar in Frameworks */ = {isa = PBXBuildFile; productRef = 91D85F1928BA7993009AAFDA /* FSCalendar */; }; + 91F040D828C646FA0049CAA7 /* Day.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91F040D728C646FA0049CAA7 /* Day.swift */; }; C35EB13728B3598A006AFA0A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35EB13628B3598A006AFA0A /* AppDelegate.swift */; }; C35EB13928B3598A006AFA0A /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35EB13828B3598A006AFA0A /* SceneDelegate.swift */; }; - C35EB13B28B3598A006AFA0A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35EB13A28B3598A006AFA0A /* ViewController.swift */; }; - C35EB13E28B3598A006AFA0A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C35EB13C28B3598A006AFA0A /* Main.storyboard */; }; C35EB14028B3598A006AFA0A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C35EB13F28B3598A006AFA0A /* Assets.xcassets */; }; - C35EB14328B3598A006AFA0A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C35EB14128B3598A006AFA0A /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 911A171A28C1ABDB009B4376 /* CustomModalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomModalViewController.swift; sourceTree = ""; }; + 914E2F5E28C4D2A9009242A1 /* TemporaryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemporaryViewController.swift; sourceTree = ""; }; + 9191481928BB52710006BFC7 /* CustomTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTabBarController.swift; sourceTree = ""; }; + 91BED6D428C86BAD00837AFF /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; + 91BED6DA28C880ED00837AFF /* LineChartViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineChartViewController.swift; sourceTree = ""; }; + 91BED6E028C8901B00837AFF /* LineChartView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineChartView.swift; sourceTree = ""; }; + 91D85F1628BA4C9A009AAFDA /* CalendarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarViewController.swift; sourceTree = ""; }; + 91F040D728C646FA0049CAA7 /* Day.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Day.swift; sourceTree = ""; }; C35EB13328B3598A006AFA0A /* FreeSubject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FreeSubject.app; sourceTree = BUILT_PRODUCTS_DIR; }; C35EB13628B3598A006AFA0A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; C35EB13828B3598A006AFA0A /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - C35EB13A28B3598A006AFA0A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - C35EB13D28B3598A006AFA0A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; C35EB13F28B3598A006AFA0A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - C35EB14228B3598A006AFA0A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; C35EB14428B3598A006AFA0A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ @@ -36,8 +48,10 @@ buildActionMask = 2147483647; files = ( 690DDC9F28B7D5FB00C278E1 /* RealmSwift in Frameworks */, + 91B45FCB28C098B200BFF72D /* Charts in Frameworks */, 690DDC9D28B7D5FB00C278E1 /* Realm in Frameworks */, 690DDC9728B7C8EC00C278E1 /* SnapKit in Frameworks */, + 91D85F1A28BA7993009AAFDA /* FSCalendar in Frameworks */, 690DDC9A28B7D5C100C278E1 /* Then in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -66,11 +80,16 @@ children = ( C35EB13628B3598A006AFA0A /* AppDelegate.swift */, C35EB13828B3598A006AFA0A /* SceneDelegate.swift */, - C35EB13A28B3598A006AFA0A /* ViewController.swift */, - C35EB13C28B3598A006AFA0A /* Main.storyboard */, C35EB13F28B3598A006AFA0A /* Assets.xcassets */, - C35EB14128B3598A006AFA0A /* LaunchScreen.storyboard */, C35EB14428B3598A006AFA0A /* Info.plist */, + 91D85F1628BA4C9A009AAFDA /* CalendarViewController.swift */, + 9191481928BB52710006BFC7 /* CustomTabBarController.swift */, + 911A171A28C1ABDB009B4376 /* CustomModalViewController.swift */, + 914E2F5E28C4D2A9009242A1 /* TemporaryViewController.swift */, + 91F040D728C646FA0049CAA7 /* Day.swift */, + 91BED6D428C86BAD00837AFF /* Launch Screen.storyboard */, + 91BED6DA28C880ED00837AFF /* LineChartViewController.swift */, + 91BED6E028C8901B00837AFF /* LineChartView.swift */, ); path = FreeSubject; sourceTree = ""; @@ -96,6 +115,8 @@ 690DDC9928B7D5C100C278E1 /* Then */, 690DDC9C28B7D5FB00C278E1 /* Realm */, 690DDC9E28B7D5FB00C278E1 /* RealmSwift */, + 91D85F1928BA7993009AAFDA /* FSCalendar */, + 91B45FCA28C098B200BFF72D /* Charts */, ); productName = FreeSubject; productReference = C35EB13328B3598A006AFA0A /* FreeSubject.app */; @@ -129,6 +150,8 @@ 690DDC9528B7C8EC00C278E1 /* XCRemoteSwiftPackageReference "SnapKit" */, 690DDC9828B7D5C100C278E1 /* XCRemoteSwiftPackageReference "Then" */, 690DDC9B28B7D5FB00C278E1 /* XCRemoteSwiftPackageReference "realm-cocoa" */, + 91D85F1828BA7993009AAFDA /* XCRemoteSwiftPackageReference "FSCalendar" */, + 91B45FC928C098B200BFF72D /* XCRemoteSwiftPackageReference "Charts" */, ); productRefGroup = C35EB13428B3598A006AFA0A /* Products */; projectDirPath = ""; @@ -144,9 +167,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - C35EB14328B3598A006AFA0A /* LaunchScreen.storyboard in Resources */, + 91BED6D528C86BAD00837AFF /* Launch Screen.storyboard in Resources */, C35EB14028B3598A006AFA0A /* Assets.xcassets in Resources */, - C35EB13E28B3598A006AFA0A /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -157,33 +179,20 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C35EB13B28B3598A006AFA0A /* ViewController.swift in Sources */, + 91D85F1728BA4C9B009AAFDA /* CalendarViewController.swift in Sources */, + 91BED6DB28C880ED00837AFF /* LineChartViewController.swift in Sources */, + 9191481A28BB52710006BFC7 /* CustomTabBarController.swift in Sources */, + 914E2F5F28C4D2A9009242A1 /* TemporaryViewController.swift in Sources */, C35EB13728B3598A006AFA0A /* AppDelegate.swift in Sources */, + 91BED6E128C8901B00837AFF /* LineChartView.swift in Sources */, + 91F040D828C646FA0049CAA7 /* Day.swift in Sources */, + 911A171B28C1ABDB009B4376 /* CustomModalViewController.swift in Sources */, C35EB13928B3598A006AFA0A /* SceneDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXVariantGroup section */ - C35EB13C28B3598A006AFA0A /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - C35EB13D28B3598A006AFA0A /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - C35EB14128B3598A006AFA0A /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - C35EB14228B3598A006AFA0A /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ C35EB14528B3598A006AFA0A /* Debug */ = { isa = XCBuildConfiguration; @@ -219,6 +228,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_PREVIEWS = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -280,6 +290,7 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; + ENABLE_PREVIEWS = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; @@ -309,8 +320,9 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = FreeSubject/Info.plist; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UILaunchStoryboardName = "Launch Screen"; + INFOPLIST_KEY_UIMainStoryboardFile = ""; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -337,8 +349,9 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = FreeSubject/Info.plist; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UILaunchStoryboardName = "Launch Screen"; + INFOPLIST_KEY_UIMainStoryboardFile = ""; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -403,6 +416,22 @@ kind = branch; }; }; + 91B45FC928C098B200BFF72D /* XCRemoteSwiftPackageReference "Charts" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/danielgindi/Charts.git"; + requirement = { + branch = master; + kind = branch; + }; + }; + 91D85F1828BA7993009AAFDA /* XCRemoteSwiftPackageReference "FSCalendar" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/WenchaoD/FSCalendar.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.0.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -426,6 +455,16 @@ package = 690DDC9B28B7D5FB00C278E1 /* XCRemoteSwiftPackageReference "realm-cocoa" */; productName = RealmSwift; }; + 91B45FCA28C098B200BFF72D /* Charts */ = { + isa = XCSwiftPackageProductDependency; + package = 91B45FC928C098B200BFF72D /* XCRemoteSwiftPackageReference "Charts" */; + productName = Charts; + }; + 91D85F1928BA7993009AAFDA /* FSCalendar */ = { + isa = XCSwiftPackageProductDependency; + package = 91D85F1828BA7993009AAFDA /* XCRemoteSwiftPackageReference "FSCalendar" */; + productName = FSCalendar; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = C35EB12B28B35989006AFA0A /* Project object */; diff --git a/FreeSubject/AppDelegate.swift b/FreeSubject/AppDelegate.swift index 017b0a6..f0d8f94 100644 --- a/FreeSubject/AppDelegate.swift +++ b/FreeSubject/AppDelegate.swift @@ -10,26 +10,25 @@ import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. +// sleep(5) return true } // MARK: UISceneSession Lifecycle - - func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { - // Called when a new scene session is being created. - // Use this method to select a configuration to create the new scene with. - return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) - } - - func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { - // Called when the user discards a scene session. - // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. - // Use this method to release any resources that were specific to the discarded scenes, as they will not return. - } +// +// func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { +// // Called when a new scene session is being created. +// // Use this method to select a configuration to create the new scene with. +// return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) +// } +// +// func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { +// // Called when the user discards a scene session. +// // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. +// // Use this method to release any resources that were specific to the discarded scenes, as they will not return. +// } } diff --git a/FreeSubject/Assets.xcassets/calendar.imageset/Contents.json b/FreeSubject/Assets.xcassets/calendar.imageset/Contents.json new file mode 100644 index 0000000..d626a5c --- /dev/null +++ b/FreeSubject/Assets.xcassets/calendar.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Vectorcalendar.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FreeSubject/Assets.xcassets/calendar.imageset/Vectorcalendar.png b/FreeSubject/Assets.xcassets/calendar.imageset/Vectorcalendar.png new file mode 100644 index 0000000..8468c37 Binary files /dev/null and b/FreeSubject/Assets.xcassets/calendar.imageset/Vectorcalendar.png differ diff --git a/FreeSubject/Assets.xcassets/color.imageset/Contents.json b/FreeSubject/Assets.xcassets/color.imageset/Contents.json new file mode 100644 index 0000000..e2057e6 --- /dev/null +++ b/FreeSubject/Assets.xcassets/color.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Rectangle 5778.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FreeSubject/Assets.xcassets/color.imageset/Rectangle 5778.png b/FreeSubject/Assets.xcassets/color.imageset/Rectangle 5778.png new file mode 100644 index 0000000..9ec674f Binary files /dev/null and b/FreeSubject/Assets.xcassets/color.imageset/Rectangle 5778.png differ diff --git a/FreeSubject/Assets.xcassets/paper.imageset/Contents.json b/FreeSubject/Assets.xcassets/paper.imageset/Contents.json new file mode 100644 index 0000000..12ec2f0 --- /dev/null +++ b/FreeSubject/Assets.xcassets/paper.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Rectangle 5895.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FreeSubject/Assets.xcassets/paper.imageset/Rectangle 5895.png b/FreeSubject/Assets.xcassets/paper.imageset/Rectangle 5895.png new file mode 100644 index 0000000..0149b2b Binary files /dev/null and b/FreeSubject/Assets.xcassets/paper.imageset/Rectangle 5895.png differ diff --git a/FreeSubject/Assets.xcassets/stats.imageset/Contents.json b/FreeSubject/Assets.xcassets/stats.imageset/Contents.json new file mode 100644 index 0000000..446d6be --- /dev/null +++ b/FreeSubject/Assets.xcassets/stats.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Vector.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FreeSubject/Assets.xcassets/stats.imageset/Vector.png b/FreeSubject/Assets.xcassets/stats.imageset/Vector.png new file mode 100644 index 0000000..eff8a4d Binary files /dev/null and b/FreeSubject/Assets.xcassets/stats.imageset/Vector.png differ diff --git a/FreeSubject/Assets.xcassets/string.imageset/Contents.json b/FreeSubject/Assets.xcassets/string.imageset/Contents.json new file mode 100644 index 0000000..89d46aa --- /dev/null +++ b/FreeSubject/Assets.xcassets/string.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Vector 144.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FreeSubject/Assets.xcassets/string.imageset/Vector 144.png b/FreeSubject/Assets.xcassets/string.imageset/Vector 144.png new file mode 100644 index 0000000..8ea7d9e Binary files /dev/null and b/FreeSubject/Assets.xcassets/string.imageset/Vector 144.png differ diff --git a/FreeSubject/Base.lproj/LaunchScreen.storyboard b/FreeSubject/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 865e932..0000000 --- a/FreeSubject/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FreeSubject/Base.lproj/Main.storyboard b/FreeSubject/Base.lproj/Main.storyboard deleted file mode 100644 index 25a7638..0000000 --- a/FreeSubject/Base.lproj/Main.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FreeSubject/CalendarViewController.swift b/FreeSubject/CalendarViewController.swift new file mode 100644 index 0000000..1ec5cba --- /dev/null +++ b/FreeSubject/CalendarViewController.swift @@ -0,0 +1,165 @@ +// +// CalendarViewController.swift +// FreeSubject +// +// Created by 홍준혁 on 2022/08/27. + +import Foundation +import SnapKit +import UIKit +import RealmSwift +import Then +import FSCalendar +import SwiftUI +import Charts + + + +class CalendarViewController: UIViewController,FSCalendarDelegate,FSCalendarDataSource,FSCalendarDelegateAppearance{ + + + let fsCalendar = FSCalendar(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) + var selectedDate: Date = Date() + let dateFormatter = DateFormatter() + + + let titleLable:UILabel = { + let label = UILabel() + label.textColor = .black + label.textAlignment = .center + label.backgroundColor = UIColor(red: 0.74, green: 0.86, blue: 0.79, alpha: 1.00) + label.clipsToBounds = true + label.layer.cornerRadius = 10 + label.text = "app name" + label.font = .systemFont(ofSize: 20, weight: .regular) + return label + }() + lazy var goToThisMonth:UIButton = { + var btn = UIButton() + btn.setImage(UIImage(systemName: "arrow.uturn.left"), for: .normal) + btn.addTarget(self, action: #selector(currentBtnClicked), for: .touchUpInside) + btn.tintColor = .black + btn.layer.cornerRadius = 16 + btn.backgroundColor = UIColor(red: 0.74, green: 0.86, blue: 0.79, alpha: 1.00) + return btn + }() + + override func viewDidLoad() { + // Do any additional setup after loading the view. + setView() + print("CalendarViewController") + + } + + override func viewWillAppear(_ animated: Bool) { + setView() + } + + func setView(){ + view.backgroundColor = UIColor(red: 0.94, green: 0.97, blue: 0.95, alpha: 1.0) + view.addSubview(titleLable) + view.addSubview(fsCalendar) + + view.addSubview(goToThisMonth) + fsCalendar.delegate = self + fsCalendar.dataSource = self + + resetDB() +// createDateDB() + setSNP() + + } + + func setSNP(){ + calendarSetting() + fsCalendar.snp.makeConstraints{ make in + make.top.equalTo(titleLable.fs_bottom).inset(150) + make.leading.equalTo(titleLable.fs_left).inset(20) + make.trailing.equalTo(titleLable.fs_right).inset(20) + make.bottom.equalToSuperview().offset(-200) + } + goToThisMonth.snp.makeConstraints{ make in + make.top.equalTo(fsCalendar).inset(10) + make.trailing.equalTo(fsCalendar).inset(15) + make.width.equalTo(34) + make.height.equalTo(34) + } + + titleLable.snp.makeConstraints{ make in + make.top.equalToSuperview().offset(60) + make.leading.equalToSuperview().offset(77) + make.trailing.equalToSuperview().offset(-77) + make.height.equalTo(60) + } + } + + func calendarSetting(){ + fsCalendar.appearance.headerMinimumDissolvedAlpha = 0.0 //양 옆 글자 투명도 + fsCalendar.dataSource = self + fsCalendar.delegate = self + fsCalendar.locale = Locale(identifier: "ko_KR") + fsCalendar.scrollEnabled = true + fsCalendar.appearance.weekdayTextColor = .black + fsCalendar.appearance.headerTitleColor = .black + fsCalendar.appearance.eventDefaultColor = UIColor.green + fsCalendar.appearance.eventSelectionColor = UIColor.green + fsCalendar.appearance.headerDateFormat = "MM월 YYYY년" + + } + + // 날짜 선택 -> 콜백 메소드 + func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) { + print("select") + dateFormatter.dateFormat = "YYYY-MM-dd" + print(dateFormatter.string(from: date)) + presentModalController(inputDate: dateFormatter.string(from: date)) + + } + + // To be updated + func presentModalController(inputDate:String) { + let vc = CustomModalViewController() + vc.Date = inputDate + vc.modalPresentationStyle = .overCurrentContext + // keep false + // modal animation will be handled in VC itself + self.present(vc, animated: false) + } + + // 현재 달로 돌아오기 위한 함수 + @objc func currentBtnClicked(sender: UIButton!) { + print(Date()) // 실제 오늘 날짜가 출력됨. + self.fsCalendar.setCurrentPage(Date(), animated: true) + } + + // Realm 생성 + func createDateDB(){ + let realm = try! Realm() + let date1 = Day(Date: "2022-09-03", iconFeeling: "smile", sleepTime: "8:30", didFeelingChange: false, didTakeMedicine: true, tableNum: 2) + print(Realm.Configuration.defaultConfiguration.fileURL!) + try! realm.write{ + realm.add(date1) + } + } + + // 아예 Realm 파일 삭제 Realm 의 요소들을 변경하면 한번씩 해줘야 한다... + func resetDB(){ + let realmURL = Realm.Configuration.defaultConfiguration.fileURL! + let realmURLs = [ + realmURL, + realmURL.appendingPathExtension("lock"), + realmURL.appendingPathExtension("note"), + realmURL.appendingPathExtension("management") + ] + + for URL in realmURLs { + do { + try FileManager.default.removeItem(at: URL) + } catch { + // handle error + } + } + } + + +} diff --git a/FreeSubject/CustomModalViewController.swift b/FreeSubject/CustomModalViewController.swift new file mode 100644 index 0000000..7aada49 --- /dev/null +++ b/FreeSubject/CustomModalViewController.swift @@ -0,0 +1,297 @@ +// +// TestViewControlle.swift +// FreeSubject +// +// Created by 홍준혁 on 2022/09/01. +// + +import UIKit +import SnapKit + +class CustomModalViewController: UIViewController { + + // 모달창에 뜨는 부분 날짜 표기 + var Date:String = "" + + // define lazy views + lazy var titleLabel: UILabel = { + let label = UILabel() + label.textColor = .black + + label.textAlignment = .center + label.backgroundColor = UIColor(red: 0.74, green: 0.85, blue: 0.78, alpha: 1.00) + label.clipsToBounds = true + label.layer.cornerRadius = 16 + // 나중에 선택한 날로 변결 + label.text = Date + label.font = .systemFont(ofSize: 20, weight: .regular) + return label + }() + lazy var iconView1: UIView = { + let view = UIView() + view.backgroundColor = UIColor(red: 0.74, green: 0.85, blue: 0.78, alpha: 1.00) + view.layer.cornerRadius = 16 + return view + }() + lazy var iconView2: UIView = { + let view = UIView() + view.backgroundColor = UIColor(red: 0.74, green: 0.85, blue: 0.78, alpha: 1.00) + view.layer.cornerRadius = 16 + return view + }() + lazy var iconView3: UIView = { + let view = UIView() + view.backgroundColor = UIColor(red: 0.74, green: 0.85, blue: 0.78, alpha: 1.00) + view.layer.cornerRadius = 16 + return view + }() + + // half-modal 뷰 + lazy var containerView: UIView = { + let view = UIView() + view.backgroundColor = .systemBackground + view.layer.cornerRadius = 16 + view.clipsToBounds = true + return view + }() + + let maxDimmedAlpha: CGFloat = 0.6 + lazy var dimmedView: UIView = { + let view = UIView() + view.backgroundColor = .black + view.alpha = maxDimmedAlpha + return view + }() + + lazy var ButtonForNextView: UIButton = { + var btn = UIButton() + btn.setTitle("확인하기", for: .normal) + btn.setTitleColor(.white, for: .normal) + btn.layer.cornerRadius = 16 + btn.backgroundColor = UIColor(red: 0.49, green: 0.65, blue: 0.56, alpha: 1.0) + btn.addTarget(self, action: #selector(nextView), for: .touchUpInside) + return btn + }() + + + // Constants + let defaultHeight: CGFloat = 300 // 처음 half-modal 이 올라오는 높이 + let dismissibleHeight: CGFloat = 150 // half-modal 없어지는 높이 + let maximumContainerHeight: CGFloat = 600 // half-modal 최대로 끌어올리는 높이 + // UIScreen.main.bounds.height - 100 + // keep current new height, initial is default height + var currentContainerHeight: CGFloat = 300 + + // Dynamic container constraint + var containerViewHeightConstraint: NSLayoutConstraint? + var containerViewBottomConstraint: NSLayoutConstraint? + + override func viewDidLoad() { + print("CustomModalViewController") + super.viewDidLoad() + view.backgroundColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0) + setupView() + setupConstraints() + // tap gesture on dimmed view to dismiss + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleCloseAction)) + dimmedView.addGestureRecognizer(tapGesture) + + setupPanGesture() + } + + @objc func handleCloseAction() { + animateDismissView() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + animateShowDimmedView() + animatePresentContainer() + } + + func setupView() { + view.backgroundColor = .clear + } + + func setupConstraints() { + // Add subviews + view.addSubview(dimmedView) + view.addSubview(containerView) + containerView.addSubview(iconView1) + containerView.addSubview(iconView2) + containerView.addSubview(iconView3) + containerView.addSubview(titleLabel) + containerView.addSubview(ButtonForNextView) + + setSNP() + } + + func setSNP(){ + titleLabel.snp.makeConstraints{ make in + make.top.equalTo(containerView).offset(33) + make.trailing.equalTo(containerView).inset(40) + make.leading.equalTo(containerView).inset(40) + make.height.equalTo(30) + } + ButtonForNextView.snp.makeConstraints{ make in + make.top.equalTo(titleLabel).inset(170) + make.centerX.equalTo(containerView) + make.height.equalTo(45) + make.leading.equalTo(containerView).inset(135) + make.trailing.equalTo(containerView).inset(135) + } + iconView1.snp.makeConstraints{ make in + make.top.equalTo(titleLabel).inset(45) + make.leading.equalTo(containerView).inset(35) + make.height.equalTo(90) + make.width.equalTo(90) + } + iconView2.snp.makeConstraints{ make in + make.top.equalTo(titleLabel).inset(45) +// make.leading.equalTo(containerView).inset(135) + make.centerX.equalTo(titleLabel) + make.height.equalTo(90) + make.width.equalTo(90) + } + iconView3.snp.makeConstraints{ make in + make.top.equalTo(titleLabel).inset(45) + make.trailing.equalTo(containerView).inset(33) + make.height.equalTo(90) + make.width.equalTo(90) + } + + dimmedView.snp.makeConstraints{ make in + make.top.equalToSuperview() + make.bottom.equalToSuperview() + make.trailing.equalToSuperview() + make.leading.equalToSuperview() + } + containerView.snp.makeConstraints{ make in + make.leading.equalToSuperview() + make.trailing.equalToSuperview() + } + + // Set dynamic constraints + // First, set container to default height + // after panning, the height can expand + containerViewHeightConstraint = containerView.heightAnchor.constraint(equalToConstant: defaultHeight) + + // By setting the height to default height, the container will be hide below the bottom anchor view + // Later, will bring it up by set it to 0 + // set the constant to default height to bring it down again + containerViewBottomConstraint = containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: defaultHeight) + // Activate constraints + containerViewHeightConstraint?.isActive = true + containerViewBottomConstraint?.isActive = true + } + + func setupPanGesture() { + // add pan gesture recognizer to the view controller's view (the whole screen) + let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.handlePanGesture(gesture:))) + // change to false to immediately listen on gesture movement + panGesture.delaysTouchesBegan = false + panGesture.delaysTouchesEnded = false + view.addGestureRecognizer(panGesture) + } + + // MARK: Pan gesture handler + @objc func handlePanGesture(gesture: UIPanGestureRecognizer) { + let translation = gesture.translation(in: view) + // Drag to top will be minus value and vice versa + print("Pan gesture y offset: \(translation.y)") + + // Get drag direction + let isDraggingDown = translation.y > 0 + print("Dragging direction: \(isDraggingDown ? "going down" : "going up")") + + // New height is based on value of dragging plus current container height + let newHeight = currentContainerHeight - translation.y + + // Handle based on gesture state + switch gesture.state { + case .changed: + // This state will occur when user is dragging + if newHeight < maximumContainerHeight { + // Keep updating the height constraint + containerViewHeightConstraint?.constant = newHeight + // refresh layout + view.layoutIfNeeded() + } + case .ended: + // This happens when user stop drag, + // so we will get the last height of container + + // Condition 1: If new height is below min, dismiss controller + if newHeight < dismissibleHeight { + self.animateDismissView() + } + else if newHeight < defaultHeight { + // Condition 2: If new height is below default, animate back to default + animateContainerHeight(defaultHeight) + } + else if newHeight < maximumContainerHeight && isDraggingDown { + // Condition 3: If new height is below max and going down, set to default height + animateContainerHeight(defaultHeight) + } + else if newHeight > defaultHeight && !isDraggingDown { + // Condition 4: If new height is below max and going up, set to max height at top + animateContainerHeight(maximumContainerHeight) + } + default: + break + } + } + + func animateContainerHeight(_ height: CGFloat) { + UIView.animate(withDuration: 0.4) { + // Update container height + self.containerViewHeightConstraint?.constant = height + // Call this to trigger refresh constraint + self.view.layoutIfNeeded() + } + // Save current height + currentContainerHeight = height + } + + // MARK: Present and dismiss animation + func animatePresentContainer() { + // update bottom constraint in animation block + UIView.animate(withDuration: 0.3) { + self.containerViewBottomConstraint?.constant = 0 + // call this to trigger refresh constraint + self.view.layoutIfNeeded() + } + } + + func animateShowDimmedView() { + dimmedView.alpha = 0 + UIView.animate(withDuration: 0.4) { + self.dimmedView.alpha = self.maxDimmedAlpha + } + } + + func animateDismissView() { + // hide blur view + dimmedView.alpha = maxDimmedAlpha + UIView.animate(withDuration: 0.4) { + self.dimmedView.alpha = 0 + } completion: { _ in + // once done, dismiss without animation + self.dismiss(animated: false) + } + // hide main view by updating bottom constraint in animation block + UIView.animate(withDuration: 0.3) { + self.containerViewBottomConstraint?.constant = self.defaultHeight + // call this to trigger refresh constraint + self.view.layoutIfNeeded() + } + } + + @objc func nextView(_ sender : Any){ + let view = TemporaryViewController() // 여기에 규철님 VC을 연결한다. TemporaryViewController 대신해서 + view.modalTransitionStyle = UIModalTransitionStyle.coverVertical + view.modalPresentationStyle = UIModalPresentationStyle.fullScreen + self.present(view, animated: true, completion: nil) + } +} + diff --git a/FreeSubject/CustomTabBarController.swift b/FreeSubject/CustomTabBarController.swift new file mode 100644 index 0000000..22bccd9 --- /dev/null +++ b/FreeSubject/CustomTabBarController.swift @@ -0,0 +1,35 @@ +// +// CustomTabBarController.swift +// FreeSubject +// +// Created by 홍준혁 on 2022/08/28. +// + +import Foundation +import UIKit +import SnapKit + +class CustomTabBarController: UITabBarController{ + override func viewDidLoad() { + print("CustomTabBarController") + super.viewDidLoad() + + // create instance + let calendarVC = CalendarViewController() +// let statsVC = StatsViewController() + let statsVC = LineChartViewController() + // set title + calendarVC.title = "달력" + statsVC.title = "통계" + // assign view controllers to tab bar + self.setViewControllers([calendarVC,statsVC], animated: false) + + + let imageCalendar = UIImage(named: "calendar") + let imageStats = UIImage(named: "stats") + guard let items = self.tabBar.items else {return} + items[0].image = imageCalendar + items[1].image = imageStats + + } +} diff --git a/FreeSubject/Day.swift b/FreeSubject/Day.swift new file mode 100644 index 0000000..114c500 --- /dev/null +++ b/FreeSubject/Day.swift @@ -0,0 +1,33 @@ +// +// Day.swift +// FreeSubject +// +// Created by 홍준혁 on 2022/09/06. +// + +import RealmSwift +import Foundation +import UIKit + +class Day: Object{ + @Persisted var Date: String = "" + @Persisted var iconFeeling: String = "" + @Persisted var sleepTime: String = "" + @Persisted var didFeelingChange: Bool = true + @Persisted var didTakeMedicine: Bool = true + @Persisted var tableNum: Int = 0 // 질문지에서 마지막 표에 대한 데이터 + + override static func primaryKey() -> String? { + return "Date" + } + + convenience init(Date:String,iconFeeling:String,sleepTime:String,didFeelingChange:Bool,didTakeMedicine:Bool,tableNum:Int) { + self.init() + self.Date = Date + self.iconFeeling = iconFeeling + self.sleepTime = sleepTime + self.didFeelingChange = didFeelingChange + self.didTakeMedicine = didTakeMedicine + self.tableNum = tableNum + } +} diff --git a/FreeSubject/Info.plist b/FreeSubject/Info.plist index dd3c9af..0eb786d 100644 --- a/FreeSubject/Info.plist +++ b/FreeSubject/Info.plist @@ -15,8 +15,6 @@ Default Configuration UISceneDelegateClassName $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main diff --git a/FreeSubject/Launch Screen.storyboard b/FreeSubject/Launch Screen.storyboard new file mode 100644 index 0000000..77caa08 --- /dev/null +++ b/FreeSubject/Launch Screen.storyboard @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FreeSubject/LineChartView.swift b/FreeSubject/LineChartView.swift new file mode 100644 index 0000000..db06a7d --- /dev/null +++ b/FreeSubject/LineChartView.swift @@ -0,0 +1,69 @@ +// +// LineChartView.swift +// FreeSubject +// +// Created by 홍준혁 on 2022/09/07. +// + +import Foundation +import Foundation +import UIKit + +class LineChartView: UIView { + + var values: [CGFloat] = [] + + var graphPath: UIBezierPath! + var zeroPath: UIBezierPath! + var animated: Bool! + + let graphLayer = CAShapeLayer() + + init(frame: CGRect, values: [CGFloat], animated: Bool) { + super.init(frame: frame) + self.values = values + self.animated = animated + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func draw(_ rect: CGRect) { + super.draw(rect) + self.graphPath = UIBezierPath() + self.zeroPath = UIBezierPath() + + self.layer.addSublayer(graphLayer) + + let xOffset: CGFloat = self.frame.width / CGFloat(values.count) + + var currentX: CGFloat = 0 + let startPosition = CGPoint(x: currentX, y: self.frame.height) + self.graphPath.move(to: startPosition) + self.zeroPath.move(to: startPosition) + + for i in 0..