├── Asset
├── appgroup.png
├── art.png
└── preview.png
├── Did-you-know-master
├── Did you know.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ ├── Manu.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ │ └── hiran.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ ├── Manu.xcuserdatad
│ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ │ ├── ExampleSCDWidget.xcscheme
│ │ │ ├── ExampleSharedCoreData.xcscheme
│ │ │ ├── SCDWidget.xcscheme
│ │ │ ├── SharedCoreData.xcscheme
│ │ │ └── xcschememanagement.plist
│ │ └── hiran.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── Facts+CoreDataClass.swift
├── Facts+CoreDataProperties.swift
├── SCDWidget
│ ├── Base.lproj
│ │ └── MainInterface.storyboard
│ ├── Info.plist
│ ├── SCDWidget.entitlements
│ └── TodayViewController.swift
├── SharedCoreData
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x-1.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x-1.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x-1.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ ├── Contents.json
│ │ └── Icon_bulb.imageset
│ │ │ ├── Contents.json
│ │ │ ├── s.png
│ │ │ ├── s@2x.png
│ │ │ └── s@3x.png
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── DataManager
│ │ ├── SCDCoreDataWrapper.swift
│ │ └── SCDFactModel.swift
│ ├── DatePicker
│ │ └── JBDatePicker
│ │ │ ├── Classes
│ │ │ ├── JBDate.swift
│ │ │ ├── JBDateExtension.swift
│ │ │ ├── JBDatePickerContentVC.swift
│ │ │ ├── JBDatePickerDayView.swift
│ │ │ ├── JBDatePickerEnums.swift
│ │ │ ├── JBDatePickerManager.swift
│ │ │ ├── JBDatePickerMonthView.swift
│ │ │ ├── JBDatePickerSelectionView.swift
│ │ │ ├── JBDatePickerView.swift
│ │ │ ├── JBDatePickerViewDelegate.swift
│ │ │ ├── JBDatePickerWeekDaysView.swift
│ │ │ ├── JBDatePickerWeekView.swift
│ │ │ └── JBFont.swift
│ │ │ ├── Info.plist
│ │ │ └── JBDatePicker.h
│ ├── DidYouKnowFacts.json
│ ├── HomeViewController.swift
│ ├── Info.plist
│ ├── SharedCoreData.entitlements
│ └── SharedCoreData.xcdatamodeld
│ │ ├── .xccurrentversion
│ │ └── SharedCoreData.xcdatamodel
│ │ └── contents
├── SharedCoreDataTests
│ ├── Info.plist
│ └── SharedCoreDataTests.swift
└── SharedCoreDataUITests
│ ├── Info.plist
│ └── SharedCoreDataUITests.swift
└── README.md
/Asset/appgroup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Asset/appgroup.png
--------------------------------------------------------------------------------
/Asset/art.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Asset/art.png
--------------------------------------------------------------------------------
/Asset/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Asset/preview.png
--------------------------------------------------------------------------------
/Did-you-know-master/Did you know.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Did-you-know-master/Did you know.xcodeproj/project.xcworkspace/xcuserdata/Manu.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/Did you know.xcodeproj/project.xcworkspace/xcuserdata/Manu.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Did-you-know-master/Did you know.xcodeproj/project.xcworkspace/xcuserdata/hiran.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/Did you know.xcodeproj/project.xcworkspace/xcuserdata/hiran.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Did-you-know-master/Did you know.xcodeproj/xcuserdata/Manu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
24 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Did-you-know-master/Did you know.xcodeproj/xcuserdata/Manu.xcuserdatad/xcschemes/ExampleSCDWidget.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
10 |
16 |
22 |
23 |
24 |
30 |
36 |
37 |
38 |
39 |
40 |
45 |
46 |
47 |
48 |
54 |
55 |
56 |
57 |
58 |
59 |
70 |
72 |
78 |
79 |
80 |
81 |
82 |
83 |
90 |
92 |
98 |
99 |
100 |
101 |
103 |
104 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/Did-you-know-master/Did you know.xcodeproj/xcuserdata/Manu.xcuserdatad/xcschemes/ExampleSharedCoreData.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Did-you-know-master/Did you know.xcodeproj/xcuserdata/Manu.xcuserdatad/xcschemes/SCDWidget.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
10 |
16 |
22 |
23 |
24 |
30 |
36 |
37 |
38 |
39 |
40 |
45 |
46 |
47 |
48 |
54 |
55 |
56 |
57 |
58 |
59 |
70 |
72 |
78 |
79 |
80 |
81 |
82 |
83 |
90 |
92 |
98 |
99 |
100 |
101 |
103 |
104 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/Did-you-know-master/Did you know.xcodeproj/xcuserdata/Manu.xcuserdatad/xcschemes/SharedCoreData.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/Did-you-know-master/Did you know.xcodeproj/xcuserdata/Manu.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ExampleSCDWidget.xcscheme
8 |
9 | orderHint
10 | 3
11 |
12 | ExampleSharedCoreData.xcscheme
13 |
14 | orderHint
15 | 2
16 |
17 | SCDWidget.xcscheme
18 |
19 | orderHint
20 | 1
21 |
22 | SharedCoreData.xcscheme
23 |
24 | orderHint
25 | 0
26 |
27 |
28 | SuppressBuildableAutocreation
29 |
30 | 324735191FE25EA10002C221
31 |
32 | primary
33 |
34 |
35 | 324735301FE25EA20002C221
36 |
37 | primary
38 |
39 |
40 | 3247353B1FE25EA20002C221
41 |
42 | primary
43 |
44 |
45 | 324735511FE26E580002C221
46 |
47 | primary
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/Did-you-know-master/Did you know.xcodeproj/xcuserdata/hiran.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SCDWidget.xcscheme
8 |
9 | orderHint
10 | 1
11 |
12 | SharedCoreData.xcscheme
13 |
14 | orderHint
15 | 0
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Did-you-know-master/Facts+CoreDataClass.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Facts+CoreDataClass.swift
3 | // SharedCoreData
4 | //
5 | // Created by iLeaf Solutions on 18/12/17.
6 | // Copyright © 2017 iLeaf. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CoreData
11 |
12 | @objc(Facts)
13 | public class Facts: NSManagedObject {
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/Did-you-know-master/Facts+CoreDataProperties.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Facts+CoreDataProperties.swift
3 | // SharedCoreData
4 | //
5 | // Created by iLeaf Solutions on 18/12/17.
6 | // Copyright © 2017 iLeaf. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CoreData
11 |
12 |
13 | extension Facts {
14 |
15 | @nonobjc public class func fetchRequest() -> NSFetchRequest {
16 | return NSFetchRequest(entityName: "Facts")
17 | }
18 |
19 | @NSManaged public var date: String?
20 | @NSManaged public var fact: String?
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/Did-you-know-master/SCDWidget/Base.lproj/MainInterface.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | TimesNewRomanPSMT
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/Did-you-know-master/SCDWidget/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | Did you know?
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | XPC!
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | NSExtension
24 |
25 | NSExtensionMainStoryboard
26 | MainInterface
27 | NSExtensionPointIdentifier
28 | com.apple.widget-extension
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Did-you-know-master/SCDWidget/SCDWidget.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.application-groups
6 |
7 | group.com.ileaf.SharedCoreData
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Did-you-know-master/SCDWidget/TodayViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TodayViewController.swift
3 | // SCDWidget
4 | //
5 | // Created by iLeaf Solutions on 14/12/17.
6 | // Copyright © 2017 iLeaf. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import NotificationCenter
11 | import CoreData
12 |
13 | class TodayViewController: UIViewController, NCWidgetProviding {
14 | //Core data context
15 | var managedContext: NSManagedObjectContext?
16 | /// Input is todays fact
17 | @IBOutlet weak var lblFactsDescription: UILabel!
18 |
19 | //MARK: View life cycle
20 | override func viewDidLoad() {
21 | super.viewDidLoad()
22 | // Do any additional setup after loading the view from its nib.
23 | }
24 |
25 | override func didReceiveMemoryWarning() {
26 | super.didReceiveMemoryWarning()
27 | // Dispose of any resources that can be recreated.
28 | }
29 |
30 | func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) {
31 | // Perform any setup necessary in order to update the view.
32 | fetchTodaysFact()
33 | // If an error is encountered, use NCUpdateResult.Failed
34 | // If there's no update required, use NCUpdateResult.NoData
35 | // If there's an update, use NCUpdateResult.NewData
36 |
37 |
38 | completionHandler(NCUpdateResult.newData)
39 | }
40 | // MARK: Helper functions
41 | func getMonth(month:Int) -> String {
42 | switch month {
43 | case 1:
44 | return "Jan"
45 | case 2:
46 | return "Feb"
47 | case 3:
48 | return "Mar"
49 | case 4:
50 | return "Apr"
51 | case 5:
52 | return "May"
53 | case 6:
54 | return "Jun"
55 | case 7:
56 | return "Jul"
57 | case 8:
58 | return "Aug"
59 | case 9:
60 | return "Sep"
61 | case 10:
62 | return "Oct"
63 | case 11:
64 | return "Nov"
65 | default:
66 | return "Dec"
67 | }
68 | }
69 | func fetchTodaysFact()
70 | {
71 | let date = Date()
72 | let calendar = Calendar.current
73 | let components = calendar.dateComponents([.year, .month, .day], from:date)
74 |
75 | // let year = components.year
76 | let month = components.month
77 |
78 | let day:Int = components.day!
79 | let todaysDate = getMonth(month: month!)+" "+String(day)
80 | let data = self.fetchTodaysFact(filter: todaysDate)
81 | let replaced = data.fact.trimmingCharacters(in: NSCharacterSet.whitespaces)
82 | lblFactsDescription.text = replaced
83 | }
84 |
85 | //MARK: Get Facts with filter from coredata
86 | //from DB Function
87 | func fetchTodaysFact(filter:String) ->SCDFactModel{
88 |
89 | var todaysFact = SCDFactModel()
90 | //var managedContext = context
91 | if #available(iOS 10.0, *) {
92 | managedContext =
93 | SCDCoreDataWrapper.sharedInstance.persistentContainer.viewContext
94 | } else {
95 | // Fallback on earlier versions
96 | managedContext = SCDCoreDataWrapper.sharedInstance.managedObjectContext
97 | }
98 | let fetchRequest =
99 | NSFetchRequest(entityName: "Facts")
100 | do {
101 | //go get the results
102 | fetchRequest.returnsObjectsAsFaults = false
103 | fetchRequest.predicate = NSPredicate(format: "date == %@",filter)
104 | // let Results = try getContext().fetch(fetchRequest)
105 | // print(Results)
106 | let searchResults = try SCDCoreDataWrapper.sharedInstance.getContext().fetch(fetchRequest)
107 | //I like to check the size of the returned results!
108 | print ("num of results = \(String(describing: searchResults.count))")
109 | //You need to convert to NSManagedObject to use 'for' loops
110 | for transPort in searchResults {
111 | //get the Key Value pairs from searchResult ()
112 | let data = SCDFactModel()
113 | todaysFact = data.factsMapping(factMapper: transPort)
114 |
115 |
116 | }
117 |
118 | return todaysFact
119 | }
120 | catch {
121 | print("Error with request: \(error)")
122 | return todaysFact
123 | }
124 | }
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SharedCoreData
4 | //
5 | // Created by iLeaf Solutions on 14/12/17.
6 | // Copyright © 2017 iLeaf. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CoreData
11 |
12 | @UIApplicationMain
13 | class AppDelegate: UIResponder, UIApplicationDelegate {
14 |
15 | var window: UIWindow?
16 |
17 |
18 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
19 | // Override point for customization after application launch.
20 | return true
21 | }
22 |
23 | func applicationWillResignActive(_ application: UIApplication) {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
26 | }
27 |
28 | func applicationDidEnterBackground(_ application: UIApplication) {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | func applicationWillEnterForeground(_ application: UIApplication) {
34 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | func applicationDidBecomeActive(_ application: UIApplication) {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | func applicationWillTerminate(_ application: UIApplication) {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | // Saves changes in the application's managed object context before the application terminates.
44 |
45 | }
46 |
47 |
48 |
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-40x40@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-60x60@2x.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@3x.png",
49 | "scale" : "3x"
50 | },
51 | {
52 | "size" : "20x20",
53 | "idiom" : "ipad",
54 | "filename" : "Icon-App-20x20@1x.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@2x-1.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "29x29",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-29x29@1x.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@2x-1.png",
73 | "scale" : "2x"
74 | },
75 | {
76 | "size" : "40x40",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-40x40@1x.png",
79 | "scale" : "1x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@2x-1.png",
85 | "scale" : "2x"
86 | },
87 | {
88 | "size" : "76x76",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-76x76@1x.png",
91 | "scale" : "1x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@2x.png",
97 | "scale" : "2x"
98 | },
99 | {
100 | "size" : "83.5x83.5",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-83.5x83.5@2x.png",
103 | "scale" : "2x"
104 | }
105 | ],
106 | "info" : {
107 | "version" : 1,
108 | "author" : "xcode"
109 | }
110 | }
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/Icon_bulb.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "s.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "s@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "s@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/Icon_bulb.imageset/s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/Icon_bulb.imageset/s.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/Icon_bulb.imageset/s@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/Icon_bulb.imageset/s@2x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Assets.xcassets/Icon_bulb.imageset/s@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iLeafSolutionsPvtLtd/Notification-Center-Widget/246af18dcab49e8f7bbde76d3e06e49c96597e86/Did-you-know-master/SharedCoreData/Assets.xcassets/Icon_bulb.imageset/s@3x.png
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | TimesNewRomanPSMT
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
42 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | TimesNewRomanPSMT
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
46 |
47 |
48 |
49 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
85 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DataManager/SCDCoreDataWrapper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SCDCoreDataWrapper.swift
3 | // SharedCoreData
4 | //
5 | // Created by iLeaf Solutions on 15/12/17.
6 | // Copyright © 2017 iLeaf. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CoreData
11 |
12 | class SCDCoreDataWrapper: NSObject {
13 | var context: NSManagedObjectContext?
14 | static let sharedInstance : SCDCoreDataWrapper = {
15 | let instance = SCDCoreDataWrapper()
16 | return instance
17 | }()
18 |
19 | // MARK: - Core Data stack
20 | @available(iOS 10.0, *)
21 | lazy var persistentContainer: NSPersistentContainer = {
22 | /*
23 | The persistent container for the application. This implementation
24 | creates and returns a container, having loaded the store for the
25 | application to it. This property is optional since there are legitimate
26 | error conditions that could cause the creation of the store to fail.
27 | */
28 | let container = NSPersistentContainer(name: "SharedCoreData")
29 | var persistentStoreDescriptions: NSPersistentStoreDescription
30 |
31 | let storeUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.ileaf.SharedCoreData")!.appendingPathComponent("\("SharedCoreData").sqlite")
32 |
33 | let description = NSPersistentStoreDescription()
34 | description.shouldInferMappingModelAutomatically = true
35 | description.shouldMigrateStoreAutomatically = true
36 | description.url = storeUrl
37 |
38 | container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.ileaf.SharedCoreData")!.appendingPathComponent("\("SharedCoreData").sqlite"))]
39 |
40 | container.loadPersistentStores(completionHandler: { (storeDescription, error) in
41 | if let error = error as NSError? {
42 | // Replace this implementation with code to handle the error appropriately.
43 | // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
44 |
45 | /*
46 | Typical reasons for an error here include:
47 | * The parent directory does not exist, cannot be created, or disallows writing.
48 | * The persistent store is not accessible, due to permissions or data protection when the device is locked.
49 | * The device is out of space.
50 | * The store could not be migrated to the current model version.
51 | Check the error message to determine what the actual problem was.
52 | */
53 | fatalError("Unresolved error \(error), \(error.userInfo)")
54 | }
55 | })
56 | return container
57 | }()
58 |
59 |
60 |
61 | // MARK: - Core Data Saving support
62 | func saveContext () {
63 | if #available(iOS 10.0, *) {
64 | context = persistentContainer.viewContext
65 | if (context?.hasChanges)! {
66 | do {
67 | try context?.save()
68 | } catch {
69 | }
70 | }
71 | } else {
72 | // Fallback on earlier versions
73 | // iOS 9.0 and below - however you were previously handling it
74 | guard let modelURL = Bundle.main.url(forResource: "SharedCoreData", withExtension:"momd") else {
75 | fatalError("Error loading model from bundle")
76 | }
77 | guard let mom = NSManagedObjectModel(contentsOf: modelURL) else {
78 | fatalError("Error initializing mom from: \(modelURL)")
79 | }
80 | let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)
81 | context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
82 | let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
83 | let docURL = urls[urls.endIndex-1]
84 | let storeURL = docURL.appendingPathComponent("SharedCoreData.sqlite")
85 | do {
86 | try psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil)
87 | } catch {
88 | fatalError("Error migrating store: \(error)")
89 | }
90 |
91 | }
92 |
93 | }
94 | public lazy var managedObjectContext: NSManagedObjectContext = {
95 | let coordinator = self.persistentStoreCoordinator
96 | var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
97 | managedObjectContext.persistentStoreCoordinator = coordinator
98 | return managedObjectContext
99 | }()
100 |
101 | //MARK:- Get the NSManagedObjectContext
102 | func getContext () -> NSManagedObjectContext {
103 | if #available(iOS 10.0, *) {
104 | return SCDCoreDataWrapper.sharedInstance.persistentContainer.viewContext
105 | } else {
106 | // Fallback on earlier versions
107 | return self.managedObjectContext
108 | //return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
109 | }
110 |
111 | }
112 |
113 | private lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
114 | do {
115 | return try NSPersistentStoreCoordinator.coordinator(name:"SharedCoreData")
116 | } catch {
117 | print("CoreData: Unresolved error \(error)")
118 | }
119 | return nil
120 | }()
121 |
122 |
123 | //MARK:- Save all did you know facts
124 | func saveFacts(facts:[SCDFactModel], entity:String ) {
125 |
126 | var managedContext = context
127 | if #available(iOS 10.0, *) {
128 | managedContext =
129 | SCDCoreDataWrapper.sharedInstance.persistentContainer.viewContext
130 | } else {
131 | // Fallback on earlier versions
132 | managedContext = self.managedObjectContext
133 | }
134 | // 2
135 | let entity = NSEntityDescription.entity(forEntityName: entity,in: managedContext!)!
136 |
137 |
138 | do {
139 |
140 | for fact in facts
141 | {
142 | let person = NSManagedObject(entity: entity,insertInto: managedContext)
143 |
144 | let factMapper = fact
145 | factMapper.coreDataMapping(data: fact, managedPerson: person)
146 | }
147 |
148 | }
149 | do{
150 | try managedContext?.save()
151 | }catch{
152 | debugPrint("error")
153 | }
154 |
155 | }
156 |
157 | //MARK:- Get Facts with filter
158 | //from DB Function
159 | func fetchTodaysFact(filter:String) ->SCDFactModel{
160 |
161 | var todaysFact = SCDFactModel()
162 | var managedContext = context
163 | if #available(iOS 10.0, *) {
164 | managedContext =
165 | SCDCoreDataWrapper.sharedInstance.persistentContainer.viewContext
166 | } else {
167 | // Fallback on earlier versions
168 | managedContext = self.managedObjectContext
169 | }
170 | let fetchRequest =
171 | NSFetchRequest(entityName: "Facts")
172 | do {
173 | //go get the results
174 | fetchRequest.returnsObjectsAsFaults = false
175 | fetchRequest.predicate = NSPredicate(format: "date == %@",filter)
176 | // let Results = try getContext().fetch(fetchRequest)
177 | // print(Results)
178 | let searchResults = try managedContext?.fetch(fetchRequest)
179 |
180 |
181 | //I like to check the size of the returned results!
182 | print ("num of results = \(String(describing: searchResults?.count))")
183 | //You need to convert to NSManagedObject to use 'for' loops
184 | for transPort in searchResults! {
185 | //get the Key Value pairs from searchResult ()
186 | let data = SCDFactModel()
187 | todaysFact = data.factsMapping(factMapper: transPort)
188 |
189 |
190 | }
191 |
192 | return todaysFact
193 | }
194 | catch {
195 | print("Error with request: \(error)")
196 | return todaysFact
197 | }
198 | }
199 |
200 | }
201 |
202 | /// NSPersistentStoreCoordinator extension
203 | extension NSPersistentStoreCoordinator {
204 |
205 | /// NSPersistentStoreCoordinator error types
206 | public enum CoordinatorError: Error {
207 | /// .momd file not found
208 | case modelFileNotFound
209 | /// NSManagedObjectModel creation fail
210 | case modelCreationError
211 | /// Gettings document directory fail
212 | case storePathNotFound
213 | }
214 |
215 | /// Return NSPersistentStoreCoordinator object
216 | static func coordinator(name: String) throws -> NSPersistentStoreCoordinator? {
217 |
218 | guard let modelURL = Bundle.main.url(forResource: name, withExtension: "momd") else {
219 | throw CoordinatorError.modelFileNotFound
220 | }
221 |
222 | guard let model = NSManagedObjectModel(contentsOf: modelURL) else {
223 | throw CoordinatorError.modelCreationError
224 | }
225 |
226 | let coordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
227 |
228 | guard let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else {
229 | throw CoordinatorError.storePathNotFound
230 | }
231 | do {
232 | let url = documents.appendingPathComponent("\(name).sqlite")
233 | let options = [ NSMigratePersistentStoresAutomaticallyOption : true,
234 | NSInferMappingModelAutomaticallyOption : true ]
235 | try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options)
236 | } catch {
237 | throw error
238 | }
239 |
240 | return coordinator
241 | }
242 | }
243 |
244 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DataManager/SCDFactModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SCDUserModel.swift
3 | // SharedCoreData
4 | //
5 | // Created by iLeaf Solutions on 15/12/17.
6 | // Copyright © 2017 iLeaf. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CoreData
11 | struct SCDFactModel {
12 |
13 | //MARK:- Properties
14 |
15 | /// know fact
16 | var fact:String = ""
17 | /// date
18 | var date:String = ""
19 |
20 |
21 |
22 |
23 |
24 | //MARK:- Facts saving mapping
25 |
26 | func coreDataMapping(data:SCDFactModel, managedPerson:NSManagedObject) {
27 | managedPerson.setValue(data.fact, forKey: "fact")
28 | managedPerson.setValue(data.date, forKey: "date")
29 |
30 |
31 | }
32 |
33 | //MARK:- Facts retrive mapping
34 | func factsMapping(factMapper:AnyObject) ->SCDFactModel {
35 |
36 | var data = SCDFactModel()
37 | data.fact = factMapper.value(forKey: "fact") as! String
38 | data.date = factMapper.value(forKey: "date") as! String
39 |
40 | return data
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/Classes/JBDate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JBDate.swift
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 22-10-16.
6 | // Copyright © 2016 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | /**
13 | This class defines a day in the week of a certain month and provides
14 | information on whether or not the day falls in the month itself or not.
15 | If not, the day belongs to the previous or next month.
16 | */
17 | final class JBDay {
18 |
19 | var dayValue: Int
20 | var monthValue: Int
21 | var yearValue: Int
22 | var isInMonth: Bool
23 |
24 | init(dayValue: Int, monthValue: Int, yearValue: Int, isInMonth: Bool) {
25 | self.dayValue = dayValue
26 | self.monthValue = monthValue
27 | self.yearValue = yearValue
28 | self .isInMonth = isInMonth
29 | }
30 |
31 | var date: Date? {
32 | let calendar = Calendar.current
33 | var comps = calendar.dateComponents([.day, .month, .year], from: Date())
34 | comps.year = yearValue
35 | comps.month = monthValue
36 | comps.day = dayValue
37 | return Calendar.current.date(from: comps)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/Classes/JBDateExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JBDateExtension.swift
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 17-10-16.
6 | // Copyright © 2016 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension Date {
12 |
13 | func stripped() -> Date?{
14 |
15 | let calendar = Calendar.current
16 | var components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: self)
17 | components.hour = 0
18 | components.minute = 0
19 | components.second = 0
20 | let strippedDate = calendar.date(from: components)
21 |
22 | return strippedDate
23 |
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/Classes/JBDatePickerContentVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JBDatePickerContentVC.swift
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 09-10-16.
6 | // Copyright © 2016 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class JBDatePickerContentVC: UIViewController, UIScrollViewDelegate {
12 |
13 | // MARK: - Properties
14 | unowned let datePickerView: JBDatePickerView
15 | let scrollView: UIScrollView
16 | var presentedMonthView: MonthView
17 | var scrollDirection: JBScrollDirection = .none
18 | private var monthViews = [MonthViewIdentifier : MonthView]()
19 |
20 | ///flag that helps us preventing presentation while another presentation is still going on
21 | private var isPresenting = false
22 |
23 | private var currentPage = 1
24 | private var pageChanged: Bool {
25 | get {
26 | return currentPage == 1 ? false : true
27 | }
28 | }
29 |
30 | private var scrollViewBounds: CGRect {
31 | return scrollView.bounds
32 | }
33 |
34 |
35 | // MARK: - Initialization
36 |
37 | init(datePickerView: JBDatePickerView, frame: CGRect, presentedDate: Date) {
38 |
39 | self.datePickerView = datePickerView
40 | self.scrollView = UIScrollView(frame: frame)
41 |
42 | //create the current Monthview for the current date and fill it with weekviews.
43 | presentedMonthView = MonthView(datePickerView: datePickerView, date: presentedDate, isPresented: true)
44 | presentedMonthView.createWeekViews()
45 |
46 | super.init(nibName: nil, bundle: nil)
47 |
48 | //setup scrollView. Give it a contentsize of 3 times the width because it will hold 3 monthViews
49 | scrollView.contentSize = CGSize(width: frame.width * 3, height: frame.height)
50 | scrollView.showsHorizontalScrollIndicator = false
51 | scrollView.showsVerticalScrollIndicator = false
52 | scrollView.layer.masksToBounds = true
53 | scrollView.isPagingEnabled = true
54 | scrollView.delegate = self
55 |
56 | addInitialMonthViews(for: presentedMonthView.date)
57 | }
58 |
59 | required init?(coder aDecoder: NSCoder) {
60 | fatalError("init(coder:) has not been implemented")
61 | }
62 |
63 | // MARK: - Adding of MonthViews
64 |
65 | /**
66 | Fills the scrollView of the contentController
67 | with the initial three monthViews
68 |
69 | - Parameter date: the Date object to pass
70 |
71 | */
72 | private func addInitialMonthViews(for date: Date) {
73 |
74 | //add the three monthViews to the scrollview
75 | addMonthView(presentedMonthView, withIdentifier: .presented)
76 | addMonthView(getPreviousMonthView(for: date), withIdentifier: .previous)
77 | addMonthView(getNextMonthView(for: date), withIdentifier: .next)
78 |
79 | }
80 |
81 |
82 | /**
83 | Adds the given monthView to the contentControllers scrollView and updates
84 | the given monthViews frame origin to place it in the correct position.
85 |
86 | - Parameter monthView: the MonthView to be added
87 | - Parameter identifier: can be .previous, .presented or .next
88 |
89 | */
90 | private func addMonthView(_ monthView: MonthView, withIdentifier identifier: MonthViewIdentifier) {
91 |
92 | monthView.frame.origin = CGPoint(x: scrollView.bounds.width * CGFloat(identifier.rawValue), y: 0)
93 | monthViews[identifier] = monthView
94 | scrollView.addSubview(monthView)
95 |
96 | }
97 |
98 | ///returns the previous monthView for a given date
99 | private func getPreviousMonthView(for date: Date) -> MonthView {
100 |
101 | let cal = Calendar.current
102 | var comps = cal.dateComponents([.month, .year], from: date)
103 | comps.month! -= 1
104 | let firstDateOfPreviousMonth = cal.date(from: comps)!
105 | let previousMonthView = MonthView(datePickerView: datePickerView, date: firstDateOfPreviousMonth, isPresented: false)
106 |
107 | //this is what gives new new monthView it's initial frame
108 | previousMonthView.frame = scrollView.frame
109 | previousMonthView.createWeekViews()
110 |
111 | return previousMonthView
112 | }
113 |
114 | ///returns the next monthView for a given date
115 | private func getNextMonthView(for date: Date) -> MonthView {
116 |
117 | let cal = Calendar.current
118 | var comps = cal.dateComponents([.month, .year], from: date)
119 | comps.month! += 1
120 | let firstDateOfNextMonth = cal.date(from: comps)!
121 | let nextMonthView = MonthView(datePickerView: datePickerView, date: firstDateOfNextMonth, isPresented: false)
122 |
123 | //this is what gives new new monthView it's initial frame
124 | nextMonthView.frame = scrollView.frame
125 | nextMonthView.createWeekViews()
126 |
127 | return nextMonthView
128 | }
129 |
130 | // MARK: - Reloading and replacing of MonthViews
131 |
132 | /**
133 | Updates the frame of the scrollView and reloads the monthViews present
134 | When called, scrolls to presented monthView
135 |
136 | - Parameter frame: the frame to update to
137 | - Note: is only called on initial load of datePicker
138 |
139 | */
140 | func updateScrollViewFrame(_ frame: CGRect) {
141 |
142 | if frame != .zero {
143 | scrollView.frame = frame
144 | scrollView.contentSize = CGSize(width: frame.size.width * 3, height: frame.size.height)
145 | }
146 |
147 | let monthViewFrame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
148 |
149 | for monthView in monthViews.values {
150 |
151 | monthView.reloadSubViewsWithFrame(monthViewFrame)
152 | }
153 |
154 | reloadMonthViews()
155 |
156 | if let presentedMonthView = monthViews[.presented] {
157 |
158 | //scroll to presented month
159 | scrollView.scrollRectToVisible(presentedMonthView.frame, animated: false)
160 | }
161 | }
162 |
163 |
164 | /**
165 | For each monthView this method updates the origin, then removes the monthView from the scrollView
166 | and adds them again.
167 | */
168 | private func reloadMonthViews() {
169 |
170 | for (identifier, monthView) in monthViews {
171 |
172 | monthView.frame.origin.x = CGFloat(identifier.rawValue) * scrollView.frame.width
173 |
174 | //this will not deinitialize, because there's still a reference to this monthView object
175 | monthView.removeFromSuperview()
176 | scrollView.addSubview(monthView)
177 | }
178 | }
179 |
180 | /**
181 | Replaces the identifier of a monthView with another identifier, so it's gets another role. The presented monthView will, for example, become the next monthView. The frame origin of the monthView involved will also be adjusted and scrolled into position if needed.
182 |
183 | - Parameter monthView: the monthView involved
184 | - Parameter identifier: the new identifier that the monthView will get
185 | - Parameter shouldScrollToPosition: a boolean that determines if the monthView's frame should scroll into position or not
186 |
187 | */
188 | private func replaceMonthViewIdentifier(_ monthView: MonthView, with identifier: MonthViewIdentifier, shouldScrollToPosition: Bool) {
189 |
190 | //adjust frame to the frame that comes with the new identifier (the new role)
191 | var monthViewFrame = monthView.frame
192 | monthViewFrame.origin.x = monthViewFrame.width * CGFloat(identifier.rawValue)
193 | monthView.frame = monthViewFrame
194 |
195 | //update the monthViews dictionary
196 | monthViews[identifier] = monthView
197 |
198 | //scroll the new 'presented' monthView into the presented position.
199 | //this will also cause the currentPage to be set to 1 again by the didScroll delegate method
200 | if shouldScrollToPosition {
201 | scrollView.scrollRectToVisible(monthViewFrame, animated: false)
202 | }
203 | }
204 |
205 |
206 | // MARK: - Scrolling MonthViews
207 |
208 | private func scrolledToPreviousMonth() {
209 |
210 | guard let previousMonthView = monthViews[.previous], let presentedMonthView = monthViews[.presented] else { return }
211 |
212 | //remove next monthView, this will be replaced by presented monthView
213 | monthViews[.next]?.removeFromSuperview()
214 |
215 | //replace previous monthView identifier with 'presented' identifier and set isPresented value
216 | replaceMonthViewIdentifier(previousMonthView, with: .presented, shouldScrollToPosition: true)
217 | previousMonthView.isPresented = true
218 |
219 | //replace presented monthView identifier with 'next' identifier and set isPresented value
220 | replaceMonthViewIdentifier(presentedMonthView, with: .next, shouldScrollToPosition: false)
221 | presentedMonthView.isPresented = false
222 |
223 | //add new monthView which will become the new 'previous' monthView
224 | addMonthView(getPreviousMonthView(for: previousMonthView.date), withIdentifier: .previous)
225 |
226 | }
227 |
228 |
229 | private func scrolledToNextMonth() {
230 |
231 | guard let nextMonthView = monthViews[.next], let presentedMonthView = monthViews[.presented] else { return }
232 |
233 | //remove previous monthView, this will be replaced by presented monthView
234 | monthViews[.previous]?.removeFromSuperview()
235 |
236 | //replace next monthView identifier with 'presented' identifier and set isPresented value
237 | replaceMonthViewIdentifier(nextMonthView, with: .presented, shouldScrollToPosition: true)
238 | nextMonthView.isPresented = true
239 |
240 | //replace presented monthView identifier with 'previous' identifier and set isPresented value
241 | replaceMonthViewIdentifier(presentedMonthView, with: .previous, shouldScrollToPosition: false)
242 | nextMonthView.isPresented = false
243 |
244 | //add new monthView which will become the new 'next' monthView
245 | addMonthView(getNextMonthView(for: nextMonthView.date), withIdentifier: .next)
246 | }
247 |
248 | // MARK: - UIScrollViewDelegate
249 |
250 | func scrollViewDidScroll(_ scrollView: UIScrollView) {
251 |
252 | let page = Int(floor((scrollView.contentOffset.x -
253 | scrollView.frame.width / 2) / scrollView.frame.width) + 1)
254 | if currentPage != page {
255 | currentPage = page
256 | }
257 |
258 | }
259 |
260 | func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
261 |
262 | //decide in which direction the user did scroll
263 | if decelerate {
264 | let rightBorderOfScrollView = scrollView.frame.width
265 | if scrollView.contentOffset.x <= rightBorderOfScrollView {
266 | scrollDirection = .toPrevious
267 | } else {
268 | scrollDirection = .toNext
269 | }
270 | }
271 | }
272 |
273 | func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
274 |
275 | if pageChanged {
276 | switch scrollDirection {
277 | case .toNext: scrolledToNextMonth()
278 | case .toPrevious: scrolledToPreviousMonth()
279 | case .none: break
280 | }
281 | }
282 |
283 | scrollDirection = .none
284 | }
285 |
286 |
287 |
288 | // MARK: - Presenting of monthViews
289 |
290 | func presentNextView() {
291 | if !isPresenting {
292 |
293 | guard let previous = monthViews[.previous], let presented = monthViews[.presented], let next = monthViews[.next] else { return }
294 |
295 | isPresenting = true
296 |
297 | UIView.animate(withDuration: 0.5, delay: 0, options: UIViewAnimationOptions(), animations: {
298 |
299 | //animate positions of monthViews
300 | previous.frame.origin.x -= self.scrollView.frame.width
301 | presented.frame.origin.x -= self.scrollView.frame.width
302 | next.frame.origin.x -= self.scrollView.frame.width
303 |
304 | }, completion: {_ in
305 |
306 | //replace identifiers
307 | self.replaceMonthViewIdentifier(presented, with: .previous, shouldScrollToPosition: false)
308 | self.replaceMonthViewIdentifier(next, with: .presented, shouldScrollToPosition: false)
309 | self.presentedMonthView = next
310 |
311 | //set isPresented value
312 | previous.isPresented = false
313 | self.presentedMonthView.isPresented = true
314 |
315 | //remove previous monthView
316 | previous.removeFromSuperview()
317 |
318 | //create and insert new 'next' monthView
319 | self.addMonthView(self.getNextMonthView(for: next.date), withIdentifier: .next)
320 | self.isPresenting = false
321 |
322 | })
323 | }
324 | }
325 |
326 |
327 | func presentPreviousView() {
328 | if !isPresenting {
329 |
330 | guard let previous = monthViews[.previous], let presented = monthViews[.presented], let next = monthViews[.next] else { return }
331 |
332 | isPresenting = true
333 |
334 | UIView.animate(withDuration: 0.5, delay: 0, options: UIViewAnimationOptions(), animations: {
335 |
336 | //animate positions of monthViews
337 | previous.frame.origin.x += self.scrollView.frame.width
338 | presented.frame.origin.x += self.scrollView.frame.width
339 | next.frame.origin.x += self.scrollView.frame.width
340 |
341 | }, completion: {_ in
342 |
343 | //replace identifiers
344 | self.replaceMonthViewIdentifier(presented, with: .next, shouldScrollToPosition: false)
345 | self.replaceMonthViewIdentifier(previous, with: .presented, shouldScrollToPosition: false)
346 | self.presentedMonthView = previous
347 |
348 | //set isPresented value
349 | next.isPresented = false
350 | self.presentedMonthView.isPresented = true
351 |
352 | //remove previous monthView
353 | next.removeFromSuperview()
354 |
355 | //create and insert new 'previous' monthView
356 | self.addMonthView(self.getPreviousMonthView(for: previous.date), withIdentifier: .previous)
357 | self.isPresenting = false
358 |
359 | })
360 | }
361 | }
362 |
363 | }
364 |
365 |
366 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/Classes/JBDatePickerDayView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JBDatePickerDayView.swift
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 13-10-16.
6 | // Copyright © 2016 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public final class JBDatePickerDayView: UIView {
12 |
13 | // MARK: - Properties
14 | private var index: Int!
15 | private var dayInfo: JBDay!
16 | weak private var weekView: JBDatePickerWeekView!
17 | weak private var monthView: JBDatePickerMonthView!
18 | weak var datePickerView: JBDatePickerView!
19 | public var date: Date?
20 |
21 | var isToday: Bool {
22 | return date == Date().stripped()
23 | }
24 |
25 | private var textLabel: UILabel!
26 | private weak var selectionView: JBDatePickerSelectionView?
27 |
28 | private let longPressArea: CGFloat = 40
29 | private var longPressAreaMaxX: CGFloat { return bounds.width + longPressArea }
30 | private var longPressAreaMaxY: CGFloat { return bounds.height + longPressArea }
31 | private var longPressAreaMin: CGFloat { return -longPressArea }
32 |
33 |
34 | // MARK: - Initialization
35 |
36 | init(datePickerView: JBDatePickerView, monthView: JBDatePickerMonthView, weekView: JBDatePickerWeekView, index: Int, dayInfo: JBDay) {
37 |
38 | self.datePickerView = datePickerView
39 | self.monthView = monthView
40 | self.weekView = weekView
41 | self.index = index
42 | self.dayInfo = dayInfo
43 |
44 | if let size = datePickerView.dayViewSize {
45 |
46 | let frame = CGRect(x: size.width * CGFloat(index), y: 0, width: size.width, height: size.height)
47 | super.init(frame: frame)
48 |
49 | }
50 | else{
51 | super.init(frame: .zero)
52 | }
53 |
54 | //backgroundColor = randomColor()
55 | self.date = dayInfo.date
56 | labelSetup()
57 |
58 | if dayInfo.isInMonth {
59 |
60 | //set default color
61 | textLabel.textColor = datePickerView.delegate?.colorForDayLabelInMonth
62 |
63 | //check date is selectable, if not selectable, set colour and don't add gestures
64 | guard datePickerView.dateIsSelectable(date: date) else {
65 | self.textLabel.textColor = datePickerView.delegate?.colorForUnavaibleDay
66 | return
67 | }
68 |
69 | }
70 | else{
71 |
72 | if let shouldShow = datePickerView.delegate?.shouldShowMonthOutDates {
73 | if shouldShow {
74 | textLabel.textColor = datePickerView.delegate?.colorForDayLabelOutOfMonth
75 |
76 | //check date is selectable, if not selectable, don't add gestures
77 | guard datePickerView.dateIsSelectable(date: date) else {return}
78 | }
79 | else{
80 | self.isUserInteractionEnabled = false
81 | self.textLabel.isHidden = true
82 | }
83 | }
84 | }
85 |
86 |
87 | //highlight current day. Must come before selection of selected date, because it would override the text color set by select()
88 | if isToday {
89 | self.textLabel.textColor = datePickerView.delegate?.colorForCurrentDay
90 | }
91 |
92 | //select selected day
93 | if date == datePickerView.dateToPresent.stripped() {
94 | guard self.dayInfo.isInMonth else { return }
95 | datePickerView.selectedDateView = self
96 | //self.backgroundColor = randomColor()
97 | }
98 |
99 | //add tapgesture recognizer
100 | let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dayViewTapped))
101 | self.addGestureRecognizer(tapGesture)
102 |
103 | //add longPress gesture recognizer
104 | let pressGesture = UILongPressGestureRecognizer(target: self, action: #selector(dayViewPressed(_:)))
105 | self.addGestureRecognizer(pressGesture)
106 |
107 | }
108 |
109 | public override init(frame: CGRect) {
110 | super.init(frame: frame)
111 | }
112 |
113 | required public init?(coder aDecoder: NSCoder) {
114 | fatalError("init(coder:) has not been implemented")
115 | }
116 |
117 |
118 | // MARK: - Label setup
119 |
120 | private func labelSetup() {
121 |
122 | textLabel = UILabel()
123 | textLabel.textAlignment = .center
124 | textLabel.translatesAutoresizingMaskIntoConstraints = false
125 | self.addSubview(textLabel)
126 |
127 | textLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
128 | textLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
129 |
130 | }
131 |
132 | private func setupLabelFont() {
133 |
134 | //get preferred font
135 | guard let preferredFont = datePickerView.delegate?.fontForDayLabel else { return }
136 |
137 | //get preferred size
138 | let preferredSize = preferredFont.fontSize
139 | let sizeOfFont: CGFloat
140 |
141 | //calculate fontsize to be used
142 | switch preferredSize {
143 | case .verySmall: sizeOfFont = min(frame.size.width, frame.size.height) / 3.5
144 | case .small: sizeOfFont = min(frame.size.width, frame.size.height) / 3
145 | case .medium: sizeOfFont = min(frame.size.width, frame.size.height) / 2.5
146 | case .large: sizeOfFont = min(frame.size.width, frame.size.height) / 2
147 | case .veryLarge: sizeOfFont = min(frame.size.width, frame.size.height) / 1.5
148 | }
149 |
150 | //get font to be used
151 | let fontToUse: UIFont
152 | switch preferredFont.fontName.isEmpty {
153 | case true:
154 | fontToUse = UIFont.systemFont(ofSize: sizeOfFont)
155 | case false:
156 | if let customFont = UIFont(name: preferredFont.fontName, size: sizeOfFont) {
157 | fontToUse = customFont
158 | }
159 | else {
160 | print("custom font '\(preferredFont.fontName)' for dayLabel not available. JBDatePicker will use system font instead")
161 | fontToUse = UIFont.systemFont(ofSize: sizeOfFont)
162 | }
163 | }
164 |
165 | textLabel.attributedText = NSMutableAttributedString(string: String(dayInfo.dayValue), attributes:[NSFontAttributeName: fontToUse])
166 |
167 | }
168 |
169 | public override func layoutSubviews() {
170 |
171 | textLabel.frame = bounds
172 | setupLabelFont()
173 | }
174 |
175 |
176 | // MARK: - Touch handling
177 |
178 | @objc public func dayViewTapped() {
179 | datePickerView.didTapDayView(dayView: self)
180 | }
181 |
182 | @objc public func dayViewPressed(_ gesture: UILongPressGestureRecognizer) {
183 |
184 | //if selectedDateView exists and is self, return. Long pressing shouldn't do anything on selected day.
185 | if let selectedDate = datePickerView.selectedDateView {
186 | guard selectedDate != self else { return }
187 | }
188 |
189 | let location = gesture.location(in: self)
190 |
191 | switch gesture.state {
192 | case .began:
193 | semiSelect(animated: true)
194 | case .ended:
195 | if let selView = selectionView {
196 | selView.removeFromSuperview()
197 | }
198 | datePickerView.didTapDayView(dayView: self)
199 |
200 | case .changed:
201 |
202 | if !(longPressAreaMin...longPressAreaMaxX).contains(location.x) || !(longPressAreaMin...longPressAreaMaxY).contains(location.y) {
203 |
204 | semiDeselect(animated: true)
205 |
206 | //this will cancel the longpress gesture (and enable it again for the next time)
207 | gesture.isEnabled = false
208 | gesture.isEnabled = true
209 | }
210 |
211 | default:
212 | break
213 | }
214 | }
215 |
216 | // MARK: - Reloading
217 |
218 | public func reloadContent() {
219 | textLabel.frame = bounds
220 | setupLabelFont()
221 |
222 | //reload selectionView
223 | if let selView = selectionView {
224 |
225 | selView.frame = textLabel.frame
226 | selView.setNeedsDisplay()
227 | }
228 |
229 | }
230 |
231 |
232 | // MARK: - Selection & Deselection
233 |
234 | func select() {
235 |
236 | let selView = JBDatePickerSelectionView(dayView: self, frame: self.bounds, isSemiSelected: false)
237 | insertSubview(selView, at: 0)
238 |
239 | selView.translatesAutoresizingMaskIntoConstraints = false
240 |
241 | //pin selectionView horizontally and make it's width equal to the height of the datePickerview. This way it stays centered while rotating the device.
242 | selView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
243 | selView.widthAnchor.constraint(equalTo: heightAnchor).isActive = true
244 |
245 | //pint it to the left and right
246 | selView.topAnchor.constraint(equalTo: topAnchor).isActive = true
247 | selView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
248 |
249 | selectionView = selView
250 |
251 | //set textcolor to selected state
252 | textLabel.textColor = datePickerView.delegate?.colorForSelelectedDayLabel
253 | }
254 |
255 | func deselect() {
256 |
257 | if let selectionView = selectionView {
258 | selectionView.removeFromSuperview()
259 | }
260 |
261 | //set textcolor to default color
262 | switch isToday {
263 | case true:
264 | textLabel.textColor = datePickerView.delegate?.colorForCurrentDay
265 | case false:
266 | textLabel.textColor = dayInfo.isInMonth ? datePickerView.delegate?.colorForDayLabelInMonth : datePickerView.delegate?.colorForDayLabelOutOfMonth
267 | }
268 | }
269 |
270 | /**
271 | creates and shows a selection circle with a semi selected color
272 |
273 | - Parameter animated: if true, this will fade in the circle
274 |
275 | */
276 | private func semiSelect(animated: Bool) {
277 |
278 | if let selectionView = selectionView {
279 | if animated {
280 | insertCircleViewAnimated(selectionView: selectionView)
281 | }
282 | else{
283 | insertSubview(selectionView, at: 0)
284 | }
285 | }
286 | else {
287 | let selView = JBDatePickerSelectionView(dayView: self, frame: self.bounds, isSemiSelected: true)
288 | if animated {
289 | insertCircleViewAnimated(selectionView: selView)
290 | }
291 | else{
292 | insertSubview(selView, at: 0)
293 | }
294 | selectionView = selView
295 | }
296 | }
297 |
298 | /**
299 | removes semi selected selection circle and removes circle from superview
300 |
301 | - Parameter animated: if true, this will fade the circle out before removal
302 |
303 | */
304 | private func semiDeselect(animated: Bool) {
305 |
306 | switch animated {
307 | case true:
308 | removeCircleViewAnimated()
309 | case false:
310 | selectionView?.removeFromSuperview()
311 | }
312 | }
313 |
314 | ///just a helper that inserts the selection circle animated
315 | private func insertCircleViewAnimated(selectionView: JBDatePickerSelectionView) {
316 |
317 | selectionView.alpha = 0.0
318 | insertSubview(selectionView, at: 0)
319 |
320 | UIView.animate(withDuration: 0.2, animations: {
321 |
322 | selectionView.alpha = 1.0
323 |
324 | })
325 | }
326 |
327 | ///just a helper that removes the selection circle animated
328 | private func removeCircleViewAnimated() {
329 |
330 | UIView.animate(withDuration: 0.2, animations: {
331 |
332 | self.selectionView?.alpha = 0.0
333 |
334 | }, completion: {_ in
335 | self.selectionView?.removeFromSuperview()
336 | })
337 | }
338 |
339 |
340 | }
341 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/Classes/JBDatePickerEnums.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JBDatePickerEnums.swift
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 09-10-16.
6 | // Copyright © 2016 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum MonthViewIdentifier: Int { case previous, presented, next }
12 | enum JBScrollDirection { case none, toNext, toPrevious }
13 |
14 | //In a calendar, day, week, weekday, month, and year numbers are generally 1-based. So Sunday is 1.
15 | public enum JBWeekDay: Int { case sunday = 1, monday, tuesday, wednesday, thursday, friday, saturday }
16 | public enum JBSelectionShape { case circle, square, roundedRect }
17 | public enum JBFontSize { case verySmall, small, medium, large, veryLarge }
18 |
19 | //only for debugging
20 | func randomColor() -> UIColor{
21 |
22 | let red = CGFloat(randomInt(min: 0, max: 255)) / 255
23 | let green = CGFloat(randomInt(min: 0, max: 255)) / 255
24 | let blue = CGFloat(randomInt(min: 0, max: 255)) / 255
25 | let randomColor = UIColor(red: red, green: green, blue: blue, alpha: 1)
26 |
27 | return randomColor
28 | }
29 |
30 | func randomInt(min: Int, max:Int) -> Int {
31 | return min + Int(arc4random_uniform(UInt32(max - min + 1)))
32 | }
33 |
34 | func randomFloat(min: Int, max:Int) -> Int {
35 | return min + Int(arc4random_uniform(UInt32(max - min + 1)))
36 | }
37 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/Classes/JBDatePickerManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JBDatePickerManager.swift
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 12-10-16.
6 | // Copyright © 2016 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | final class JBDatePickerManager {
12 |
13 | // MARK: - Properties
14 | private var components: DateComponents
15 | private unowned let datePickerView: JBDatePickerView
16 | private var calendar: Calendar = .current
17 | private var currentDate: Date = Date()
18 | private var startdayOfWeek: Int
19 |
20 |
21 |
22 | // MARK: - Initialization
23 |
24 | init(datePickerView: JBDatePickerView) {
25 | self.datePickerView = datePickerView
26 | self.components = calendar.dateComponents([.month, .day], from: currentDate)
27 | startdayOfWeek = (datePickerView.delegate?.firstWeekDay.rawValue)!
28 |
29 | //let user preference prevail about default
30 | calendar.firstWeekday = startdayOfWeek
31 |
32 | }
33 |
34 |
35 | // MARK: - Date information
36 |
37 | /**
38 | Gets the startdate and the enddate of the month of a certain date and also the amount of weeks
39 | for that month and all the days with their weekViewIndex and value
40 |
41 | - Parameter date: the Date object of the month that we want the info about
42 | - Returns: a tuple holding the startdate, the enddate, the number of weeks and
43 | an array holding dictionaries with the weekDayIndex as key and a JBDay object as value.
44 | The JBDay object holds the value (like 17) and a bool that determines that the day involved
45 | is included in the month or not.
46 | */
47 | func getMonthInfoForDate(_ date: Date) -> (monthStartDay: Date, monthEndDay: Date, numberOfWeeksInMonth: Int, weekDayInfo: [[Int:JBDay]]) {
48 |
49 | var components = calendar.dateComponents([.year, .month, .weekOfMonth], from: date)
50 |
51 | //first day of the month
52 | components.day = 1
53 | let monthValue = components.month!
54 | let yearValue = components.year!
55 | let monthStartDay = calendar.date(from: components)!
56 |
57 | //last day of the month
58 | components.month! += 1
59 | let nextMonthValue = components.month!
60 | let nextYearValue = components.year!
61 | components.day! -= 1
62 | let monthEndDay = calendar.date(from: components)!
63 |
64 | //reset components
65 | components = calendar.dateComponents([.year, .month, .weekOfMonth], from: date)
66 |
67 | //last day of the previous month. We have to substract two because we went up to get the next month
68 | components.month! -= 1
69 | let previousMonthEndDay = calendar.date(from: components)!
70 | let previousMonthValue = components.month!
71 | let previousYearValue = components.year!
72 |
73 | //count of weeks in month
74 | var numberOfWeeksInMonth: Int = calendar.range(of: .weekOfMonth, in: .month, for: date)!.count
75 |
76 | //get dates that fall within the month
77 | let datesInRange = calendar.range(of: .day, in: .month, for: date)
78 | var monthDatesArray = [Int]()
79 | for value in 1.. 0 {
91 | for value in 1...numberOfDaysInNextMonth {
92 | nextMonthDatesArray.append(value)
93 | }
94 | }
95 |
96 | //get dates that fall within previous month
97 | var previousMonthDatesArray = [Int]()
98 | let datesInRangeOfPreviousMonth = calendar.range(of: .day, in: .month, for: previousMonthEndDay)
99 | let numberOfDaysInPreviousMonth = 7 - (7 - firstDayIndexInWeekView)
100 | let subRangeLowerBound = (datesInRangeOfPreviousMonth?.upperBound)! - numberOfDaysInPreviousMonth
101 | let upperBound = (datesInRangeOfPreviousMonth?.upperBound)!
102 |
103 | if subRangeLowerBound < upperBound {
104 | for value in subRangeLowerBound.. numberOfWeeksInMonth * 7 {
112 | numberOfWeeksInMonth += 1
113 | }
114 |
115 | //create array of dictionaries that we well return in the end
116 | var weeksInMonthInformationToReturn = [[Int:JBDay]]()
117 |
118 | //this value holds 0 to the number of days in a month
119 | var dayOfMonthIndex: Int = 0
120 |
121 | for weekIndex in 0..= 1 else {continue}
141 |
142 | dayOfWeekIndex = firstDayIndexInWeekView
143 |
144 | for _ in 0.. DateComponents {
215 |
216 | return calendar.dateComponents([.year, .month, .weekOfMonth, .day], from: date)
217 |
218 | }
219 |
220 | /**
221 | This is a correctionFactor. A day that falls on a thursday will always have weekday 5. Sunday is 1, Saterday is 7. However, in the weekView, this will be indexnumber 4 when week starts at sunday, and indexnumber 3 when week starts on a monday. If the week was to start on a thursday, the correctionfactor will be 5. Because this day will get index 0 in the weekView in that case.
222 | The function basically returns this dictionary: [-6:1, -5:2, -4:3, -3:4, -2:5, -1:6, 0:0, 1:1, 2:2, 3:3, 4:4, 5:5, 6:6]
223 | */
224 | private func indexForDate(_ weekDay: Int) -> Int {
225 |
226 | let basicIndex = weekDay - startdayOfWeek
227 |
228 | if basicIndex < 0 {
229 | return basicIndex + 7
230 | }
231 | else{
232 | return basicIndex
233 | }
234 |
235 | }
236 |
237 |
238 |
239 | }
240 |
241 |
242 |
243 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/Classes/JBDatePickerMonthView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JBDatePickerMonthView.swift
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 09-10-16.
6 | // Copyright © 2016 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public final class JBDatePickerMonthView: UIStackView {
12 |
13 |
14 | // MARK: - Properties
15 |
16 | weak var datePickerView: JBDatePickerView!
17 | var date: Date!
18 | var isPresented: Bool! {
19 |
20 | willSet{
21 | if newValue == true{
22 | //this will eventually call the delegate
23 | datePickerView.presentedMonthView = self
24 | }
25 | }
26 | }
27 |
28 | public var monthDescription: String!
29 | var monthInfo: (monthStartDay: Date, monthEndDay: Date, numberOfWeeksInMonth: Int, weekDayInfo: [[Int:JBDay]])!
30 | var numberOfWeeks: Int!
31 | var weekViews: [JBDatePickerWeekView]!
32 |
33 | // MARK: - Initialization
34 |
35 | init(datePickerView: JBDatePickerView, date: Date, isPresented: Bool) {
36 |
37 | self.datePickerView = datePickerView
38 | self.date = date
39 | self.isPresented = isPresented
40 | super.init(frame: .zero)
41 |
42 | self.axis = .vertical
43 | self.distribution = .fillEqually
44 |
45 | //self.backgroundColor = randomColor()
46 |
47 | let datePickerManager = datePickerView.manager
48 | self.monthInfo = datePickerManager?.getMonthInfoForDate(self.date)
49 | self.numberOfWeeks = monthInfo.numberOfWeeksInMonth
50 | self.monthDescription = datePickerView.monthDescriptionForDate(self.date)
51 |
52 | //this is needed to inform the delegate about the presented month
53 | //the property observer isn't called on initialization
54 | if isPresented {
55 | datePickerView.presentedMonthView = self
56 | }
57 |
58 | }
59 |
60 | override init(frame: CGRect) {
61 | super.init(frame: frame)
62 | }
63 |
64 | required public init(coder aDecoder: NSCoder) {
65 | fatalError("init(coder:) has not been implemented")
66 | }
67 |
68 |
69 | // MARK: - Reloading
70 |
71 | func reloadSubViewsWithFrame(_ frame: CGRect) {
72 | self.frame = frame
73 |
74 | }
75 |
76 | // MARK: - Create weekviews
77 |
78 | func createWeekViews() {
79 |
80 | weekViews = [JBDatePickerWeekView]()
81 |
82 | for i in 0...5 {
83 | let weekView = JBDatePickerWeekView(datePickerView: datePickerView, monthView: self, index: i)
84 | weekViews.append(weekView)
85 | self.addArrangedSubview(weekView)
86 | }
87 | }
88 |
89 |
90 |
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/Classes/JBDatePickerSelectionView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JBDatePickerSelectionView.swift
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 19-10-16.
6 | // Copyright © 2016 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class JBDatePickerSelectionView: UIView {
12 |
13 | // MARK: - Computed properties
14 |
15 | private let padding: CGFloat = 10
16 |
17 | private var radius: CGFloat {
18 |
19 | return (min(frame.height, frame.width) - padding) / 2
20 | }
21 |
22 |
23 | private var circlePath: CGPath {
24 | let arcCenter = CGPoint(x: frame.width / 2, y: frame.height / 2)
25 | let startAngle = CGFloat(0)
26 | let endAngle = CGFloat.pi * 2.0
27 | let clockwise = true
28 | let path = UIBezierPath(arcCenter: arcCenter, radius: radius,
29 | startAngle: startAngle, endAngle: endAngle, clockwise: clockwise).cgPath
30 |
31 | return path
32 |
33 | }
34 |
35 | private var squarePath: CGPath {
36 |
37 | let pathSize = radius * 2
38 | let center = CGPoint(x: frame.width / 2, y: frame.height / 2)
39 | let startPoint = CGPoint(x: center.x - radius, y: center.y - radius)
40 | let path = UIBezierPath(rect: CGRect(x: startPoint.x, y: startPoint.y, width: pathSize, height: pathSize))
41 |
42 | return path.cgPath
43 | }
44 |
45 | private var roundedRectPath: CGPath {
46 |
47 | let pathSize = radius * 2
48 | let cornerRadiusForShape = radius / 2
49 | let center = CGPoint(x: frame.width / 2, y: frame.height / 2)
50 | let startPoint = CGPoint(x: center.x - radius, y: center.y - radius)
51 | let path = UIBezierPath(roundedRect: CGRect(x: startPoint.x, y: startPoint.y, width: pathSize, height: pathSize), cornerRadius: cornerRadiusForShape)
52 |
53 | return path.cgPath
54 | }
55 |
56 | private var fillColor: UIColor {
57 |
58 | switch isSemiSelected {
59 | case true:
60 | return (dayView.datePickerView.delegate?.colorForSemiSelectedSelectionCircle)!
61 | case false:
62 | switch dayView.isToday {
63 | case true:
64 | return (dayView.datePickerView.delegate?.colorForSelectionCircleForToday)!
65 | case false:
66 | return (dayView.datePickerView.delegate?.colorForSelectionCircleForOtherDate)!
67 | }
68 | }
69 | }
70 |
71 | private var selectionPath: CGPath {
72 |
73 | guard let delegate = dayView.datePickerView.delegate else { return circlePath }
74 |
75 | switch delegate.selectionShape {
76 | case .circle:
77 | return circlePath
78 | case .square:
79 | return squarePath
80 | case .roundedRect:
81 | return roundedRectPath
82 | }
83 | }
84 |
85 | // MARK: - Stored properties
86 |
87 | private unowned let dayView: JBDatePickerDayView
88 | var isSemiSelected: Bool
89 |
90 | // MARK: - Initialization
91 |
92 | init(dayView: JBDatePickerDayView, frame: CGRect, isSemiSelected: Bool) {
93 | self.dayView = dayView
94 | self.isSemiSelected = isSemiSelected
95 | super.init(frame: frame)
96 | backgroundColor = .clear
97 | shapeLayer().fillColor = fillColor.cgColor
98 | }
99 |
100 | required init?(coder aDecoder: NSCoder) {
101 | fatalError("init(coder:) has not been implemented")
102 | }
103 |
104 | override class var layerClass: AnyClass {
105 | return CAShapeLayer.self
106 | }
107 |
108 | private func shapeLayer() -> CAShapeLayer {
109 | return layer as! CAShapeLayer
110 | }
111 |
112 | // MARK: - Drawing
113 |
114 | override func layoutSubviews() {
115 | super.layoutSubviews()
116 |
117 | shapeLayer().path = selectionPath
118 | }
119 |
120 |
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/Classes/JBDatePickerView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JBDatePickerView.swift
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 09-10-16.
6 | // Copyright © 2016 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | typealias ContentController = JBDatePickerContentVC
12 | typealias Manager = JBDatePickerManager
13 | typealias MonthView = JBDatePickerMonthView
14 | typealias WeekDaysView = JBDatePickerWeekDaysView
15 |
16 | public final class JBDatePickerView: UIView {
17 |
18 | // MARK: - Properties
19 |
20 | var contentController: ContentController!
21 | var manager: Manager!
22 | var weekViewSize: CGSize!
23 | var dayViewSize: CGSize!
24 | var dateToPresent: Date!
25 | var weekdaysView: WeekDaysView!
26 | fileprivate var dateFormatter = DateFormatter()
27 |
28 | public weak var delegate: JBDatePickerViewDelegate? {
29 | didSet{
30 | commonInit()
31 | }
32 | }
33 |
34 | public var presentedMonthView: JBDatePickerMonthView! {
35 | didSet {
36 | delegate?.didPresentOtherMonth(presentedMonthView)
37 | layoutIfNeeded()
38 | }
39 | }
40 |
41 | public var selectedDateView: JBDatePickerDayView! {
42 |
43 | willSet {
44 | selectedDateView?.deselect()
45 | }
46 |
47 | didSet {
48 | selectedDateView.select()
49 | dateToPresent = selectedDateView.date
50 | }
51 | }
52 |
53 |
54 | // MARK: - Initialization
55 |
56 | private func commonInit() {
57 |
58 | //initialize datePickerManager
59 | manager = Manager(datePickerView: self)
60 |
61 | //initialize contentController with preferred (or current) date
62 | dateToPresent = delegate?.dateToShow ?? Date()
63 | contentController = ContentController(datePickerView: self, frame: bounds, presentedDate: dateToPresent)
64 |
65 | //add scrollView
66 | addSubview(contentController.scrollView)
67 | contentController.scrollView.translatesAutoresizingMaskIntoConstraints = false
68 |
69 | //create and add weekdayView
70 | weekdaysView = WeekDaysView(datePickerView: self)
71 | addSubview(weekdaysView)
72 | weekdaysView.translatesAutoresizingMaskIntoConstraints = false
73 |
74 | //pin datePickerView to left, right and bottom of scrollView.
75 | leftAnchor.constraint(equalTo: contentController.scrollView.leftAnchor).isActive = true
76 | rightAnchor.constraint(equalTo: contentController.scrollView.rightAnchor).isActive = true
77 | bottomAnchor.constraint(equalTo: contentController.scrollView.bottomAnchor).isActive = true
78 |
79 | //pin weekDaysView to left, right and top of datePickerView
80 | weekdaysView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
81 | weekdaysView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
82 | weekdaysView.topAnchor.constraint(equalTo: topAnchor).isActive = true
83 |
84 | //add heightconstraint for weekDaysview
85 | weekdaysView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: (delegate?.weekDaysViewHeightRatio)!).isActive = true
86 |
87 | }
88 | }
89 |
90 |
91 | extension JBDatePickerView {
92 |
93 | /**
94 | Updates the layout of JBDatePicker. This makes sure that elements in JBDatePicker that need a frame, will get their frame.
95 | */
96 | public func updateLayout() {
97 |
98 | guard delegate != nil else {
99 |
100 | print("JBDatePickerView warning: there is no delegate set. This is needed for JBDatePickerView to work correctly")
101 | return
102 | }
103 |
104 | guard weekdaysView != nil else { return }
105 |
106 | let width = bounds.size.width
107 | let availableRectForScrollView = CGRect(x: bounds.origin.x, y: weekdaysView.bounds.height, width: width, height: bounds.size.height - weekdaysView.bounds.height)
108 |
109 | //adjust scrollView frame to available space
110 | contentController.updateScrollViewFrame(availableRectForScrollView)
111 | }
112 |
113 | public override func layoutSubviews() {
114 | super.layoutSubviews()
115 |
116 | updateLayout()
117 | }
118 | }
119 |
120 |
121 | extension JBDatePickerView {
122 |
123 | func monthDescriptionForDate(_ date: Date) -> String {
124 |
125 | let monthFormatString = "MMMM yyyy"
126 | dateFormatter.dateFormat = monthFormatString
127 | if let preferredLanguage = Bundle.main.preferredLocalizations.first {
128 | if delegate?.shouldLocalize == true {
129 | dateFormatter.locale = Locale(identifier: preferredLanguage)
130 | }
131 | }
132 |
133 | return dateFormatter.string(from: date)
134 | }
135 |
136 | func dateIsSelectable(date: Date?) -> Bool {
137 |
138 | //default true, pass check to delegate if exists
139 | return delegate?.shouldAllowSelectionOfDay(date) ?? true
140 | }
141 |
142 | ///this will call the delegate as well as set the selectedDate on the datePicker.
143 | func didTapDayView(dayView: JBDatePickerDayView) {
144 | selectedDateView = dayView
145 | delegate?.didSelectDay(dayView)
146 | }
147 | }
148 |
149 |
150 | extension JBDatePickerView {
151 |
152 | ///scrolls the next month into the visible area and creates an new 'next' month waiting in line.
153 | public func loadNextView() {
154 | contentController.presentNextView()
155 | }
156 |
157 | ///scrolls the previous month into the visible area and creates an new 'previous' month waiting in line.
158 | public func loadPreviousView() {
159 | contentController.presentPreviousView()
160 | }
161 |
162 | }
163 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/Classes/JBDatePickerViewDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JBDatePickerViewDelegate.swift
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 17-10-16.
6 | // Copyright © 2016 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public protocol JBDatePickerViewDelegate: class {
12 |
13 | /**
14 | Is called when the user selected a day
15 | - parameter dayView: the dayView the user selected
16 | - note:
17 | Implementing this method is mandatory
18 | */
19 | func didSelectDay(_ dayView: JBDatePickerDayView)
20 |
21 | /**
22 | Is called when the user swiped (or manually moved) to another month
23 | - parameter monthView: the monthView that is now 'on screen'
24 | - note:
25 | Implementing this method is optional.
26 | */
27 | func didPresentOtherMonth(_ monthView: JBDatePickerMonthView)
28 |
29 | /**
30 | Is called to check if any particular date is selectable by the picker
31 | - parameter date: the date to check if allowed
32 | - note:
33 | Implementing this method is optional.
34 | */
35 | func shouldAllowSelectionOfDay(_ date: Date?) -> Bool
36 |
37 | /**
38 | Is called when setting up the calendar view as an override point for customization of weekday labels
39 | - parameter calendar: calendar instance used by the calendar view
40 | - note:
41 | Implementing this method is optional.
42 | */
43 | func weekdaySymbols(for calendar: Calendar) -> [String]
44 |
45 | /**
46 | Sets the day that determines which month is shown on initial load
47 | - note:
48 | Implementing this variable is optional. It's default is set the current date.
49 | */
50 | var dateToShow: Date {get}
51 |
52 |
53 | /**
54 | Sets the first day of the week.
55 | - note:
56 | Implementing this variable is optional. It's default is set to the locale.
57 | */
58 | var firstWeekDay: JBWeekDay {get}
59 |
60 |
61 | /**
62 | Determines if a month should also show the dates of the previous and next month
63 | - note:
64 | Implementing this variable is optional. It's default is set to true.
65 | */
66 | var shouldShowMonthOutDates: Bool {get}
67 |
68 | /**
69 | Determines if the weekday symbols and the month description should follow available localizations
70 | - note:
71 | Implementing this variable is optional. It's default is set to false. This means that the weekday symbols
72 | and the month description will be in the same language as the device language. If you want it to conform to the
73 | localization of your app, return true here. If you return true and your app is not localized, the weekday symbols and
74 | the month description will be in the development language.
75 | */
76 | var shouldLocalize: Bool {get}
77 |
78 |
79 | // MARK: - General appearance properties
80 |
81 | /**
82 | Determines the height ratio of the weekDaysView compared to the total height
83 |
84 | - note:
85 | Implementing this variable is optional. It's default is set to 0.1 (10%).
86 |
87 | */
88 | var weekDaysViewHeightRatio: CGFloat {get}
89 |
90 | /**
91 | Determines the shape that is used to indicate a selected date. Possiblilities are:
92 | .circle, .square, .roundedRect
93 |
94 | - note:
95 | Implementing this variable is optional. It's default is set to .circle.
96 |
97 | */
98 | var selectionShape: JBSelectionShape { get }
99 |
100 | /**
101 | font of the date labels. Defaults to systemfont with a medium size.
102 |
103 | - Note: you can use any UIFont name you want, as long as it is available. If it's not available, JBDatePicker will
104 | use the systemfont instead. If you want to use the systemfont but customize it's size, use an empty string as the
105 | fontname.
106 |
107 | ## Usage Example: ##
108 | ````
109 | //set custom font
110 | var fontForDayLabel: JBFont {
111 | return JBFont(name: "AvenirNext-MediumItalic", size: .medium)
112 | }
113 |
114 | //set system font with custom size
115 | var fontForDayLabel: JBFont {
116 | return JBFont(name: "", size: .large)
117 | }
118 |
119 | ````
120 | */
121 | var fontForDayLabel: JBFont { get }
122 |
123 |
124 | // MARK: - Text Color appearance properties
125 |
126 | ///color of any date label text that falls within the presented month
127 | var colorForDayLabelInMonth: UIColor { get }
128 |
129 | ///color of any date label text that falls out of the presented month and is part of the next or previous (but not presented) month
130 | var colorForDayLabelOutOfMonth: UIColor { get }
131 |
132 | ///color of any date label text that occurs outside the allowed selectable days (day earlier than earliest selectable or later than last selectable)
133 | var colorForUnavaibleDay: UIColor { get }
134 |
135 | ///color of the 'today' date label text
136 | var colorForCurrentDay: UIColor { get }
137 |
138 | ///color of any label text that is selected
139 | var colorForSelelectedDayLabel: UIColor { get }
140 |
141 |
142 | // MARK: - WeekdaysView appearance properties
143 |
144 | ///color of the bar which shows the 'mon' to 'sun' labels. Defaults to green.
145 | var colorForWeekDaysViewBackground: UIColor { get }
146 |
147 | ///color of the labels in the WeekdaysView bar that say 'mon' to 'sun'. Defaults to white.
148 | var colorForWeekDaysViewText: UIColor { get }
149 |
150 |
151 | /**
152 | font of the labels in the WeekdaysView bar that say 'mon' to 'sun'. Defaults to systemfont with
153 | a medium size.
154 |
155 | - Note: you can use any UIFont name you want, as long as it is available. If it's not available, JBDatePicker will
156 | use the systemfont instead. If you want to use the systemfont but customize it's size, use an empty string as the
157 | fontname.
158 |
159 | ## Usage Example: ##
160 | ````
161 | //set custom font
162 | var fontForWeekDaysViewText: JBFont {
163 | return JBFont(name: "AvenirNext-MediumItalic", size: .medium)
164 | }
165 |
166 | //set system font with custom size
167 | var fontForWeekDaysViewText: JBFont {
168 | return JBFont(name: "", size: .large)
169 | }
170 |
171 | ````
172 | */
173 | var fontForWeekDaysViewText: JBFont { get }
174 |
175 |
176 | // MARK: - Selection Color appearance properties
177 |
178 | ///color of the selection circle for dates that aren't today
179 | var colorForSelectionCircleForOtherDate: UIColor { get }
180 |
181 | ///color of the selection circle for today
182 | var colorForSelectionCircleForToday: UIColor { get }
183 |
184 | ///color of the semi selected selection circle (that shows on a long press)
185 | var colorForSemiSelectedSelectionCircle: UIColor { get }
186 |
187 | }
188 |
189 | /**
190 | This protocol extension is used to make some of the delegate methods and variables optional by giving them a default implementation or value.
191 | */
192 | public extension JBDatePickerViewDelegate {
193 |
194 | public func didPresentOtherMonth(_ monthView: JBDatePickerMonthView) {}
195 | public func shouldAllowSelectionOfDay(_ date: Date?) -> Bool { return true }
196 | public func weekdaySymbols(for calendar: Calendar) -> [String] { return calendar.shortStandaloneWeekdaySymbols }
197 |
198 | // MARK: - General defaults
199 |
200 | public var dateToShow: Date { return Date()}
201 | public var firstWeekDay: JBWeekDay {
202 |
203 | if let calendarValue = JBWeekDay(rawValue: Calendar.current.firstWeekday){
204 | return calendarValue
205 | }
206 | else {
207 | return .monday
208 | }
209 | }
210 |
211 | public var shouldShowMonthOutDates: Bool { return true }
212 | public var shouldLocalize: Bool { return false }
213 | public var weekDaysViewHeightRatio: CGFloat { return 0.1 }
214 | public var selectionShape: JBSelectionShape { return .circle }
215 | public var fontForDayLabel: JBFont { return JBFont() }
216 |
217 | // MARK: - Color defaults
218 |
219 | public var colorForDayLabelInMonth: UIColor { return .darkGray }
220 | public var colorForDayLabelOutOfMonth: UIColor { return .lightGray }
221 | public var colorForUnavaibleDay: UIColor { return .lightGray }
222 | public var colorForCurrentDay: UIColor { return .red }
223 | public var colorForSelelectedDayLabel: UIColor { return .white }
224 | public var colorForWeekDaysViewBackground: UIColor { return UIColor(red: 81.0/255.0, green: 182.0/255.0, blue: 185.0/255.0, alpha: 1.0) }
225 | public var colorForWeekDaysViewText: UIColor { return .white }
226 | public var fontForWeekDaysViewText: JBFont { return JBFont() }
227 | public var colorForSelectionCircleForOtherDate: UIColor { return UIColor(red: 81.0/255.0, green: 182.0/255.0, blue: 185.0/255.0, alpha: 1.0) }
228 | public var colorForSelectionCircleForToday: UIColor { return UIColor(red: 255.0/255.0, green: 98.0/255.0, blue: 89.0/255.0, alpha: 1.0) }
229 | public var colorForSemiSelectedSelectionCircle: UIColor { return UIColor(red: 240/255, green: 240/255, blue: 240/255, alpha: 1.0) }
230 | }
231 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/Classes/JBDatePickerWeekDaysView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JBDatePickerWeekDaysView.swift
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 24-10-16.
6 | // Copyright © 2016 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public final class JBDatePickerWeekDaysView: UIStackView {
12 |
13 | // MARK: - Properties
14 | private weak var datePickerView: JBDatePickerView!
15 | private var firstWeekDay: JBWeekDay!
16 | private var weekdayNameSymbols = [String]()
17 | private var weekdayLabels = [UILabel]()
18 | private var weekdayLabelTextColor: UIColor!
19 |
20 |
21 | // MARK: - Initialization
22 | public init(datePickerView: JBDatePickerView) {
23 | self.datePickerView = datePickerView
24 | super.init(frame: .zero)
25 | setup()
26 | }
27 |
28 | public override init(frame: CGRect) {
29 | super.init(frame: frame)
30 | setup()
31 | }
32 |
33 | public required init(coder aDecoder: NSCoder) {
34 | super.init(coder: aDecoder)
35 | setup()
36 | }
37 |
38 | // MARK: - Setup
39 |
40 | private func setup() {
41 | guard datePickerView != nil else {return}
42 |
43 | //stackView setup
44 | self.axis = .horizontal
45 | self.distribution = .fillEqually
46 | self.translatesAutoresizingMaskIntoConstraints = false
47 |
48 | //get preferences
49 | firstWeekDay = datePickerView.delegate?.firstWeekDay
50 |
51 | //setup appearance
52 | self.weekdayLabelTextColor = datePickerView.delegate?.colorForWeekDaysViewText
53 |
54 | //get weekday name symbols
55 | var cal = Calendar.current
56 | if let preferredLanguage = Bundle.main.preferredLocalizations.first {
57 | if datePickerView.delegate?.shouldLocalize == true {
58 | cal.locale = Locale(identifier: preferredLanguage)
59 | }
60 | }
61 | weekdayNameSymbols = datePickerView.delegate?.weekdaySymbols(for: cal) ?? cal.shortStandaloneWeekdaySymbols
62 |
63 | //adjust order of weekDayNameSymbols if needed
64 | let firstWeekdayIndex = firstWeekDay.rawValue - 1
65 | if firstWeekdayIndex >= 0 {
66 |
67 | //create new array order by slicing according to firstweekday
68 | let sliceOne = weekdayNameSymbols[firstWeekdayIndex...6]
69 | let sliceTwo = weekdayNameSymbols[0..
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DatePicker/JBDatePicker/JBDatePicker.h:
--------------------------------------------------------------------------------
1 | //
2 | // JBDatePicker.h
3 | // JBDatePicker
4 | //
5 | // Created by Joost van Breukelen on 04-04-17.
6 | // Copyright © 2017 Joost van Breukelen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for JBDatePicker.
12 | FOUNDATION_EXPORT double JBDatePickerVersionNumber;
13 |
14 |
15 |
16 | //! Project version string for JBDatePicker.
17 | FOUNDATION_EXPORT const unsigned char JBDatePickerVersionString[];
18 |
19 | // In this header, you should import all the public headers of your framework using statements like #import
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/DidYouKnowFacts.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "date": "Jan 1",
4 | "fact": " 11% of people are left handed"
5 | },
6 | {
7 | "date": "Jan 2",
8 | "fact": " August has the highest percentage of births"
9 | },
10 | {
11 | "date": "Jan 3",
12 | "fact": " unless food is mixed with saliva you can't taste it"
13 | },
14 | {
15 | "date": "Jan 4",
16 | "fact": " the average person falls asleep in 7 minutes"
17 | },
18 | {
19 | "date": "Jan 5",
20 | "fact": " a bear has 42 teeth"
21 | },
22 | {
23 | "date": "Jan 6",
24 | "fact": " an ostrich's eye is bigger than its brain"
25 | },
26 | {
27 | "date": "Jan 7",
28 | "fact": " lemons contain more sugar than strawberries"
29 | },
30 | {
31 | "date": "Jan 8",
32 | "fact": " 8% of people have an extra rib"
33 | },
34 | {
35 | "date": "Jan 9",
36 | "fact": " 85% of plant life is found in the ocean"
37 | },
38 | {
39 | "date": "Jan 10",
40 | "fact": " Ralph Lauren's original name was Ralph Lifshitz"
41 | },
42 | {
43 | "date": "Jan 11",
44 | "fact": " rabbits like licorice"
45 | },
46 | {
47 | "date": "Jan 12",
48 | "fact": " the Hawaiian alphabet has 13 letters"
49 | },
50 | {
51 | "date": "Jan 13",
52 | "fact": " 'Topolino' is the name for Mickey Mouse Italy"
53 | },
54 | {
55 | "date": "Jan 14",
56 | "fact": " a lobsters blood is colorless but when exposed to oxygen it turns blue"
57 | },
58 | {
59 | "date": "Jan 15",
60 | "fact": " armadillos have 4 babies at a time and are all the same sex"
61 | },
62 | {
63 | "date": "Jan 16",
64 | "fact": " reindeer like bananas"
65 | },
66 | {
67 | "date": "Jan 17",
68 | "fact": " the longest recorded flight of a chicken was 13 seconds"
69 | },
70 | {
71 | "date": "Jan 18",
72 | "fact": " birds need gravity to swallow"
73 | },
74 | {
75 | "date": "Jan 19",
76 | "fact": "the most commonly used letter in the alphabet is E"
77 | },
78 | {
79 | "date": "Jan 20",
80 | "fact": " the 3 most common languages in the world are Mandarin Chinese, Spanish and English"
81 | },
82 | {
83 | "date": "Jan 21",
84 | "fact": " dreamt is the only word that ends in mt"
85 | },
86 | {
87 | "date": "Jan 22",
88 | "fact": " the first letters of the months July through to November spell JASON"
89 | },
90 | {
91 | "date": "Jan 23",
92 | "fact": " a cat has 32 muscles in each ear"
93 | },
94 | {
95 | "date": "Jan 24",
96 | "fact": " Perth is Australia's windiest city"
97 | },
98 | {
99 | "date": "Jan 25",
100 | "fact": " Elvis's middle name was Aron"
101 | },
102 | {
103 | "date": "Jan 26",
104 | "fact": " goldfish can see both infrared and ultraviolet light"
105 | },
106 | {
107 | "date": "Jan 27",
108 | "fact": " the smallest bones in the human body are found in your ear"
109 | },
110 | {
111 | "date": "Jan 28",
112 | "fact": " cats spend 66% of their life asleep"
113 | },
114 | {
115 | "date": "Jan 29",
116 | "fact": " Switzerland eats the most chocolate equating to 10 kilos per person per year"
117 | },
118 | {
119 | "date": "Jan 30",
120 | "fact": " money is the number one thing that couples argue about"
121 | },
122 | {
123 | "date": "Jan 31",
124 | "fact": " macadamia nuts are toxic to dogs"
125 | },
126 | {
127 | "date": "Feb 1",
128 | "fact": " when lightning strikes it can reach up to 30,000 degrees celsius (54,000 degrees fahrenheit)"
129 | },
130 | {
131 | "date": "Feb 2",
132 | "fact": " spiders are arachnids and not insects"
133 | },
134 | {
135 | "date": "Feb 3",
136 | "fact": " each time you see a full moon you always see the same side"
137 | },
138 | {
139 | "date": "Feb 4",
140 | "fact": " stewardesses is the longest word that is typed with only the left hand"
141 | },
142 | {
143 | "date": "Feb 5",
144 | "fact": " honey is the only natural food which never spoils"
145 | },
146 | {
147 | "date": "Feb 6",
148 | "fact": " M&M's chocolate stands for the initials for its inventors Mars and Murrie"
149 | },
150 | {
151 | "date": "Feb 7",
152 | "fact": " that you burn more calories eating celery than it contains (the more you eat the thinner you become)"
153 | },
154 | {
155 | "date": "Feb 8",
156 | "fact": " the only continent with no active volcanoes is Australia"
157 | },
158 | {
159 | "date": "Feb 9",
160 | "fact": " the longest street in the world is Yonge street in Toronto Canada measuring 1,896 km (1,178 miles)"
161 | },
162 | {
163 | "date": "Feb 10",
164 | "fact": " about 90% of the worlds population kisses"
165 | },
166 | {
167 | "date": "Feb 11",
168 | "fact": " Coca-Cola originally contained cocaine"
169 | },
170 | {
171 | "date": "Feb 12",
172 | "fact": " the Internet was originally called ARPANet (Advanced Research Projects Agency Network) designed by the US department of defense"
173 | },
174 | {
175 | "date": "Feb 13",
176 | "fact": " toilets use 35% of indoor water use"
177 | },
178 | {
179 | "date": "Feb 14",
180 | "fact": " the fortune cookie was invented in San Francisco"
181 | },
182 | {
183 | "date": "Feb 15",
184 | "fact": " Koalas sleep around 18 hours a day"
185 | },
186 | {
187 | "date": "Feb 16",
188 | "fact": " the first Burger King was opened in Florida Miami in 1954"
189 | },
190 | {
191 | "date": "Feb 17",
192 | "fact": " all insects have 6 legs"
193 | },
194 | {
195 | "date": "Feb 18",
196 | "fact": " the croissant was invented in Austria"
197 | },
198 | {
199 | "date": "Feb 19",
200 | "fact": " In eastern Africa you can buy beer brewed from bananas"
201 | },
202 | {
203 | "date": "Feb 20",
204 | "fact": " African Grey Parrots have vocabularies of over 200 words"
205 | },
206 | {
207 | "date": "Feb 21",
208 | "fact": " a giraffe can clean its ears with its 21 inch tongue"
209 | },
210 | {
211 | "date": "Feb 22",
212 | "fact": " Australia was originally called New Holland"
213 | },
214 | {
215 | "date": "Feb 23",
216 | "fact": " 'Lonely Planet' for travelers is based in Melbourne Australia"
217 | },
218 | {
219 | "date": "Feb 24",
220 | "fact": " the sentence \"the quick brown fox jumps over the lazy dog\" uses every letter in the English alphabet"
221 | },
222 | {
223 | "date": "Feb 25",
224 | "fact": " the Grand Canyon can hold around 900 trillion footballs"
225 | },
226 | {
227 | "date": "Feb 26",
228 | "fact": " all the blinking in one day equates to having your eyes closed for 30 minutes"
229 | },
230 | {
231 | "date": "Feb 27",
232 | "fact": " your foot has 26 bones in it"
233 | },
234 | {
235 | "date": "Feb 28",
236 | "fact": " the average human brain contains around 78% water"
237 | },
238 | {
239 | "date": "Feb 29",
240 | "fact": " 1 nautical knot equates to 1.852 Kph (1.150 mph)"
241 | },
242 | {
243 | "date": "Mar 1",
244 | "fact": " if you add up all the numbers from 1 to 100 consecutively (1 + 2 + 3...) it totals 5050"
245 | },
246 | {
247 | "date": "Mar 2",
248 | "fact": " sponges hold more cold water than hot"
249 | },
250 | {
251 | "date": "Mar 3",
252 | "fact": " lightning strikes the Earth 6,000 times every minute"
253 | },
254 | {
255 | "date": "Mar 4",
256 | "fact": " fire usually moves faster uphill than downhill"
257 | },
258 | {
259 | "date": "Mar 5",
260 | "fact": " cats have over 100 vocal chords"
261 | },
262 | {
263 | "date": "Mar 6",
264 | "fact": " camel's milk doesn't curdle"
265 | },
266 | {
267 | "date": "Mar 7",
268 | "fact": " elephants sleep between 4 - 5 hours in 24 period"
269 | },
270 | {
271 | "date": "Mar 8",
272 | "fact": " it's possible to lead a cow up stairs but not down"
273 | },
274 | {
275 | "date": "Mar 9",
276 | "fact": " frogs can't swallow with their eyes open"
277 | },
278 | {
279 | "date": "Mar 10",
280 | "fact": " elephants are the only mammal that can't jump"
281 | },
282 | {
283 | "date": "Mar 11",
284 | "fact": " a 1/4 of your bones are in your feet"
285 | },
286 | {
287 | "date": "Mar 12",
288 | "fact": " your tongue is the fastest healing part of your body"
289 | },
290 | {
291 | "date": "Mar 13",
292 | "fact": " on your birthday you share it with 9 million others"
293 | },
294 | {
295 | "date": "Mar 14",
296 | "fact": " 1 googol is the number 1 followed by 100 zeros"
297 | },
298 | {
299 | "date": "Mar 15",
300 | "fact": " a 1 minute kiss burns 26 calories"
301 | },
302 | {
303 | "date": "Mar 16",
304 | "fact": " you burn more calories sleeping than watching TV"
305 | },
306 | {
307 | "date": "Mar 17",
308 | "fact": " frogs don't usually swallow water (they absorb most of the moisture they need through their skin)"
309 | },
310 | {
311 | "date": "Mar 18",
312 | "fact": " at birth dalmations are always white"
313 | },
314 | {
315 | "date": "Mar 19",
316 | "fact": " hummingbirds are the only bird that can fly backwards"
317 | },
318 | {
319 | "date": "Mar 20",
320 | "fact": " a duck can't walk without bobbing its head"
321 | },
322 | {
323 | "date": "Mar 21",
324 | "fact": " a hummingbird's heart beats at over a 1,000 times a minute"
325 | },
326 | {
327 | "date": "Mar 22",
328 | "fact": " dragonflies have 6 legs but can't walk"
329 | },
330 | {
331 | "date": "Mar 23",
332 | "fact": " a crocodile can't move its tongue"
333 | },
334 | {
335 | "date": "Mar 24",
336 | "fact": " that the first MTV video played was 'Video killed the radio star' by the Buggles"
337 | },
338 | {
339 | "date": "Mar 25",
340 | "fact": " in 1878 the first telephone book made contained only 50 names"
341 | },
342 | {
343 | "date": "Mar 26",
344 | "fact": " pop corn was invented by the Aztec Indians"
345 | },
346 | {
347 | "date": "Mar 27",
348 | "fact": " an average person will spend 25 years asleep"
349 | },
350 | {
351 | "date": "Mar 28",
352 | "fact": " hippopotamuses have killed more people in Africa than any other animal"
353 | },
354 | {
355 | "date": "Mar 29",
356 | "fact": " an elephants ears are used to regulate body temperature"
357 | },
358 | {
359 | "date": "Mar 30",
360 | "fact": " the Arctic Ocean is the smallest in the world"
361 | },
362 | {
363 | "date": "Mar 31",
364 | "fact": " the most common mental illnesses are anxiety and depression"
365 | },
366 | {
367 | "date": "Apr 1",
368 | "fact": " the word laser stands for 'Light Amplification by Stimulated Emission of Radiation'"
369 | },
370 | {
371 | "date": "Apr 2",
372 | "fact": " crocodiles never outgrow their enclosure"
373 | },
374 | {
375 | "date": "Apr 3",
376 | "fact": " reindeer hair is hollow inside like a tube"
377 | },
378 | {
379 | "date": "Apr 4",
380 | "fact": " your skin is the largest organ making up the human body"
381 | },
382 | {
383 | "date": "Apr 5",
384 | "fact": " cows don't have upper front teeth"
385 | },
386 | {
387 | "date": "Apr 6",
388 | "fact": " everyday is a holiday somewhere in the world"
389 | },
390 | {
391 | "date": "Apr 7",
392 | "fact": " the coins thrown into the Trevi fountain in Italy are collected for charity"
393 | },
394 | {
395 | "date": "Apr 8",
396 | "fact": " french fries are originally from Belgium"
397 | },
398 | {
399 | "date": "Apr 9",
400 | "fact": " there are 31,557,600 seconds in a year"
401 | },
402 | {
403 | "date": "Apr 10",
404 | "fact": " there are 22 stars in the Paramount studios logo"
405 | },
406 | {
407 | "date": "Apr 11",
408 | "fact": " in a deck of cards the king of hearts is the only king without a moustache"
409 | },
410 | {
411 | "date": "Apr 12",
412 | "fact": " black on yellow are the 2 colors with the strongest impact"
413 | },
414 | {
415 | "date": "Apr 13",
416 | "fact": " the safest car color is white"
417 | },
418 | {
419 | "date": "Apr 14",
420 | "fact": " the most commonly forgotten item for travelers is their toothbrush"
421 | },
422 | {
423 | "date": "Apr 15",
424 | "fact": " Coca Cola launched its 3rd product Sprite in 1961"
425 | },
426 | {
427 | "date": "Apr 16",
428 | "fact": " apples are more effective at waking you up in the morning than coffee"
429 | },
430 | {
431 | "date": "Apr 17",
432 | "fact": " room temperature is defined as between 20 to 25C (68 to 77F)"
433 | },
434 | {
435 | "date": "Apr 18",
436 | "fact": " an octopus pupil is rectangular"
437 | },
438 | {
439 | "date": "Apr 19",
440 | "fact": " the hyoid bone in your throat is the only bone in your body not attached to any other"
441 | },
442 | {
443 | "date": "Apr 20",
444 | "fact": " the Australian aircraft carrier QANTAS stands for Queensland And Northern Territories Aerial Service"
445 | },
446 | {
447 | "date": "Apr 21",
448 | "fact": " the movie Pulp Fiction cost $8 million to make with $5 million going towards actor's salaries"
449 | },
450 | {
451 | "date": "Apr 22",
452 | "fact": " there are only 4 words in the English language which end in 'dous' (they are: hazardous, horrendous, stupendous and tremendous)"
453 | },
454 | {
455 | "date": "Apr 23",
456 | "fact": " the oldest word in the English language is 'town'"
457 | },
458 | {
459 | "date": "Apr 24",
460 | "fact": " cats can't move their jaw sideways"
461 | },
462 | {
463 | "date": "Apr 25",
464 | "fact": " grapes explode when you put them in the microwave"
465 | },
466 | {
467 | "date": "Apr 26",
468 | "fact": " its physically impossible for pigs to look up at the sky"
469 | },
470 | {
471 | "date": "Apr 27",
472 | "fact": " your most sensitive finger is your index finger (closest to your thumb)"
473 | },
474 | {
475 | "date": "Apr 28",
476 | "fact": " 'Bookkeeper' and 'bookkeeping' are the only 2 words in the English language with three consecutive double letters"
477 | },
478 | {
479 | "date": "Apr 29",
480 | "fact": " Venetian blinds were invented in Japan"
481 | },
482 | {
483 | "date": "Apr 30",
484 | "fact": " the average golf ball has 336 dimples"
485 | },
486 | {
487 | "date": "May 1",
488 | "fact": " the word 'Strengths' is the longest word in the English language with just one vowel"
489 | },
490 | {
491 | "date": "May 2",
492 | "fact": " the movie 'Wayne's World' was filmed in two weeks"
493 | },
494 | {
495 | "date": "May 3",
496 | "fact": " the Amazon rainforest produces half the world's oxygen supply"
497 | },
498 | {
499 | "date": "May 4",
500 | "fact": " a group of frogs is called an army"
501 | },
502 | {
503 | "date": "May 5",
504 | "fact": " a group of rhinos is called a crash"
505 | },
506 | {
507 | "date": "May 6",
508 | "fact": " a group of kangaroos is called a mob"
509 | },
510 | {
511 | "date": "May 7",
512 | "fact": " a group of whales is called a pod"
513 | },
514 | {
515 | "date": "May 8",
516 | "fact": " a group of geese is called a gaggle"
517 | },
518 | {
519 | "date": "May 9",
520 | "fact": " a group of owls is called a parliament"
521 | },
522 | {
523 | "date": "May 10",
524 | "fact": " the first sailing boats were built in Egypt"
525 | },
526 | {
527 | "date": "May 11",
528 | "fact": " Brazil is named after a tree"
529 | },
530 | {
531 | "date": "May 12",
532 | "fact": " Brazil covers 50% of the South American continent"
533 | },
534 | {
535 | "date": "May 13",
536 | "fact": " Brazil borders every country in South America except Chile and Ecuador"
537 | },
538 | {
539 | "date": "May 14",
540 | "fact": " Hilton was the first international hotel chain"
541 | },
542 | {
543 | "date": "May 15",
544 | "fact": " the brand Nokia is named after a place in Southern Finland"
545 | },
546 | {
547 | "date": "May 16",
548 | "fact": " Monopoly is the most played board game in the world"
549 | },
550 | {
551 | "date": "May 17",
552 | "fact": " 96% of candles sold are purchased by women"
553 | },
554 | {
555 | "date": "May 18",
556 | "fact": " 42% of men and women 25% don�t wash their hands after using a public toilet"
557 | },
558 | {
559 | "date": "May 19",
560 | "fact": " if you filled a matchbox with gold it could be flattened into a sheet the size of a tennis court"
561 | },
562 | {
563 | "date": "May 20",
564 | "fact": " Jamaica has 120 rivers"
565 | },
566 | {
567 | "date": "May 21",
568 | "fact": " a cats urine glows under a blacklight"
569 | },
570 | {
571 | "date": "May 22",
572 | "fact": " white cats with blue eyes are usually deaf"
573 | },
574 | {
575 | "date": "May 23",
576 | "fact": " cats have a peripheral vision of 285 degrees"
577 | },
578 | {
579 | "date": "May 24",
580 | "fact": " small dogs usually live longer than larger breeds"
581 | },
582 | {
583 | "date": "May 25",
584 | "fact": " domestic cats dislike citrus scents"
585 | },
586 | {
587 | "date": "May 26",
588 | "fact": " cats can jump up to 7 times their tail length"
589 | },
590 | {
591 | "date": "May 27",
592 | "fact": " China manufacturers 70% of the worlds toys"
593 | },
594 | {
595 | "date": "May 28",
596 | "fact": " The Great Wall of China is approximately 6,430 Km long (3,995 miles)"
597 | },
598 | {
599 | "date": "May 29",
600 | "fact": " paper originated from China"
601 | },
602 | {
603 | "date": "May 30",
604 | "fact": " the wheelbarrow is invented in China"
605 | },
606 | {
607 | "date": "May 31",
608 | "fact": " tree hugging is forbidden in china"
609 | },
610 | {
611 | "date": "Jun 1",
612 | "fact": " the film 'Mary Poppins' was filmed entirely indoors"
613 | },
614 | {
615 | "date": "Jun 2",
616 | "fact": " all of the clocks in the movie 'Pulp Fiction' are fixed to 4:20"
617 | },
618 | {
619 | "date": "Jun 3",
620 | "fact": " instant coffee was invented in 1901"
621 | },
622 | {
623 | "date": "Jun 4",
624 | "fact": " the human body of a 70 kg person contains 0.2mg of gold"
625 | },
626 | {
627 | "date": "Jun 5",
628 | "fact": " rice is the staple food for 50% of the worlds population"
629 | },
630 | {
631 | "date": "Jun 6",
632 | "fact": " Pearls melt in vinegar"
633 | },
634 | {
635 | "date": "Jun 7",
636 | "fact": " a hard boiled eggs spin (uncooked or soft boiled don�t)"
637 | },
638 | {
639 | "date": "Jun 8",
640 | "fact": " there is no butter in buttermilk"
641 | },
642 | {
643 | "date": "Jun 9",
644 | "fact": " giraffes and rats can last longer without water than camels"
645 | },
646 | {
647 | "date": "Jun 10",
648 | "fact": " the dot on top of the letter 'i' is called a tittle"
649 | },
650 | {
651 | "date": "Jun 11",
652 | "fact": " the electric chair was invented by a dentist"
653 | },
654 | {
655 | "date": "Jun 12",
656 | "fact": " you're more likely to be killed by a champagne cork than by a poisonous spider"
657 | },
658 | {
659 | "date": "Jun 13",
660 | "fact": " a crocodile can't stick out its tongue"
661 | },
662 | {
663 | "date": "Jun 14",
664 | "fact": " rubber bands last longer when kept refrigerated"
665 | },
666 | {
667 | "date": "Jun 15",
668 | "fact": " women blink twice as much as men"
669 | },
670 | {
671 | "date": "Jun 16",
672 | "fact": " ostriches don't bury their heads in sand"
673 | },
674 | {
675 | "date": "Jun 17",
676 | "fact": " only female mosquitoes bite"
677 | },
678 | {
679 | "date": "Jun 18",
680 | "fact": " Scotland has the most redheads"
681 | },
682 | {
683 | "date": "Jun 19",
684 | "fact": " household dust is made of dead skin cells"
685 | },
686 | {
687 | "date": "Jun 20",
688 | "fact": " the past tense for the English word 'dare' is 'durst'"
689 | },
690 | {
691 | "date": "Jun 21",
692 | "fact": " hummingbirds can't walk"
693 | },
694 | {
695 | "date": "Jun 22",
696 | "fact": " wind doesn�t make a sound until it blows against an object"
697 | },
698 | {
699 | "date": "Jun 23",
700 | "fact": " the naming of tropical storms and hurricanes officially began in 1953"
701 | },
702 | {
703 | "date": "Jun 24",
704 | "fact": " India has the most post offices than any other country (over 100,000)"
705 | },
706 | {
707 | "date": "Jun 25",
708 | "fact": " India is home to over 200 million cows"
709 | },
710 | {
711 | "date": "Jun 26",
712 | "fact": " the Taj Mahal in India is made entirely out of marble"
713 | },
714 | {
715 | "date": "Jun 27",
716 | "fact": " Bali has the worlds largest variety of flora"
717 | },
718 | {
719 | "date": "Jun 28",
720 | "fact": " Bill Gates began programming computers at the of age 13"
721 | },
722 | {
723 | "date": "Jun 29",
724 | "fact": " every single possible 3 character .com domain has been registered"
725 | },
726 | {
727 | "date": "Jun 30",
728 | "fact": " the word 'uncopyrightable' is the is the only 15 letter word that can be spelled without repeating any letter"
729 | },
730 | {
731 | "date": "Jul 1",
732 | "fact": " the word 'testify' derived from a time when men were required to swear on their testicles"
733 | },
734 | {
735 | "date": "Jul 2",
736 | "fact": " the word typewriter is the longest word that can be typed using only the top row of a keyboard"
737 | },
738 | {
739 | "date": "Jul 3",
740 | "fact": " that you can spell the word 'level' the same backwards"
741 | },
742 | {
743 | "date": "Jul 4",
744 | "fact": " Madonna and Michael Jackson were both born in 1958"
745 | },
746 | {
747 | "date": "Jul 5",
748 | "fact": " almonds are members of the peach family"
749 | },
750 | {
751 | "date": "Jul 6",
752 | "fact": " an egg contains every vitamin except vitamin C"
753 | },
754 | {
755 | "date": "Jul 7",
756 | "fact": " owls can't move their eyes from side to side"
757 | },
758 | {
759 | "date": "Jul 8",
760 | "fact": " you take over 23,000 breaths everyday"
761 | },
762 | {
763 | "date": "Jul 9",
764 | "fact": " gold never erodes"
765 | },
766 | {
767 | "date": "Jul 10",
768 | "fact": " scorpions glow under ultra violet light"
769 | },
770 | {
771 | "date": "Jul 11",
772 | "fact": " when water freezes it expans by 9%"
773 | },
774 | {
775 | "date": "Jul 12",
776 | "fact": " ants stretch when they wake up in the morning"
777 | },
778 | {
779 | "date": "Jul 13",
780 | "fact": " your foot and your forearm are the same length"
781 | },
782 | {
783 | "date": "Jul 14",
784 | "fact": " diamonds are the hardest natural substance"
785 | },
786 | {
787 | "date": "Jul 15",
788 | "fact": " 111,111,111 x 111,111,111 = 12,345,678,987,654,321"
789 | },
790 | {
791 | "date": "Jul 16",
792 | "fact": " the longest possible eclipse of the sun is 7.31 minutes"
793 | },
794 | {
795 | "date": "Jul 17",
796 | "fact": " Halley's comet passes the Earth every 76 years (the next time it will return will be 2062)"
797 | },
798 | {
799 | "date": "Jul 18",
800 | "fact": " there is no sound in space"
801 | },
802 | {
803 | "date": "Jul 19",
804 | "fact": " tennis was originally played with bare hands"
805 | },
806 | {
807 | "date": "Jul 20",
808 | "fact": " the Olympic flag was designed in 1913"
809 | },
810 | {
811 | "date": "Jul 21",
812 | "fact": " a bowling pin will fall at a tilt of 7.5 degrees"
813 | },
814 | {
815 | "date": "Jul 22",
816 | "fact": " there are 31,536,000 seconds in a year"
817 | },
818 | {
819 | "date": "Jul 23",
820 | "fact": " a piece of paper cannot be folded more than 7 times"
821 | },
822 | {
823 | "date": "Jul 24",
824 | "fact": " the opposite sides of a die always adds up to 7"
825 | },
826 | {
827 | "date": "Jul 25",
828 | "fact": " VHS stands for Video Home System"
829 | },
830 | {
831 | "date": "Jul 26",
832 | "fact": " the WD in WD-40 stands for Water Displacer"
833 | },
834 | {
835 | "date": "Jul 27",
836 | "fact": " the electric toothbrush was invented in 1939"
837 | },
838 | {
839 | "date": "Jul 28",
840 | "fact": " Porsche also builds tractors"
841 | },
842 | {
843 | "date": "Jul 29",
844 | "fact": " the Eiffel Tower has 1,792 steps"
845 | },
846 | {
847 | "date": "Jul 30",
848 | "fact": " Isaac Newton invented the cat door"
849 | },
850 | {
851 | "date": "Jul 31",
852 | "fact": " the Titanic was built in Belfast"
853 | },
854 | {
855 | "date": "Aug 1",
856 | "fact": " Buckingham Palace has over 600 rooms"
857 | },
858 | {
859 | "date": "Aug 2",
860 | "fact": " Hawaii was originally called the Sandwich Islands"
861 | },
862 | {
863 | "date": "Aug 3",
864 | "fact": " Americans eat 35,000 tons of pasta a year"
865 | },
866 | {
867 | "date": "Aug 4",
868 | "fact": " Hawaii is the only US state that grows coffee"
869 | },
870 | {
871 | "date": "Aug 5",
872 | "fact": " Americans throw away 44 million newspapers a day"
873 | },
874 | {
875 | "date": "Aug 6",
876 | "fact": " Einstein slept 10 hours a night"
877 | },
878 | {
879 | "date": "Aug 7",
880 | "fact": " Germany borders 9 other countries"
881 | },
882 | {
883 | "date": "Aug 8",
884 | "fact": " Peru has more pyramids than Egypt"
885 | },
886 | {
887 | "date": "Aug 9",
888 | "fact": " Christmas trees originated from Germany"
889 | },
890 | {
891 | "date": "Aug 10",
892 | "fact": " more people die from falling coconuts then from shark attacks"
893 | },
894 | {
895 | "date": "Aug 11",
896 | "fact": " the original design of Monopoly was circular"
897 | },
898 | {
899 | "date": "Aug 12",
900 | "fact": " the Earth is struck by lightning over 100 times every second"
901 | },
902 | {
903 | "date": "Aug 13",
904 | "fact": " over 2,500 left handed people are killed a year from using right handed products"
905 | },
906 | {
907 | "date": "Aug 14",
908 | "fact": " gorillas sleep 14 hours a day"
909 | },
910 | {
911 | "date": "Aug 15",
912 | "fact": " the lifespan of a squirrel is 9 years"
913 | },
914 | {
915 | "date": "Aug 16",
916 | "fact": " the stomach acids found in a snakes stomach can digest bones and teeth but not fur or hair"
917 | },
918 | {
919 | "date": "Aug 17",
920 | "fact": " the word racecar can be spelled the same way backwards"
921 | },
922 | {
923 | "date": "Aug 18",
924 | "fact": " a giraffe can go longer without water than a camel"
925 | },
926 | {
927 | "date": "Aug 19",
928 | "fact": " you burn more calories sleeping than watching television"
929 | },
930 | {
931 | "date": "Aug 20",
932 | "fact": " the word 'underground is the only word that begins and ends with the letters 'und'"
933 | },
934 | {
935 | "date": "Aug 21",
936 | "fact": " 56% of typing is completed by your left hand"
937 | },
938 | {
939 | "date": "Aug 22",
940 | "fact": " there are more chickens than people"
941 | },
942 | {
943 | "date": "Aug 23",
944 | "fact": " for every human there are 200 million insects"
945 | },
946 | {
947 | "date": "Aug 24",
948 | "fact": " the average bed contains over 6 billion dust mites"
949 | },
950 | {
951 | "date": "Aug 25",
952 | "fact": " an iguana can stay under water for 28 minutes"
953 | },
954 | {
955 | "date": "Aug 26",
956 | "fact": " emus can't walk backwards"
957 | },
958 | {
959 | "date": "Aug 27",
960 | "fact": " the Eifel Tower has 2,500,000 rivets"
961 | },
962 | {
963 | "date": "Aug 28",
964 | "fact": " Americas top selling ice cream flavour is vanilla"
965 | },
966 | {
967 | "date": "Aug 29",
968 | "fact": " the doorbell was invented in 1831"
969 | },
970 | {
971 | "date": "Aug 30",
972 | "fact": " there are 7 points on the Statue of Liberty's crown"
973 | },
974 | {
975 | "date": "Aug 31",
976 | "fact": " the oldest known vegetable is the pea"
977 | },
978 | {
979 | "date": "Sep 1",
980 | "fact": " the most fatal car accidents occur on Saturdays"
981 | },
982 | {
983 | "date": "Sep 2",
984 | "fact": " the average hen lays 228 eggs a year"
985 | },
986 | {
987 | "date": "Sep 3",
988 | "fact": " the Eiffel Tower has 1,792 steps"
989 | },
990 | {
991 | "date": "Sep 4",
992 | "fact": " Iceland consumes more Coca Cola than any other country"
993 | },
994 | {
995 | "date": "Sep 5",
996 | "fact": " Oak trees don't produce acorns until they are 50 years old"
997 | },
998 | {
999 | "date": "Sep 6",
1000 | "fact": " the word 'almost' is the longest word spelt alphabetically"
1001 | },
1002 | {
1003 | "date": "Sep 7",
1004 | "fact": " human thigh bones are stronger than concrete"
1005 | },
1006 | {
1007 | "date": "Sep 8",
1008 | "fact": " Earth is the only planet not named after a god"
1009 | },
1010 | {
1011 | "date": "Sep 9",
1012 | "fact": " months that start on a Sunday will always have a Friday the 13th"
1013 | },
1014 | {
1015 | "date": "Sep 10",
1016 | "fact": " more people are allergic to cows milk than any other food"
1017 | },
1018 | {
1019 | "date": "Sep 11",
1020 | "fact": " more people are killed from bees than snakes"
1021 | },
1022 | {
1023 | "date": "Sep 12",
1024 | "fact": " the average person laughs 10 times a day"
1025 | },
1026 | {
1027 | "date": "Sep 13",
1028 | "fact": " the Atlantic Ocean is saltier than the Pacific"
1029 | },
1030 | {
1031 | "date": "Sep 14",
1032 | "fact": " your mouth produces 1 litre of saliva a day"
1033 | },
1034 | {
1035 | "date": "Sep 15",
1036 | "fact": " your head contains 22 bones"
1037 | },
1038 | {
1039 | "date": "Sep 16",
1040 | "fact": " the coloured part of your eye is called the iris"
1041 | },
1042 | {
1043 | "date": "Sep 17",
1044 | "fact": " if your DNA was stretched out it would reach to the moon 6,000 times"
1045 | },
1046 | {
1047 | "date": "Sep 18",
1048 | "fact": " everyone has a unique tongue print"
1049 | },
1050 | {
1051 | "date": "Sep 19",
1052 | "fact": " you begin to feel thirsty when your body losses 1% of water"
1053 | },
1054 | {
1055 | "date": "Sep 20",
1056 | "fact": " hiccups usually lasts for 5 minutes"
1057 | },
1058 | {
1059 | "date": "Sep 21",
1060 | "fact": " not all your taste buds are on our tongue (10% are on the insides of you cheeks)"
1061 | },
1062 | {
1063 | "date": "Sep 22",
1064 | "fact": " the life span of a house fly is between 10 to 25 days"
1065 | },
1066 | {
1067 | "date": "Sep 23",
1068 | "fact": " a dolphins top speed is 60kmh (37mph)"
1069 | },
1070 | {
1071 | "date": "Sep 24",
1072 | "fact": " the smallest dog is the Chihuahua"
1073 | },
1074 | {
1075 | "date": "Sep 25",
1076 | "fact": " a sharks top speed is 70kmh (44mph)"
1077 | },
1078 | {
1079 | "date": "Sep 26",
1080 | "fact": " there are 70 million sheep in New Zealand (with 4 million people)"
1081 | },
1082 | {
1083 | "date": "Sep 27",
1084 | "fact": " the worlds smallest bird is the 'bee hummingbird' found in Cuba"
1085 | },
1086 | {
1087 | "date": "Sep 28",
1088 | "fact": " African elephants only have 4 teeth"
1089 | },
1090 | {
1091 | "date": "Sep 29",
1092 | "fact": " The first English dictionary was written in 1755"
1093 | },
1094 | {
1095 | "date": "Sep 30",
1096 | "fact": " the rarest type of diamond is green"
1097 | },
1098 | {
1099 | "date": "Oct 1",
1100 | "fact": " MasterCard was originally called MasterCharge"
1101 | },
1102 | {
1103 | "date": "Oct 2",
1104 | "fact": " the US flag has 13 stripes (representing the original 13 states)"
1105 | },
1106 | {
1107 | "date": "Oct 3",
1108 | "fact": " men are stuck by lightning 7 times more than women"
1109 | },
1110 | {
1111 | "date": "Oct 4",
1112 | "fact": " Tokyo was once known as Edo"
1113 | },
1114 | {
1115 | "date": "Oct 5",
1116 | "fact": " women make up 49% of the worlds population"
1117 | },
1118 | {
1119 | "date": "Oct 6",
1120 | "fact": " wine is sold in tinted bottles because it spoils when exposed to light"
1121 | },
1122 | {
1123 | "date": "Oct 7",
1124 | "fact": " the tea bag was invented in 1908"
1125 | },
1126 | {
1127 | "date": "Oct 8",
1128 | "fact": " carrots contain 0% fat"
1129 | },
1130 | {
1131 | "date": "Oct 9",
1132 | "fact": " 1 billion snails are served in restaurants each year"
1133 | },
1134 | {
1135 | "date": "Oct 10",
1136 | "fact": " plastic bottles were first used for soft drinks in 1970"
1137 | },
1138 | {
1139 | "date": "Oct 11",
1140 | "fact": " the $ sign was introduced in 1788"
1141 | },
1142 | {
1143 | "date": "Oct 12",
1144 | "fact": " the meaning of 'Blue Chip' comes from blue casino chips which have a high value"
1145 | },
1146 | {
1147 | "date": "Oct 13",
1148 | "fact": " DVDs are physically the same size as a CDs but can store 13 times more data"
1149 | },
1150 | {
1151 | "date": "Oct 14",
1152 | "fact": " the term 'disc jockey' was first used in 1937"
1153 | },
1154 | {
1155 | "date": "Oct 15",
1156 | "fact": " sound travels 4.3 times faster through water than in air"
1157 | },
1158 | {
1159 | "date": "Oct 16",
1160 | "fact": " the average soccer ball is made up of 32 leather panels and held together by 642 stitches"
1161 | },
1162 | {
1163 | "date": "Oct 17",
1164 | "fact": " soccer is the most followed sport"
1165 | },
1166 | {
1167 | "date": "Oct 18",
1168 | "fact": " volleyball was invented in 1895"
1169 | },
1170 | {
1171 | "date": "Oct 19",
1172 | "fact": " that in developed countries 27% of food is thrown away"
1173 | },
1174 | {
1175 | "date": "Oct 20",
1176 | "fact": " the odds of being struck by lightning are 600,000 to 1"
1177 | },
1178 | {
1179 | "date": "Oct 21",
1180 | "fact": " the first train reached a top speed of only 8 kmh (5 mph)"
1181 | },
1182 | {
1183 | "date": "Oct 22",
1184 | "fact": " Niagara Falls could fill 4,000 bathtubs every second"
1185 | },
1186 | {
1187 | "date": "Oct 23",
1188 | "fact": " it takes 1 alligator to make a pair of shoes and 3 for a pair of boots"
1189 | },
1190 | {
1191 | "date": "Oct 24",
1192 | "fact": " your most active muscles are in your eye"
1193 | },
1194 | {
1195 | "date": "Oct 25",
1196 | "fact": " a banana contains 75% water"
1197 | },
1198 | {
1199 | "date": "Oct 26",
1200 | "fact": " 13 people die every year from vending machines"
1201 | },
1202 | {
1203 | "date": "Oct 27",
1204 | "fact": " rain contains vitamin B12"
1205 | },
1206 | {
1207 | "date": "Oct 28",
1208 | "fact": " your liver has over 500 functions"
1209 | },
1210 | {
1211 | "date": "Oct 29",
1212 | "fact": " your brain uses 25% of all the oxygen your breathe"
1213 | },
1214 | {
1215 | "date": "Oct 30",
1216 | "fact": " after Hawaii, New York is the state surrounded by the most water"
1217 | },
1218 | {
1219 | "date": "Oct 31",
1220 | "fact": " ice skating rinks always go counter clock wise (for the majority of people that are right handed needing to hang onto the rail)"
1221 | },
1222 | {
1223 | "date": "Nov 1",
1224 | "fact": " a flea can jump 350 times its body length"
1225 | },
1226 | {
1227 | "date": "Nov 2",
1228 | "fact": " cucumbers are 96% water."
1229 | },
1230 | {
1231 | "date": "Nov 3",
1232 | "fact": " a full moon is 9 times brighter than a half moon"
1233 | },
1234 | {
1235 | "date": "Nov 4",
1236 | "fact": " a honeybee's top speed is 24kph (15mph)"
1237 | },
1238 | {
1239 | "date": "Nov 5",
1240 | "fact": " a humming bird flaps its wings up to 90 times a second (5,400 times a minute)"
1241 | },
1242 | {
1243 | "date": "Nov 6",
1244 | "fact": " flys always launch backwards for a quick getaway"
1245 | },
1246 | {
1247 | "date": "Nov 7",
1248 | "fact": " horses have 18 more bones than humans"
1249 | },
1250 | {
1251 | "date": "Nov 8",
1252 | "fact": " a cheetahs top speed is 114kph (70mph)"
1253 | },
1254 | {
1255 | "date": "Nov 9",
1256 | "fact": " horses sleep standing up"
1257 | },
1258 | {
1259 | "date": "Nov 10",
1260 | "fact": " a jellyfish is 95% water"
1261 | },
1262 | {
1263 | "date": "Nov 11",
1264 | "fact": " bats are the only mammals that fly"
1265 | },
1266 | {
1267 | "date": "Nov 12",
1268 | "fact": " a cat uses its whiskers to determine if a space is too small to squeeze through"
1269 | },
1270 | {
1271 | "date": "Nov 13",
1272 | "fact": " every day 7% of the US eats at McDonalds"
1273 | },
1274 | {
1275 | "date": "Nov 14",
1276 | "fact": " a snail can sleep for 3 years"
1277 | },
1278 | {
1279 | "date": "Nov 15",
1280 | "fact": " tigers have striped skin as well as fur"
1281 | },
1282 | {
1283 | "date": "Nov 16",
1284 | "fact": " crocodiles are colour blind"
1285 | },
1286 | {
1287 | "date": "Nov 17",
1288 | "fact": " a chameleons tongue is twice the length of its body"
1289 | },
1290 | {
1291 | "date": "Nov 18",
1292 | "fact": " dogs sweat through the pads on their feet"
1293 | },
1294 | {
1295 | "date": "Nov 19",
1296 | "fact": " hippopotamuses are born under water"
1297 | },
1298 | {
1299 | "date": "Nov 20",
1300 | "fact": " bananas grow pointing upwards."
1301 | },
1302 | {
1303 | "date": "Nov 21",
1304 | "fact": " whales can't swim backwards"
1305 | },
1306 | {
1307 | "date": "Nov 22",
1308 | "fact": " camels are born without humps"
1309 | },
1310 | {
1311 | "date": "Nov 23",
1312 | "fact": " only female mosquitoes bite"
1313 | },
1314 | {
1315 | "date": "Nov 24",
1316 | "fact": " the average porcupine has 30,000 spikes"
1317 | },
1318 | {
1319 | "date": "Nov 25",
1320 | "fact": " tarantula spiders can survive 2 and a half years without food"
1321 | },
1322 | {
1323 | "date": "Nov 26",
1324 | "fact": " crocodiles are responsible for over a 1,000 deaths each year by the Banks of the Nile river"
1325 | },
1326 | {
1327 | "date": "Nov 27",
1328 | "fact": " there are more insects in the world than all other animals combined"
1329 | },
1330 | {
1331 | "date": "Nov 28",
1332 | "fact": " giraffes can't swim"
1333 | },
1334 | {
1335 | "date": "Nov 29",
1336 | "fact": " crocodiles swallow rocks to help them dive deeper"
1337 | },
1338 | {
1339 | "date": "Nov 30",
1340 | "fact": " an elephant's trunk can hold over 5 litres of water"
1341 | },
1342 | {
1343 | "date": "Dec 1",
1344 | "fact": " bull's can run faster uphill than down"
1345 | },
1346 | {
1347 | "date": "Dec 2",
1348 | "fact": " a shark's teeth are literally as hard as steel"
1349 | },
1350 | {
1351 | "date": "Dec 3",
1352 | "fact": " a moth has no stomach"
1353 | },
1354 | {
1355 | "date": "Dec 4",
1356 | "fact": " grasshoppers have white blood"
1357 | },
1358 | {
1359 | "date": "Dec 5",
1360 | "fact": " it takes 50 minutes to soft boil and two hours to hard boil an ostrich egg"
1361 | },
1362 | {
1363 | "date": "Dec 6",
1364 | "fact": " New York was once called New Amsterdam"
1365 | },
1366 | {
1367 | "date": "Dec 7",
1368 | "fact": " there is 200 times more gold in the world's oceans than has been mined"
1369 | },
1370 | {
1371 | "date": "Dec 8",
1372 | "fact": " Brazil got its name from the Brazilian nut (not the other way around)"
1373 | },
1374 | {
1375 | "date": "Dec 9",
1376 | "fact": " the moon orbits the Earth every 27.32 days"
1377 | },
1378 | {
1379 | "date": "Dec 10",
1380 | "fact": " more than 75% of all countries are north of the equator"
1381 | },
1382 | {
1383 | "date": "Dec 11",
1384 | "fact": " 2 million hydrogen atoms would be required to cover a full stop (.)"
1385 | },
1386 | {
1387 | "date": "Dec 12",
1388 | "fact": " Hawaii officially became apart of the US in 1900"
1389 | },
1390 | {
1391 | "date": "Dec 13",
1392 | "fact": " the D.C. in Washington D.C. stands for District of Columbia"
1393 | },
1394 | {
1395 | "date": "Dec 14",
1396 | "fact": " New York contains 920km (571miles) of shoreline"
1397 | },
1398 | {
1399 | "date": "Dec 15",
1400 | "fact": " The Dead Sea is actually an inland lake"
1401 | },
1402 | {
1403 | "date": "Dec 16",
1404 | "fact": " there are no rivers in Saudi Arabia"
1405 | },
1406 | {
1407 | "date": "Dec 17",
1408 | "fact": " the largest exporter of sugar is Cuba"
1409 | },
1410 | {
1411 | "date": "Dec 18",
1412 | "fact": " dirty snow melts quicker than clean snow"
1413 | },
1414 | {
1415 | "date": "Dec 19",
1416 | "fact": " Icelandic phone books are listed by first names (not surnames)"
1417 | },
1418 | {
1419 | "date": "Dec 20",
1420 | "fact": " 1 gigayear = 1,000,000,000,000 years"
1421 | },
1422 | {
1423 | "date": "Dec 21",
1424 | "fact": " the water in the Dead Sea is so salty that its easier to float than sink"
1425 | },
1426 | {
1427 | "date": "Dec 22",
1428 | "fact": " Rio de Janeiro translates to river of January"
1429 | },
1430 | {
1431 | "date": "Dec 23",
1432 | "fact": " the Moons diameter is 3,476km"
1433 | },
1434 | {
1435 | "date": "Dec 24",
1436 | "fact": " New York's Central Park was opened in 1876"
1437 | },
1438 | {
1439 | "date": "Dec 25",
1440 | "fact": " the subject of the first printed book in England was about chess"
1441 | },
1442 | {
1443 | "date": "Dec 26",
1444 | "fact": " the word old English word 'juke' meaning dancing lends its name to the juke box"
1445 | },
1446 | {
1447 | "date": "Dec 27",
1448 | "fact": " EMI awards stands for 'Electrical and Musical Instruments'"
1449 | },
1450 | {
1451 | "date": "Dec 28",
1452 | "fact": " the most sung song is happy birthday"
1453 | },
1454 | {
1455 | "date": "Dec 29",
1456 | "fact": " the first rugby club was formed in 1843"
1457 | },
1458 | {
1459 | "date": "Dec 30",
1460 | "fact": " the most common injury in ten pin bowling is a sore thumb"
1461 | },
1462 | {
1463 | "date": "Dec 31",
1464 | "fact": " the yo-yo was originally used as a weapon for hunting the in the Philippines"
1465 | }
1466 | ]
1467 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/HomeViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HomeViewController.swift
3 | // SharedCoreData
4 | //
5 | // Created by iLeaf Solutions on 18/12/17.
6 | // Copyright © 2017 iLeaf. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class HomeViewController: UIViewController,JBDatePickerViewDelegate{
12 |
13 | ///Input is month name
14 | @IBOutlet weak var lblCurrentMnth: UILabel!
15 | /// calender view
16 | @IBOutlet weak var datePickerView: JBDatePickerView!
17 | /// Input is todays did you know fact
18 | @IBOutlet weak var lblFactsDescription: UILabel!
19 | /// Contain all facts
20 | var arrayFacts = [SCDFactModel]()
21 | /// Know facts model
22 | var factsModel = SCDFactModel()
23 | /// Date formatter
24 | lazy var dateFormatter: DateFormatter = {
25 |
26 | var formatter = DateFormatter()
27 | formatter.dateFormat = "MMM d"
28 | return formatter
29 | }()
30 |
31 | // MARK: View life cycle
32 | override func viewDidLoad() {
33 | super.viewDidLoad()
34 | // Do any additional setup after loading the view, typically from a nib.
35 | datePickerView.delegate = self
36 | if !isAppAlreadyLaunchedOnce(){
37 |
38 | //Read json and save it to coredata
39 | readJson()
40 | }
41 | else
42 | { //Fetch todays fact
43 | fetchTodaysFact()
44 | }
45 |
46 |
47 | //let arry = SCDCoreDataWrapper.sharedInstance.getUser(entity: "User")
48 |
49 |
50 | }
51 | override func didReceiveMemoryWarning() {
52 | super.didReceiveMemoryWarning()
53 | // Dispose of any resources that can be recreated.
54 | }
55 | // MARK: Helper functions
56 | func getMonth(month:Int) -> String {
57 | switch month {
58 | case 1:
59 | return "Jan"
60 | case 2:
61 | return "Feb"
62 | case 3:
63 | return "Mar"
64 | case 4:
65 | return "Apr"
66 | case 5:
67 | return "May"
68 | case 6:
69 | return "Jun"
70 | case 7:
71 | return "Jul"
72 | case 8:
73 | return "Aug"
74 | case 9:
75 | return "Sep"
76 | case 10:
77 | return "Oct"
78 | case 11:
79 | return "Nov"
80 | default:
81 | return "Dec"
82 | }
83 | }
84 | func fetchTodaysFact()
85 | {
86 | let date = Date()
87 | let calendar = Calendar.current
88 | let components = calendar.dateComponents([.year, .month, .day], from:date)
89 | let month = components.month
90 |
91 | let day:Int = components.day!
92 | let todaysDate = getMonth(month: month!)+" "+String(day)
93 | let data = SCDCoreDataWrapper.sharedInstance.fetchTodaysFact(filter: todaysDate)
94 | let replaced = data.fact.trimmingCharacters(in: NSCharacterSet.whitespaces)
95 | lblFactsDescription.text = replaced.capitalizingFirstLetter()
96 | }
97 |
98 | // MARK: - JBDatePickerViewDelegate implementation
99 |
100 | func didSelectDay(_ dayView: JBDatePickerDayView) {
101 | //Fetching todays fact from coredata
102 | let data = SCDCoreDataWrapper.sharedInstance.fetchTodaysFact(filter: dateFormatter.string(from: datePickerView.selectedDateView.date!))
103 | let replaced = data.fact.trimmingCharacters(in: NSCharacterSet.whitespaces)
104 |
105 | lblFactsDescription.text = replaced.capitalizingFirstLetter()
106 |
107 | }
108 |
109 | func didPresentOtherMonth(_ monthView: JBDatePickerMonthView) {
110 | self.lblCurrentMnth.text = datePickerView.presentedMonthView.monthDescription
111 |
112 | }
113 | // MARK: - JBDatePickerViewDelegate custom colors
114 | var colorForWeekDaysViewBackground: UIColor {
115 | return UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1.0)
116 | }
117 |
118 | var colorForSelectionCircleForOtherDate: UIColor {
119 | return UIColor(red: 81.0/255.0, green: 92.0/255.0, blue: 229.0/255.0, alpha: 1.0)
120 | }
121 | var colorForSelectionCircleForToday: UIColor
122 | {
123 | return UIColor(red: 81.0/255.0, green: 92.0/255.0, blue: 229.0/255.0, alpha: 1.0)
124 | }
125 | var colorForWeekDaysViewText : UIColor
126 | {
127 | return UIColor(red: 81.0/255.0, green: 92.0/255.0, blue: 229.0/255.0, alpha: 1.0)
128 | }
129 | //MARK:App already launched or not
130 |
131 | /// App already launched or not
132 | ///
133 | /// - Returns: App already launched true or false
134 | func isAppAlreadyLaunchedOnce()->Bool{
135 | let defaults = UserDefaults.standard
136 | if let isAppAlreadyLaunchedOnce = defaults.string(forKey: "kIsAppAlreadyLaunchedOnce"){
137 | print("App already launched : \(isAppAlreadyLaunchedOnce)")
138 | return true
139 | }else{
140 | defaults.set(true, forKey: "kIsAppAlreadyLaunchedOnce")
141 | return false
142 | }
143 | }
144 | //MARK: Read json and save to coredata
145 | private func readJson() {
146 | do {
147 | if let file = Bundle.main.url(forResource: "DidYouKnowFacts", withExtension: "json") {
148 | let data = try Data(contentsOf: file)
149 | let json = try JSONSerialization.jsonObject(with: data, options: [])
150 | if let object = json as? [String: Any] {
151 | // json is a dictionary
152 | print(object)
153 | } else if let object = json as? [Any] {
154 | // json is an array
155 | for data in object{
156 | if let items : NSDictionary = data as? NSDictionary
157 | {
158 | self.factsModel.fact = items["fact"] as!String
159 | self.factsModel.date = items["date"] as! String
160 | arrayFacts.append(self.factsModel)
161 | }
162 |
163 | }
164 | SCDCoreDataWrapper.sharedInstance.saveFacts(facts: arrayFacts, entity: "Facts")
165 | fetchTodaysFact()
166 | print(object)
167 | } else {
168 | print("JSON is invalid")
169 | }
170 | } else {
171 | print("no file")
172 | }
173 | } catch {
174 | print(error.localizedDescription)
175 | }
176 | }
177 |
178 |
179 | }
180 | extension String {
181 | func capitalizingFirstLetter() -> String {
182 | let first = String(characters.prefix(1)).capitalized
183 | let other = String(characters.dropFirst())
184 | return first + other
185 | }
186 |
187 | mutating func capitalizeFirstLetter() {
188 | self = self.capitalizingFirstLetter()
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | Did you know?
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/SharedCoreData.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.application-groups
6 |
7 | group.com.ileaf.SharedCoreData
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/SharedCoreData.xcdatamodeld/.xccurrentversion:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | _XCCurrentVersionName
6 | SharedCoreData.xcdatamodel
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreData/SharedCoreData.xcdatamodeld/SharedCoreData.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreDataTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreDataTests/SharedCoreDataTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SharedCoreDataTests.swift
3 | // SharedCoreDataTests
4 | //
5 | // Created by iLeaf Solutions on 14/12/17.
6 | // Copyright © 2017 iLeaf. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import SharedCoreData
11 |
12 | class SharedCoreDataTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measure {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreDataUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Did-you-know-master/SharedCoreDataUITests/SharedCoreDataUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SharedCoreDataUITests.swift
3 | // SharedCoreDataUITests
4 | //
5 | // Created by iLeaf Solutions on 14/12/17.
6 | // Copyright © 2017 iLeaf. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class SharedCoreDataUITests: XCTestCase {
12 |
13 | override func setUp() {
14 | super.setUp()
15 |
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 |
18 | // In UI tests it is usually best to stop immediately when a failure occurs.
19 | continueAfterFailure = false
20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
21 | XCUIApplication().launch()
22 |
23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
24 | }
25 |
26 | override func tearDown() {
27 | // Put teardown code here. This method is called after the invocation of each test method in the class.
28 | super.tearDown()
29 | }
30 |
31 | func testExample() {
32 | // Use recording to get started writing UI tests.
33 | // Use XCTAssert and related functions to verify your tests produce the correct results.
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Did you Know?
2 | A notification center widget with shared core data.
3 | Example project for sharing data between iOS app extension and container app through shared core data.
4 |
5 |
6 |
7 | ## Preview
8 |
9 |
10 | ## Installation
11 |
12 | ### Compatibility
13 |
14 | - iOS 10.3+
15 |
16 | - Xcode 8.0+
17 |
18 | ## Usage
19 |
20 | 1. Create an app group
21 |
22 | App Groups are the scheme iOS uses to allow different apps to share data. If the apps have the right entitlements and proper provisioning, they can access a shared directory outside of their normal iOS sandbox. To share data between widget extension and container app, select the target for your app and go to the capabilities tab. There, enable app groups. Repeat the same in the target of your widget extension
23 |
24 |
25 |
26 | When you flip that switch, Xcode will talk to the developer center to configure your app ID for app groups. Next it'll ask you for a group name. Give it one and it'll create and download a new provisioning profile. Now, your app and its extension are ready to share the container, so it’s time to put the data in it.
27 |
28 | 2. Create your core data in shared container
29 |
30 | - Move SCDCoreDataWrapper.swift class, the .xcdatamodeled and NSManagedObject subclass to my SharedCode Framework.
31 | - Get the URL of the group container with containerURL(forSecurityApplicationGroupIdentifier: of FileManager passing the container identifier. You need to point to the security group as your store url so that they are both being stored to that.
32 |
33 | ## Author
34 | iLeaf Solutions
35 | [http://www.ileafsolutions.com](http://www.ileafsolutions.com)
36 |
--------------------------------------------------------------------------------