├── LICENSE ├── MyNotes.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── YES.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── MyNotes ├── Assets.xcassets │ ├── AppIcon-beta.appiconset │ │ ├── Contents.json │ │ ├── Icon-20@2x.png │ │ ├── Icon-20@3x.png │ │ ├── Icon-29@2x.png │ │ ├── Icon-29@3x.png │ │ ├── Icon-40@2x.png │ │ ├── Icon-40@3x.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ └── ios-marketing.png │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-20@2x.png │ │ ├── Icon-20@3x.png │ │ ├── Icon-29@2x.png │ │ ├── Icon-29@3x.png │ │ ├── Icon-40@2x.png │ │ ├── Icon-40@3x.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ └── ios-marketing.png │ ├── Background1.imageset │ │ ├── Background1.pdf │ │ └── Contents.json │ ├── Card1.imageset │ │ ├── Card1.pdf │ │ └── Contents.json │ ├── Card2.imageset │ │ ├── Card2.pdf │ │ └── Contents.json │ ├── Card3.imageset │ │ ├── Card3.pdf │ │ └── Contents.json │ ├── Card4.imageset │ │ ├── Card4.pdf │ │ └── Contents.json │ ├── Colors │ │ ├── Color.colorset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── LaunchScreen.colorset │ │ │ └── Contents.json │ │ ├── LogColor.colorset │ │ │ └── Contents.json │ │ ├── RegisterColor.colorset │ │ │ └── Contents.json │ │ ├── RowAnyColor.colorset │ │ │ └── Contents.json │ │ ├── RowDoneColor.colorset │ │ │ └── Contents.json │ │ ├── ShadowColor.colorset │ │ │ └── Contents.json │ │ ├── TextColor.colorset │ │ │ └── Contents.json │ │ ├── background1.colorset │ │ │ └── Contents.json │ │ ├── background2.colorset │ │ │ └── Contents.json │ │ ├── background3.colorset │ │ │ └── Contents.json │ │ ├── card2.colorset │ │ │ └── Contents.json │ │ ├── card3.colorset │ │ │ └── Contents.json │ │ ├── card4.colorset │ │ │ └── Contents.json │ │ ├── card5.colorset │ │ │ └── Contents.json │ │ └── primary.colorset │ │ │ └── Contents.json │ ├── Contents.json │ ├── done.imageset │ │ ├── Contents.json │ │ ├── done-1.png │ │ └── done.png │ ├── find.imageset │ │ ├── Contents.json │ │ ├── find-1.png │ │ └── find.png │ ├── focus.imageset │ │ ├── Card6.pdf │ │ └── Contents.json │ ├── launch.imageset │ │ ├── Contents.json │ │ └── launch.png │ ├── learn.imageset │ │ ├── Contents.json │ │ ├── learn-1.png │ │ └── learn.png │ ├── things.imageset │ │ ├── Contents.json │ │ ├── things-1.png │ │ └── things.png │ ├── think.imageset │ │ ├── Contents.json │ │ ├── think-1.png │ │ └── think.png │ └── time.imageset │ │ ├── Contents.json │ │ ├── time-1.png │ │ └── time.png ├── Base.lproj │ └── LaunchScreen.storyboard ├── ContentView.swift ├── DataModel │ └── MyNotes.xcdatamodeld │ │ ├── .xccurrentversion │ │ └── MyNotes.xcdatamodel │ │ └── contents ├── Delegates │ ├── AppDelegate.swift │ └── SceneDelegate.swift ├── HomeView │ ├── ContentfulLoginView.swift │ ├── ContentfulRegisterView.swift │ ├── HomeView.swift │ ├── LoginView.swift │ ├── MincloudTools.swift │ └── RegisterView.swift ├── Info.plist ├── Lottie │ ├── LottieSyncView.swift │ ├── LottieTestView.swift │ ├── LottieToDoDoneView.swift │ ├── LottieUserLoadingView.swift │ ├── LottieView.swift │ ├── RingView.swift │ ├── bots-channel.json │ ├── card-loading.json │ ├── done.json │ ├── download.json │ ├── loading.json │ ├── success.json │ └── sync.json ├── News │ ├── NewsController.swift │ ├── NewsListView.swift │ └── NewsRowView.swift ├── Notes │ ├── NoteAddView.swift │ ├── NoteCardView.swift │ ├── NoteDetailView.swift │ ├── NoteEditView.swift │ ├── NoteRowView.swift │ ├── NoteSearchResultRowView.swift │ ├── NotesCardListView.swift │ ├── NotesSearchView.swift │ └── NotesTextListView.swift ├── NotesDataModel │ ├── NoteItem+Convenience.swift │ ├── NoteItem+CoreDataClass.swift │ ├── NoteItem+CoreDataProperties.swift │ └── NoteItemController.swift ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── TabView │ └── TabBarView.swift ├── TestPages │ ├── BlurView.swift │ ├── CardsView.swift │ ├── CourseList.swift │ ├── LaunchTest.swift │ ├── NotesListView_old.swift │ └── NotesStore.swift ├── Timer │ ├── TimerController.swift │ └── TimerHomeView.swift ├── ToDos │ ├── ToDoRowView.swift │ ├── ToDosListView.swift │ ├── ToDosSearchResultRowView.swift │ └── ToDosSearchView.swift ├── ToDosDataModel │ ├── ToDoItem+Convenience.swift │ ├── ToDoItem+CoreDataClass.swift │ ├── ToDoItem+CoreDataProperties.swift │ └── ToDoItemController.swift ├── multiLineTextField.swift └── selectableText.swift ├── README.md └── showPics ├── 06BCD721F20815F9EC543A270617D2CD.JPG ├── 4CBCB616F4FE4E2B11071F0708E01276.JPG ├── 5B625FD91844FFFD8B3EE9EC65ECDFA9.JPG ├── 69A4895D8F226B3086C5FB5FB35451DA.JPG ├── 826E72E45F928DED4157610E79C75039.JPG ├── 866AF2BF6E8FF415C75D40CCDF9740BD.JPG ├── A17817B53082F53ED584960716FE6053.JPG ├── ADA3D4E40B173FB681C7CB35AF397FCF.JPG ├── B601B5A0BA233CAC8161F48E986102EE.JPG ├── BA9D268CD0E878BF5790F646B301DB97.JPG ├── EDB36F7F0AA33E667D8EE9B1A22D9702.JPG └── demo.md /MyNotes.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MyNotes.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MyNotes.xcodeproj/xcuserdata/YES.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MyNotes.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 5 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-29@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-29@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-40@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-40@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-60@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-60@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "1024x1024", 53 | "idiom" : "ios-marketing", 54 | "filename" : "ios-marketing.png", 55 | "scale" : "1x" 56 | } 57 | ], 58 | "info" : { 59 | "version" : 1, 60 | "author" : "xcode" 61 | } 62 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-20@2x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-20@3x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-29@2x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-29@3x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-40@2x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-40@3x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon-beta.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon-beta.appiconset/ios-marketing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon-beta.appiconset/ios-marketing.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Icon-20@2x.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "Icon-20@3x.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "Icon-29@2x.png", 17 | "idiom" : "iphone", 18 | "scale" : "2x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "Icon-29@3x.png", 23 | "idiom" : "iphone", 24 | "scale" : "3x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "Icon-40@2x.png", 29 | "idiom" : "iphone", 30 | "scale" : "2x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "filename" : "Icon-40@3x.png", 35 | "idiom" : "iphone", 36 | "scale" : "3x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "Icon-60@2x.png", 41 | "idiom" : "iphone", 42 | "scale" : "2x", 43 | "size" : "60x60" 44 | }, 45 | { 46 | "filename" : "Icon-60@3x.png", 47 | "idiom" : "iphone", 48 | "scale" : "3x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "ios-marketing.png", 53 | "idiom" : "ios-marketing", 54 | "scale" : "1x", 55 | "size" : "1024x1024" 56 | } 57 | ], 58 | "info" : { 59 | "author" : "xcode", 60 | "version" : 1 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-20@2x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-20@3x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-29@2x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-29@3x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/AppIcon.appiconset/ios-marketing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/AppIcon.appiconset/ios-marketing.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Background1.imageset/Background1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/Background1.imageset/Background1.pdf -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Background1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Background1.pdf", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Card1.imageset/Card1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/Card1.imageset/Card1.pdf -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Card1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Card1.pdf", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Card2.imageset/Card2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/Card2.imageset/Card2.pdf -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Card2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Card2.pdf", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Card3.imageset/Card3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/Card3.imageset/Card3.pdf -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Card3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Card3.pdf", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Card4.imageset/Card4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/Card4.imageset/Card4.pdf -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Card4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Card4.pdf", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/Color.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "1.000", 9 | "green" : "1.000", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "1.000", 27 | "green" : "1.000", 28 | "red" : "1.000" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/LaunchScreen.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x81", 9 | "green" : "0x4C", 10 | "red" : "0x0F" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "0.782", 26 | "blue" : "0x81", 27 | "green" : "0x4C", 28 | "red" : "0x0F" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/LogColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xF8", 9 | "green" : "0x78", 10 | "red" : "0x69" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.575", 27 | "green" : "0.106", 28 | "red" : "0.324" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/RegisterColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "1.000", 9 | "green" : "0.590", 10 | "red" : "0.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.575", 27 | "green" : "0.329", 28 | "red" : "0.000" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/RowAnyColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.980", 9 | "green" : "0.961", 10 | "red" : "0.961" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.125", 27 | "green" : "0.118", 28 | "red" : "0.118" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/RowDoneColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.921", 9 | "green" : "0.921", 10 | "red" : "0.921" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.086", 27 | "green" : "0.078", 28 | "red" : "0.078" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/ShadowColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "0.209", 8 | "blue" : "0.000", 9 | "green" : "0.000", 10 | "red" : "0.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "0.000", 26 | "blue" : "0.837", 27 | "green" : "0.837", 28 | "red" : "0.837" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/TextColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "platform" : "ios", 6 | "reference" : "darkTextColor" 7 | }, 8 | "idiom" : "universal" 9 | }, 10 | { 11 | "appearances" : [ 12 | { 13 | "appearance" : "luminosity", 14 | "value" : "dark" 15 | } 16 | ], 17 | "color" : { 18 | "color-space" : "srgb", 19 | "components" : { 20 | "alpha" : "1.000", 21 | "blue" : "1.000", 22 | "green" : "1.000", 23 | "red" : "1.000" 24 | } 25 | }, 26 | "idiom" : "universal" 27 | } 28 | ], 29 | "info" : { 30 | "author" : "xcode", 31 | "version" : 1 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/background1.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0xFF", 13 | "alpha" : "1.000", 14 | "blue" : "0xFF", 15 | "green" : "0xFF" 16 | } 17 | } 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "appearances" : [ 22 | { 23 | "appearance" : "luminosity", 24 | "value" : "dark" 25 | } 26 | ], 27 | "color" : { 28 | "color-space" : "srgb", 29 | "components" : { 30 | "red" : "0x00", 31 | "alpha" : "1.000", 32 | "blue" : "0x00", 33 | "green" : "0x00" 34 | } 35 | } 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/background2.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0xD6", 13 | "alpha" : "1.000", 14 | "blue" : "0xE3", 15 | "green" : "0xD7" 16 | } 17 | } 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "appearances" : [ 22 | { 23 | "appearance" : "luminosity", 24 | "value" : "dark" 25 | } 26 | ], 27 | "color" : { 28 | "color-space" : "srgb", 29 | "components" : { 30 | "red" : "0.067", 31 | "alpha" : "1.000", 32 | "blue" : "0.067", 33 | "green" : "0.067" 34 | } 35 | } 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/background3.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0xFF", 13 | "alpha" : "1.000", 14 | "blue" : "0xFF", 15 | "green" : "0xFF" 16 | } 17 | } 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "appearances" : [ 22 | { 23 | "appearance" : "luminosity", 24 | "value" : "dark" 25 | } 26 | ], 27 | "color" : { 28 | "color-space" : "srgb", 29 | "components" : { 30 | "red" : "0x22", 31 | "alpha" : "1.000", 32 | "blue" : "0x22", 33 | "green" : "0x22" 34 | } 35 | } 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/card2.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0x14", 13 | "alpha" : "1.000", 14 | "blue" : "0xFD", 15 | "green" : "0xBE" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/card3.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0xF7", 13 | "alpha" : "1.000", 14 | "blue" : "0x57", 15 | "green" : "0x37" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/card4.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0x18", 13 | "alpha" : "1.000", 14 | "blue" : "0x4F", 15 | "green" : "0x20" 16 | } 17 | } 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "appearances" : [ 22 | { 23 | "appearance" : "luminosity", 24 | "value" : "dark" 25 | } 26 | ], 27 | "color" : { 28 | "color-space" : "srgb", 29 | "components" : { 30 | "red" : "0x00", 31 | "alpha" : "1.000", 32 | "blue" : "0xE5", 33 | "green" : "0xFF" 34 | } 35 | } 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/card5.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0x00", 13 | "alpha" : "1.000", 14 | "blue" : "0x00", 15 | "green" : "0x00" 16 | } 17 | } 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "appearances" : [ 22 | { 23 | "appearance" : "luminosity", 24 | "value" : "dark" 25 | } 26 | ], 27 | "color" : { 28 | "color-space" : "srgb", 29 | "components" : { 30 | "red" : "0x23", 31 | "alpha" : "1.000", 32 | "blue" : "0xDD", 33 | "green" : "0x57" 34 | } 35 | } 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Colors/primary.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0x18", 13 | "alpha" : "1.000", 14 | "blue" : "0x4F", 15 | "green" : "0x20" 16 | } 17 | } 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "appearances" : [ 22 | { 23 | "appearance" : "luminosity", 24 | "value" : "dark" 25 | } 26 | ], 27 | "color" : { 28 | "color-space" : "srgb", 29 | "components" : { 30 | "red" : "0x00", 31 | "alpha" : "1.000", 32 | "blue" : "0x00", 33 | "green" : "0x00" 34 | } 35 | } 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/done.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "done.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "filename" : "done-1.png", 16 | "idiom" : "universal", 17 | "scale" : "1x" 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "appearances" : [ 25 | { 26 | "appearance" : "luminosity", 27 | "value" : "dark" 28 | } 29 | ], 30 | "idiom" : "universal", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "universal", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "appearances" : [ 39 | { 40 | "appearance" : "luminosity", 41 | "value" : "dark" 42 | } 43 | ], 44 | "idiom" : "universal", 45 | "scale" : "3x" 46 | } 47 | ], 48 | "info" : { 49 | "author" : "xcode", 50 | "version" : 1 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/done.imageset/done-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/done.imageset/done-1.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/done.imageset/done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/done.imageset/done.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/find.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "find.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "filename" : "find-1.png", 16 | "idiom" : "universal", 17 | "scale" : "1x" 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "appearances" : [ 25 | { 26 | "appearance" : "luminosity", 27 | "value" : "dark" 28 | } 29 | ], 30 | "idiom" : "universal", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "universal", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "appearances" : [ 39 | { 40 | "appearance" : "luminosity", 41 | "value" : "dark" 42 | } 43 | ], 44 | "idiom" : "universal", 45 | "scale" : "3x" 46 | } 47 | ], 48 | "info" : { 49 | "author" : "xcode", 50 | "version" : 1 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/find.imageset/find-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/find.imageset/find-1.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/find.imageset/find.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/find.imageset/find.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/focus.imageset/Card6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/focus.imageset/Card6.pdf -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/focus.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Card6.pdf", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/launch.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "launch.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/launch.imageset/launch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/launch.imageset/launch.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/learn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "learn.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "filename" : "learn-1.png", 16 | "idiom" : "universal", 17 | "scale" : "1x" 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "appearances" : [ 25 | { 26 | "appearance" : "luminosity", 27 | "value" : "dark" 28 | } 29 | ], 30 | "idiom" : "universal", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "universal", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "appearances" : [ 39 | { 40 | "appearance" : "luminosity", 41 | "value" : "dark" 42 | } 43 | ], 44 | "idiom" : "universal", 45 | "scale" : "3x" 46 | } 47 | ], 48 | "info" : { 49 | "author" : "xcode", 50 | "version" : 1 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/learn.imageset/learn-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/learn.imageset/learn-1.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/learn.imageset/learn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/learn.imageset/learn.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/things.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "things.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "filename" : "things-1.png", 16 | "idiom" : "universal", 17 | "scale" : "1x" 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "appearances" : [ 25 | { 26 | "appearance" : "luminosity", 27 | "value" : "dark" 28 | } 29 | ], 30 | "idiom" : "universal", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "universal", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "appearances" : [ 39 | { 40 | "appearance" : "luminosity", 41 | "value" : "dark" 42 | } 43 | ], 44 | "idiom" : "universal", 45 | "scale" : "3x" 46 | } 47 | ], 48 | "info" : { 49 | "author" : "xcode", 50 | "version" : 1 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/things.imageset/things-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/things.imageset/things-1.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/things.imageset/things.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/things.imageset/things.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/think.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "think.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "filename" : "think-1.png", 16 | "idiom" : "universal", 17 | "scale" : "1x" 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "appearances" : [ 25 | { 26 | "appearance" : "luminosity", 27 | "value" : "dark" 28 | } 29 | ], 30 | "idiom" : "universal", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "universal", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "appearances" : [ 39 | { 40 | "appearance" : "luminosity", 41 | "value" : "dark" 42 | } 43 | ], 44 | "idiom" : "universal", 45 | "scale" : "3x" 46 | } 47 | ], 48 | "info" : { 49 | "author" : "xcode", 50 | "version" : 1 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/think.imageset/think-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/think.imageset/think-1.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/think.imageset/think.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/think.imageset/think.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/time.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "time.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "filename" : "time-1.png", 16 | "idiom" : "universal", 17 | "scale" : "1x" 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "appearances" : [ 25 | { 26 | "appearance" : "luminosity", 27 | "value" : "dark" 28 | } 29 | ], 30 | "idiom" : "universal", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "universal", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "appearances" : [ 39 | { 40 | "appearance" : "luminosity", 41 | "value" : "dark" 42 | } 43 | ], 44 | "idiom" : "universal", 45 | "scale" : "3x" 46 | } 47 | ], 48 | "info" : { 49 | "author" : "xcode", 50 | "version" : 1 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/time.imageset/time-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/time.imageset/time-1.png -------------------------------------------------------------------------------- /MyNotes/Assets.xcassets/time.imageset/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/MyNotes/Assets.xcassets/time.imageset/time.png -------------------------------------------------------------------------------- /MyNotes/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /MyNotes/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/20. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ContentView: View { 12 | @State private var newTodoItem = "good" 13 | 14 | @State var showTimer = false 15 | 16 | var body: some View { 17 | VStack { 18 | Text("Hello, World!") 19 | 20 | 21 | Button(action: {self.showTimer = true}, 22 | label: {Image(systemName: "timer") 23 | .font(.largeTitle)}) 24 | .sheet(isPresented: $showTimer, content: {TimerHomeView()}) 25 | 26 | } 27 | //.navigationBarTitle("ContentView") 28 | 29 | 30 | } 31 | } 32 | 33 | struct ContentView_Previews: PreviewProvider { 34 | static var previews: some View { 35 | ContentView() 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /MyNotes/DataModel/MyNotes.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | MyNotes.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /MyNotes/DataModel/MyNotes.xcdatamodeld/MyNotes.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /MyNotes/Delegates/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/20. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CoreData 11 | import MinCloud 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate { 15 | 16 | 17 | 18 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | // Override point for customization after application launch. 20 | 21 | //判断是否第一次启动(两个都是第一次则以这个为准) 22 | if UserDefaults.isFirstLaunch() { 23 | print("应用第一次启动") 24 | } 25 | 26 | 27 | if isNewDay(){ 28 | UserDefaults.standard.set(0,forKey: "dailyTimeCount") 29 | } 30 | BaaS.register(clientID: "a841b7c7edd38152e535") 31 | return true 32 | } 33 | 34 | // MARK: UISceneSession Lifecycle 35 | 36 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 37 | // Called when a new scene session is being created. 38 | // Use this method to select a configuration to create the new scene with. 39 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 40 | } 41 | 42 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 43 | // Called when the user discards a scene session. 44 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 45 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 46 | } 47 | 48 | // MARK: - Core Data stack 49 | 50 | lazy var persistentContainer: NSPersistentContainer = { 51 | /* 52 | The persistent container for the application. This implementation 53 | creates and returns a container, having loaded the store for the 54 | application to it. This property is optional since there are legitimate 55 | error conditions that could cause the creation of the store to fail. 56 | */ 57 | let container = NSPersistentContainer(name: "MyNotes") 58 | container.loadPersistentStores(completionHandler: { (storeDescription, error) in 59 | if let error = error as NSError? { 60 | // Replace this implementation with code to handle the error appropriately. 61 | // 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. 62 | 63 | /* 64 | Typical reasons for an error here include: 65 | * The parent directory does not exist, cannot be created, or disallows writing. 66 | * The persistent store is not accessible, due to permissions or data protection when the device is locked. 67 | * The device is out of space. 68 | * The store could not be migrated to the current model version. 69 | Check the error message to determine what the actual problem was. 70 | */ 71 | fatalError("Unresolved error \(error), \(error.userInfo)") 72 | } 73 | }) 74 | return container 75 | }() 76 | 77 | // MARK: - Core Data Saving support 78 | 79 | func saveContext () { 80 | let context = persistentContainer.viewContext 81 | if context.hasChanges { 82 | do { 83 | try context.save() 84 | } catch { 85 | // Replace this implementation with code to handle the error appropriately. 86 | // 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. 87 | let nserror = error as NSError 88 | fatalError("Unresolved error \(nserror), \(nserror.userInfo)") 89 | } 90 | } 91 | } 92 | 93 | } 94 | 95 | -------------------------------------------------------------------------------- /MyNotes/Delegates/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/20. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SwiftUI 11 | 12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 21 | 22 | // Get the managed object context from the shared persistent container. 23 | let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 24 | 25 | // Create the SwiftUI view and set the context as the value for the managedObjectContext environment keyPath. 26 | // Add `@Environment(\.managedObjectContext)` in the views that will need the context. 27 | let contentView = TabBarView().environment(\.managedObjectContext, context) 28 | 29 | // Use a UIHostingController as window root view controller. 30 | if let windowScene = scene as? UIWindowScene { 31 | let window = UIWindow(windowScene: windowScene) 32 | window.rootViewController = UIHostingController(rootView: contentView) 33 | self.window = window 34 | window.makeKeyAndVisible() 35 | } 36 | } 37 | 38 | func sceneDidDisconnect(_ scene: UIScene) { 39 | // Called as the scene is being released by the system. 40 | // This occurs shortly after the scene enters the background, or when its session is discarded. 41 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 42 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 43 | } 44 | 45 | func sceneDidBecomeActive(_ scene: UIScene) { 46 | // Called when the scene has moved from an inactive state to an active state. 47 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 48 | } 49 | 50 | func sceneWillResignActive(_ scene: UIScene) { 51 | // Called when the scene will move from an active state to an inactive state. 52 | // This may occur due to temporary interruptions (ex. an incoming phone call). 53 | } 54 | 55 | func sceneWillEnterForeground(_ scene: UIScene) { 56 | // Called as the scene transitions from the background to the foreground. 57 | // Use this method to undo the changes made on entering the background. 58 | } 59 | 60 | func sceneDidEnterBackground(_ scene: UIScene) { 61 | // Called as the scene transitions from the foreground to the background. 62 | // Use this method to save data, release shared resources, and store enough scene-specific state information 63 | // to restore the scene back to its current state. 64 | 65 | // Save changes in the application's managed object context when the application transitions to the background. 66 | (UIApplication.shared.delegate as? AppDelegate)?.saveContext() 67 | } 68 | 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /MyNotes/HomeView/ContentfulRegisterView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentfulRegisterView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/18. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ContentfulRegisterView: View { 12 | 13 | @State private var username = "" 14 | @State private var pass = "" 15 | @ObservedObject var tool = MincloudTools() 16 | @Binding var show:Bool 17 | 18 | @State var isLoading = false 19 | @State private var isShowingAlert = false 20 | 21 | func register(){ 22 | self.isLoading = true 23 | self.tool.userregister(name: self.username, pass: self.pass) 24 | 25 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5) { 26 | if registeResult{ 27 | print(registeResult) 28 | print("注册界面的成功") 29 | self.isLoading = false 30 | self.show.toggle() 31 | }else{ 32 | print("注册界面的失败") 33 | self.isLoading = false 34 | self.isShowingAlert=true 35 | } 36 | } 37 | 38 | 39 | } 40 | 41 | var body: some View { 42 | ZStack(alignment: .top) { 43 | Color.black 44 | .edgesIgnoringSafeArea(.all) 45 | 46 | Color("background2") 47 | .edgesIgnoringSafeArea(.bottom) 48 | 49 | VStack(spacing:20) { 50 | Text("Registe \n Start Right Now") 51 | .font(.title) 52 | .fontWeight(.bold) 53 | .foregroundColor(.white) 54 | .padding(.top, 40) 55 | .multilineTextAlignment(.center) 56 | 57 | VStack { 58 | HStack { 59 | TextField("Input your username", text: ($username)) 60 | .font(.system(size: 24)) 61 | .padding(.leading) 62 | Spacer() 63 | } 64 | 65 | Divider() 66 | .padding(.leading, 20) 67 | .padding(.trailing, 20) 68 | HStack { 69 | 70 | TextField("Input your passward", text: ($pass)) 71 | .font(.system(size: 24)) 72 | .padding(.leading) 73 | Spacer() 74 | } 75 | 76 | 77 | } 78 | .frame(width: 343, height: 150) 79 | .background(BlurView(style: .systemMaterial)) 80 | .clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous)) 81 | .shadow(color: Color(#colorLiteral(red: 0.1647058824, green: 0.1882352941, blue: 0.3882352941, alpha: 1)).opacity(0.2), radius: 20, x: 0, y: 20) 82 | 83 | 84 | HStack { 85 | Button(action: { 86 | if !self.username.isEmpty && !self.pass.isEmpty { 87 | self.register() 88 | }else { 89 | self.isShowingAlert = true 90 | } 91 | }) { 92 | Text("Registe".uppercased()) 93 | .foregroundColor(.white) 94 | .fontWeight(.bold) 95 | } 96 | .padding(12) 97 | .frame(width: 160) 98 | 99 | .background(Color(.systemGreen)) 100 | .clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous)) 101 | .shadow(color: Color(#colorLiteral(red: 0.1647058824, green: 0.1882352941, blue: 0.3882352941, alpha: 1)).opacity(0.2), radius: 20, x: 0, y: 20) 102 | 103 | } 104 | .padding(.horizontal, 20) 105 | .frame(maxWidth: 400) 106 | 107 | 108 | Spacer() 109 | 110 | 111 | Image("done") 112 | .resizable() 113 | .aspectRatio(contentMode: .fill) 114 | .scaleEffect(0.6) 115 | .offset(y:-75) 116 | 117 | }.frame(maxWidth:screen.width) 118 | .background(Color("RegisterColor")) 119 | .edgesIgnoringSafeArea(.bottom) 120 | 121 | if isLoading { 122 | LottieUserLoadingView() 123 | } 124 | } .alert(isPresented: $isShowingAlert) { 125 | Alert(title: Text("Registe Failed"), message: Text("Check Your Username and Password"), dismissButton: .default(Text("OK"))) 126 | } 127 | 128 | 129 | } 130 | } 131 | 132 | struct ContentfulRegisterView_Previews: PreviewProvider { 133 | static var previews: some View { 134 | ContentfulRegisterView(show: .constant(true)) 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /MyNotes/HomeView/HomeView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/14. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct HomeView: View { 12 | @State var showTimer = false 13 | 14 | //借助控制器获取数据库 15 | @ObservedObject var toDoItemController = toDoItemControllerGLobal 16 | @ObservedObject var noteItemController = NoteItemController() 17 | @Environment(\.presentationMode) var presentationMode 18 | 19 | //@State private var timeCount = timerControllerGlobal.timeCount / 60 20 | 21 | @State var isLogged = UserDefaults.standard.isLoggedIn() 22 | @State var showUser = false 23 | 24 | @State var showRing = false 25 | 26 | var body: some View { 27 | NavigationView{ 28 | List{ 29 | Button(action:{}){ 30 | HStack(spacing: 20) { 31 | RingView(color1: #colorLiteral(red: 0.3647058904, green: 0.06666667014, blue: 0.9686274529, alpha: 1), color2: #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1), width: 75, height: 75, percent: CGFloat(Double(timerControllerGlobal.dailyTimeCount / 60)),show: $showRing) 32 | VStack(alignment: .leading, spacing: 10) { 33 | Text("Focused \(timerControllerGlobal.timeCount / 60) mins Totally") 34 | .font(.system(size: 15)) 35 | Text("Focused \(timerControllerGlobal.dailyTimeCount / 60) mins Today") 36 | .font(.system(size: 17)) 37 | .bold() 38 | Button(action:{ 39 | self.showTimer.toggle() 40 | }){ 41 | HStack { 42 | Text("Start Focus") 43 | .foregroundColor(.white) 44 | .font(.system(size: 17)) 45 | Image(systemName: "timer") 46 | .foregroundColor(.white) 47 | }.padding(.horizontal,20) 48 | 49 | }.sheet(isPresented: $showTimer, content: {TimerHomeView()}) 50 | .frame(height: 40, alignment: .leading) 51 | .background(Color(.systemGreen)) 52 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 53 | .shadow(color: Color("ShadowColor"), radius: 2, x: 0, y: 0) 54 | .padding(.top,5) 55 | } 56 | Spacer() 57 | } 58 | .frame(maxWidth:screen.width) 59 | .frame(height:120) 60 | .padding(10) 61 | .padding(.horizontal,10) 62 | .background(Color("RowAnyColor")) 63 | .clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous)) 64 | .shadow(color: Color("ShadowColor"), radius: 3, x: 0, y: 0) 65 | .padding(.bottom,5) 66 | }.sheet(isPresented: $showTimer, content: {TimerHomeView()}) 67 | 68 | 69 | 70 | Section(header:Text("ToDos").font(.system(size: 15)).foregroundColor(Color(.systemGray))){ 71 | 72 | ForEach(toDoItemController.ToDoItemDataStore, id:\.id){todo in 73 | Group{ 74 | if todo.done == false{ //这里可以加个日期的条件 75 | Button(action: {}){ 76 | ToDoRowView(toDoItemController: self.toDoItemController, toDoItem: todo, done: todo.done, showDone: .constant(false))} 77 | } 78 | } 79 | }.padding(.bottom,-6) 80 | 81 | } 82 | 83 | Image("time") 84 | .resizable() 85 | .aspectRatio(contentMode: .fill) 86 | .padding() 87 | 88 | 89 | }.navigationBarTitle("Home") 90 | .navigationBarItems(trailing: 91 | Button(action: { 92 | self.showUser = true 93 | },label: {Image(systemName: "person.crop.square").font(.largeTitle)}) 94 | .sheet(isPresented: $showUser, content: {ContentfulLoginView(isLogged: self.$isLogged)}) 95 | ) 96 | .onAppear{ 97 | self.showRing = true 98 | } 99 | } 100 | } 101 | } 102 | 103 | 104 | struct HomeView_Previews: PreviewProvider { 105 | static var previews: some View { 106 | HomeView() 107 | .environment(\.colorScheme, .dark) 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /MyNotes/HomeView/LoginView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoginView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/14. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | 12 | struct LoginVieiw: View { 13 | @State private var username = "" 14 | @State private var pass = "" 15 | @ObservedObject var tool = MincloudTools() 16 | @State var showRegister = false 17 | 18 | @Binding var isLogged:Bool 19 | @State private var loggedUsername = UserDefaults.standard.string(forKey: "username") 20 | 21 | var body: some View { 22 | ZStack { 23 | if isLogged { 24 | VStack(spacing:20) { 25 | Text("Userinfo") 26 | Text(loggedUsername ?? "unknow") 27 | .padding(10) 28 | .background(Color(red: 247/255, green: 247/255, blue: 247/255)) 29 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 30 | .shadow(color: Color.black.opacity(0.2), radius: 2) 31 | 32 | Button(action: { 33 | self.tool.userUpload() 34 | }) { 35 | Text("上传本地数据") 36 | } 37 | 38 | Button(action: { 39 | self.tool.userDownload() 40 | }) { 41 | Text("同步云端数据") 42 | } 43 | 44 | 45 | 46 | Button(action: { 47 | UserDefaults.standard.setLoggedIn(value: false) 48 | self.isLogged = UserDefaults.standard.isLoggedIn() 49 | }) { 50 | Text("登出") 51 | } 52 | 53 | 54 | } 55 | 56 | } 57 | 58 | if !isLogged { 59 | VStack { 60 | Text("Login") 61 | TextField("username", text: ($username)) 62 | .padding(10) 63 | .background(Color(red: 247/255, green: 247/255, blue: 247/255)) 64 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 65 | .shadow(color: Color.black.opacity(0.2), radius: 2) 66 | TextField("passward", text: ($pass)) 67 | .padding(10) 68 | .background(Color(red: 247/255, green: 247/255, blue: 247/255)) 69 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 70 | .shadow(color: Color.black.opacity(0.2), radius: 2) 71 | 72 | HStack { 73 | Button(action: { 74 | self.tool.userlogin(name: self.username, pass: self.pass) 75 | 76 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) { 77 | self.isLogged = UserDefaults.standard.isLoggedIn() 78 | print(self.isLogged) 79 | self.loggedUsername = self.username 80 | } 81 | 82 | }) { 83 | Text("登录") 84 | } 85 | 86 | Button(action: { 87 | self.showRegister = true 88 | },label: {Text("注册")}) 89 | .sheet(isPresented: $showRegister, content: {RegisterView(show: self.$showRegister)}) 90 | } 91 | } 92 | } 93 | } 94 | } 95 | 96 | } 97 | 98 | struct LoginVieiw_Previews: PreviewProvider { 99 | static var previews: some View { 100 | LoginVieiw(isLogged: .constant(true)) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /MyNotes/HomeView/RegisterView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RegisterView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/14. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct RegisterView: View { 12 | 13 | @State private var username = "" 14 | @State private var pass = "" 15 | @ObservedObject var tool = MincloudTools() 16 | @Binding var show:Bool 17 | 18 | var body: some View { 19 | VStack { 20 | Text("Register") 21 | TextField("username", text: ($username)) 22 | .padding(10) 23 | .background(Color(red: 247/255, green: 247/255, blue: 247/255)) 24 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 25 | .shadow(color: Color.black.opacity(0.2), radius: 2) 26 | TextField("passward", text: ($pass)) 27 | .padding(10) 28 | .background(Color(red: 247/255, green: 247/255, blue: 247/255)) 29 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 30 | .shadow(color: Color.black.opacity(0.2), radius: 2) 31 | Button(action: { 32 | self.tool.userregister(name: self.username, pass: self.pass) 33 | self.show.toggle() 34 | }) { 35 | Text("注册") 36 | } 37 | } 38 | } 39 | } 40 | 41 | struct RegisterView_Previews: PreviewProvider { 42 | static var previews: some View { 43 | RegisterView(show: .constant(true)) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /MyNotes/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | 37 | 38 | 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UISupportedInterfaceOrientations~ipad 53 | 54 | UIInterfaceOrientationPortrait 55 | UIInterfaceOrientationPortraitUpsideDown 56 | UIInterfaceOrientationLandscapeLeft 57 | UIInterfaceOrientationLandscapeRight 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /MyNotes/Lottie/LottieSyncView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LottieSyncView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/21. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct LottieSyncView: View { 12 | var body: some View { 13 | VStack { 14 | LottieView(filename: "sync") 15 | .frame(width: 400, height: 400) 16 | .foregroundColor(.white) 17 | 18 | } 19 | .padding(-90) 20 | .background(Color(#colorLiteral(red: 0.9607843137, green: 0.9607843137, blue: 0.968627451, alpha: 1))) 21 | .clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous)) 22 | .frame(maxWidth: .infinity, maxHeight: .infinity) 23 | .shadow(color: Color(.black).opacity(0.5), radius: 3, x: 0, y: 0) 24 | .offset(y: -100) 25 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) 26 | } 27 | } 28 | 29 | struct LottieSyncView_Previews: PreviewProvider { 30 | static var previews: some View { 31 | LottieSyncView() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /MyNotes/Lottie/LottieTestView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LottieTestView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/16. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct LottieTestView: View { 12 | var body: some View { 13 | VStack { 14 | LottieView(filename: "card-loading") 15 | .frame(width: 120, height: 120) 16 | 17 | 18 | } 19 | .padding(10) 20 | .background(Color(.gray).opacity(0.3)) 21 | .clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous)) 22 | .frame(maxWidth: .infinity, maxHeight: .infinity) 23 | .offset(y: -100) 24 | } 25 | } 26 | 27 | struct LoadingView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | LottieTestView() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /MyNotes/Lottie/LottieToDoDoneView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LottieToDoDoneView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/21. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct LottieToDoDoneView: View { 12 | var body: some View { 13 | VStack { 14 | LottieView(filename: "done") 15 | .frame(width: 400, height: 400) 16 | 17 | 18 | } 19 | .padding(-80) 20 | //.background(Color(.gray).opacity(0.3)) 21 | .clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous)) 22 | .frame(maxWidth: .infinity, maxHeight: .infinity) 23 | .offset(y: -100) 24 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) 25 | } 26 | } 27 | 28 | struct LottieToDoDoneView_Previews: PreviewProvider { 29 | static var previews: some View { 30 | LottieToDoDoneView() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MyNotes/Lottie/LottieUserLoadingView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LottieUserLoadingView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/21. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct LottieUserLoadingView: View { 12 | var body: some View { 13 | VStack { 14 | LottieView(filename: "card-loading") 15 | .frame(width: 120, height: 120) 16 | 17 | 18 | } 19 | .padding(10) 20 | .background(Color(.gray).opacity(0.3)) 21 | .clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous)) 22 | .frame(maxWidth: .infinity, maxHeight: .infinity) 23 | .offset(y: -100) 24 | } 25 | } 26 | 27 | struct LottieUserLoadingView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | LottieUserLoadingView() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /MyNotes/Lottie/LottieView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LottieView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/16. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import Lottie 11 | 12 | struct LottieView: UIViewRepresentable { 13 | var filename = "" 14 | 15 | func makeUIView(context: UIViewRepresentableContext) -> UIView { 16 | let view = UIView(frame: .zero) 17 | 18 | let animationView = AnimationView() 19 | let animation = Animation.named(filename) 20 | animationView.animation = animation 21 | animationView.contentMode = .scaleAspectFit 22 | animationView.play() 23 | 24 | animationView.translatesAutoresizingMaskIntoConstraints = false 25 | view.addSubview(animationView) 26 | 27 | NSLayoutConstraint.activate([ 28 | animationView.heightAnchor.constraint(equalTo: view.heightAnchor), 29 | animationView.widthAnchor.constraint(equalTo: view.widthAnchor), 30 | ]) 31 | 32 | return view 33 | } 34 | 35 | func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext) { 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /MyNotes/Lottie/RingView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RingView.swift 3 | // MyPlan 4 | // 5 | // Created by YES on 2020/2/28. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct RingView: View { 12 | var color1 = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1) 13 | var color2 = #colorLiteral(red: 0.3647058904, green: 0.06666667014, blue: 0.9686274529, alpha: 1) 14 | var width: CGFloat = 55 15 | var height: CGFloat = 55 16 | var percent: CGFloat = 88 17 | // var multiplier = width / 44 不能定义在这里 18 | @Binding var show: Bool // 要在文件外部也可以动画,要声明绑定而不是状态来接收具体的状态 19 | 20 | var body: some View { 21 | let multiplier = width / 44 22 | let progress = 1 - percent / 100 23 | 24 | return ZStack { 25 | Circle() 26 | .stroke(Color.black.opacity(0.1),style: StrokeStyle(lineWidth: 5 * multiplier)) 27 | .frame(width: width, height: height) 28 | 29 | Circle() 30 | // 圆形开口 31 | .trim(from: show ? progress : 1, to: 1) 32 | // 圆形的样式设计,渐变+笔刷 33 | .stroke( 34 | LinearGradient(gradient: Gradient(colors: [Color(color1),Color(color2)]), startPoint: .topTrailing, endPoint: .bottomLeading), 35 | style: StrokeStyle(lineWidth: 5 * multiplier, lineCap: .round, lineJoin: .round, miterLimit: .infinity, dash: [20,0], dashPhase: 0)) 36 | .rotationEffect(Angle(degrees: 90)) 37 | .rotation3DEffect(Angle(degrees: 180), axis: (x:1, y:0, z:0)) 38 | .frame(width: width, height: height) 39 | .shadow(color: Color(color2).opacity(0.1), radius: 3 * multiplier, x: 0, y: 3 * multiplier) 40 | .animation(.easeInOut) //在外部使用动画更好 41 | 42 | Text("\(Int(percent))") 43 | .font(.system(size: 14 * multiplier)) 44 | .fontWeight(.bold) 45 | .onTapGesture { 46 | self.show.toggle() 47 | } 48 | } 49 | } 50 | } 51 | 52 | struct RingView_Previews: PreviewProvider { 53 | static var previews: some View { 54 | RingView(show: .constant(true)) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /MyNotes/Lottie/loading.json: -------------------------------------------------------------------------------- 1 | {"v":"5.5.10","fr":30,"ip":0,"op":210,"w":1155,"h":700,"nm":"loading black","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":209,"s":[360]}],"ix":10},"p":{"a":0,"k":[573,353,0],"ix":2},"a":{"a":0,"k":[2.18,2.965,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[245.328,245.328],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":30,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":60,"s":[24]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":150,"s":[24]},{"t":180,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":30,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":60,"s":[29]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":150,"s":[29]},{"t":180,"s":[100]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":30,"s":[103]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":60,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":150,"s":[0]},{"t":180,"s":[68]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.984314024682,0.984314024682,0.96470600203,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":27,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[2.18,2.965],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":219,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":209,"s":[360]}],"ix":10},"p":{"a":0,"k":[573,353,0],"ix":2},"a":{"a":0,"k":[2.18,2.965,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[245.328,245.328],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":25,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":55,"s":[36]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":155,"s":[36]},{"t":185,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":25,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":55,"s":[54]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":155,"s":[54]},{"t":185,"s":[100]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":25,"s":[97]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":55,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":155,"s":[0]},{"t":185,"s":[65]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0, 0, 0, 1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":27,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[2.18,2.965],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":219,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":42,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":209,"s":[360]}],"ix":10},"p":{"a":0,"k":[573,353,0],"ix":2},"a":{"a":0,"k":[2.18,2.965,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[245.328,245.328],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":20,"s":[0]},{"i":{"x":[0.709],"y":[1]},"o":{"x":[0.302],"y":[0]},"t":50,"s":[0]},{"i":{"x":[0.779],"y":[1]},"o":{"x":[0.426],"y":[0]},"t":160,"s":[0]},{"t":190,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":20,"s":[0]},{"i":{"x":[0.709],"y":[1]},"o":{"x":[0.302],"y":[0]},"t":50,"s":[32]},{"i":{"x":[0.779],"y":[1]},"o":{"x":[0.426],"y":[0]},"t":160,"s":[32]},{"t":190,"s":[100]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":20,"s":[-277]},{"i":{"x":[0.709],"y":[1]},"o":{"x":[0.302],"y":[0]},"t":50,"s":[-55]},{"i":{"x":[0.779],"y":[1]},"o":{"x":[0.426],"y":[0]},"t":160,"s":[-55]},{"t":190,"s":[64]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.984314024682,0.984314024682,0.96470600203,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":27,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[2.18,2.965],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":219,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":80,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":209,"s":[360]}],"ix":10},"p":{"a":0,"k":[573,353,0],"ix":2},"a":{"a":0,"k":[2.18,2.965,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[245.328,245.328],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":45,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":165,"s":[0]},{"t":195,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":45,"s":[8]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":165,"s":[8]},{"t":195,"s":[100]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[-288]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":45,"s":[-119]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":165,"s":[-119]},{"t":195,"s":[64]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.984314024682,0.984314024682,0.96470600203,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":27,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[2.18,2.965],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":219,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":20,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":209,"s":[360]}],"ix":10},"p":{"a":0,"k":[573,353,0],"ix":2},"a":{"a":0,"k":[2.18,3.965,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[245.328,245.328],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":40,"s":[20]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[20]},{"t":200,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":40,"s":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[100]},{"t":200,"s":[100]}],"ix":2},"o":{"a":0,"k":60,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.98431372549,0.98431372549,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":27,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[2.18,2.965],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":219,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[573,353,0],"ix":2},"a":{"a":0,"k":[3.797,-1.703,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":10,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":200,"s":[100,100,100]},{"t":209,"s":[0,0,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[332.594,332.594],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.0196078431372549, 0.9490196078431372, 0.8823529411764706, 1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.797,-2.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":219,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /MyNotes/News/NewsController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NewsController.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/19. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Combine 11 | import MinCloud 12 | 13 | struct Book: Identifiable { 14 | let id: String 15 | var name: String 16 | var author: String 17 | var price: Float 18 | var content: String 19 | var coverUrl: String 20 | } 21 | 22 | 23 | struct News: Identifiable { 24 | let id: String 25 | var publicTime: String 26 | var title: String 27 | var content: String 28 | } 29 | 30 | 31 | final class NewsStore: ObservableObject { 32 | let newsTable = Table(tableId: "Subscribe") // 建立一个 Table 对象,bookshelf 是知晓云的一个数据表,通过 bookTable 可以操作 bookshelf 表。 33 | 34 | @Published var newsStore: [News] = [] // 书籍列表 35 | 36 | 37 | func fetch() { 38 | let query = Query() 39 | query.orderBy = ["-created_at"] 40 | 41 | newsTable.find(query: query) { (recordList, error) in 42 | var newsStore: [News] = [] 43 | recordList?.records?.forEach({ (record) in 44 | let id = record.Id! 45 | let publicTime = record.get("time") as! String 46 | let title = record.get("title") as! String 47 | let content = record.get("content") as! String 48 | let news = News(id: id, publicTime: publicTime, title: title, content: content) 49 | newsStore.append(news) 50 | //print(id) 51 | }) 52 | 53 | DispatchQueue.main.async { 54 | self.newsStore = newsStore 55 | } 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /MyNotes/News/NewsListView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NewsListView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/20. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct NewsListView: View { 12 | 13 | 14 | @ObservedObject var store = NewsStore() 15 | 16 | var body: some View { 17 | NavigationView(){ 18 | List(store.newsStore) { item in 19 | NewsRowView(news: item) 20 | } 21 | .onAppear(perform: { self.store.fetch() }) 22 | .navigationBarTitle(Text("Subscribe")) 23 | .navigationBarItems(trailing: Button(action:{self.store.fetch()}){ 24 | Image(systemName: "exclamationmark.square") 25 | .font(.largeTitle) 26 | }) 27 | } 28 | } 29 | } 30 | 31 | struct NewsListView_Previews: PreviewProvider { 32 | static var previews: some View { 33 | NewsListView() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /MyNotes/News/NewsRowView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NewsRow.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/20. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct NewsRowView: View { 12 | var news: News 13 | 14 | var body: some View { 15 | VStack { 16 | HStack { 17 | Image(systemName: "hexagon") 18 | Text(news.publicTime) 19 | Spacer() 20 | } 21 | .foregroundColor(Color(#colorLiteral(red: 0.7450980544, green: 0.1568627506, blue: 0.07450980693, alpha: 1))) 22 | 23 | HStack { 24 | Text(news.title) 25 | .font(.headline) 26 | Spacer() 27 | }.padding(.leading,30) 28 | 29 | HStack { 30 | Text(news.content) 31 | .font(.subheadline) 32 | Spacer() 33 | }.padding(.leading,30) 34 | .foregroundColor(Color(.systemGray2)) 35 | .offset(x: 0, y: 10) 36 | }.padding(.bottom,30) 37 | } 38 | } 39 | 40 | struct NewsRowView_Previews: PreviewProvider { 41 | static var previews: some View { 42 | NewsRowView(news: News(id: "123", publicTime: "14:32", title: "基于CRISPR的新冠病毒快速诊断技术出现", content: "据科技日报,英国《自然·生物技术》杂志近日公开的一项生物医学研究,美国科学家报告了一种基于 CRISPR 的诊断工具可以快速检测出新冠病毒。")) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /MyNotes/Notes/NoteAddView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NoteAddView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/25. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct NoteAddView: View { 12 | @ObservedObject var noteItemController: NoteItemController 13 | @State private var title = "" 14 | @State private var content = "Write something?" 15 | @State private var isShowingAlert = false 16 | @State private var contentInputTips = "Write something?" 17 | 18 | @Environment(\.presentationMode) var presentationMode 19 | 20 | var body: some View { 21 | NavigationView{ 22 | VStack(spacing:20){ 23 | VStack(spacing:1) { 24 | HStack { 25 | Text("Title") 26 | .font(.system(size: 25)) 27 | Spacer() 28 | } 29 | TextField("Note title", text: ($title)) 30 | .padding(10) 31 | .background(Color(.systemGray5)) 32 | .clipShape(RoundedRectangle(cornerRadius: 15, style: .continuous)) 33 | } 34 | VStack(spacing:1) { 35 | HStack { 36 | Text("Content") 37 | .font(.system(size: 25)) 38 | Spacer() 39 | } 40 | 41 | multiLineTextField(text: $content) 42 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 43 | } 44 | Spacer() 45 | 46 | Button(action:{ 47 | //非空则保存 48 | if !self.title.isEmpty && !self.content.isEmpty{ 49 | self.noteItemController.createNoteItem(title: self.title, content: self.content) 50 | //重置绑定 51 | self.title = "" 52 | self.content = "" 53 | //? 54 | self.presentationMode.wrappedValue.dismiss() 55 | }else { 56 | self.isShowingAlert = true 57 | } 58 | }){ 59 | Text("Add Note") 60 | .foregroundColor(.white) 61 | .font(.system(size: 20)) 62 | .frame(width: 300, height: 50, alignment: .center) 63 | } 64 | .padding() 65 | .frame(width: 300, height: 50, alignment: .center) 66 | .background(Color(.blue)) 67 | .clipShape(RoundedRectangle(cornerRadius: 15, style: .continuous)) 68 | .shadow(color: Color(.blue).opacity(0.3), radius: 5, x: 0, y: 5) 69 | }.padding() 70 | .navigationBarTitle("Add a Note", displayMode: .automatic) 71 | .alert(isPresented: $isShowingAlert) { 72 | Alert(title: Text("Warning"), message: Text("No Content"), dismissButton: .default(Text("OK"))) 73 | } 74 | } 75 | } 76 | } 77 | 78 | struct NoteAddView_Previews: PreviewProvider { 79 | static var previews: some View { 80 | NoteAddView(noteItemController: NoteItemController()) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /MyNotes/Notes/NoteCardView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NoteRowView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/25. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | 10 | import SwiftUI 11 | import UIKit 12 | 13 | struct NoteCardView: View { 14 | 15 | var noteItemController: NoteItemController 16 | @State var noteItem: NoteItem 17 | 18 | @Binding var showFullView: Bool 19 | @Binding var active: Bool // 状态栏显示与否的绑定 20 | var index: Int 21 | @State var showEditView = false 22 | 23 | @Binding var activeIndex: Int 24 | 25 | // 卡片展开时的手势拖动 26 | @Binding var activeView: CGSize 27 | 28 | var colorOfRowIndex: Int 29 | 30 | var colors = [#colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1),#colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1),#colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1),#colorLiteral(red: 0.9568627477, green: 0.6588235497, blue: 0.5450980663, alpha: 1),#colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1),#colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1)] 31 | 32 | @Environment(\.presentationMode) var presentationMode 33 | 34 | var timeFormatter: String { 35 | let formatter = DateFormatter() 36 | formatter.dateFormat = "yy-MM-dd, HH:mm" 37 | let dateString = formatter.string(from: noteItem.createdAt ?? Date()) 38 | 39 | let returnString = "\(dateString)" 40 | return returnString 41 | } 42 | 43 | var body: some View { 44 | ZStack(alignment: .top) { 45 | VStack(alignment: .leading, spacing: 10.0) { 46 | HStack{ 47 | Text("Content") 48 | .font(.system(size: 24, weight: .bold)) 49 | Spacer() 50 | } 51 | HStack { 52 | Text(noteItem.content ?? "content") 53 | Spacer() 54 | } 55 | 56 | } 57 | .padding(30) 58 | .offset(y : showFullView ? 240 : 0) 59 | //不showFullView的时候文本藏在上面的VStack下 60 | .frame(maxWidth: showFullView ? .infinity : screen.width - 60, maxHeight: showFullView ? .infinity : 200, alignment: .top) 61 | .background(Color("RowAnyColor")) 62 | .clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous)) 63 | .shadow(color: Color("ShadowColor"), radius: 20, x: 0, y: 20) 64 | .opacity(showFullView ? 1 : 0) 65 | VStack { 66 | HStack(alignment: .top) { 67 | VStack(alignment: .leading, spacing: 8.0) { 68 | Text(noteItem.title ?? "no title") 69 | .font(.system(size: 24, weight: .bold)) 70 | .foregroundColor(Color.white) 71 | .offset(x: 0, y: showFullView ? 20 : 0) 72 | 73 | 74 | Text(showFullView ? timeFormatter : noteItem.content ?? "no content") 75 | .offset(x: 0, y: showFullView ? 20 : 0) 76 | .foregroundColor(Color.white) 77 | 78 | } 79 | Spacer() 80 | 81 | // ZStack { 82 | // HStack { 83 | // VStack { 84 | // Image(systemName: "xmark") 85 | // .font(.system(size: 16, weight: .medium)) 86 | // .foregroundColor(.white) 87 | // } 88 | // .frame(width: 36, height: 36) 89 | // .background(Color.black) 90 | // .clipShape(Circle()) 91 | // .opacity(showFullView ? 1 : 0) 92 | // } 93 | // } 94 | } 95 | Spacer() 96 | } 97 | .padding(showFullView ? 30 : 20) 98 | .padding(.top, showFullView ? 30 : 0) 99 | .frame(maxWidth: showFullView ? .infinity : screen.width - 60 , maxHeight: showFullView ? 240 : 180) 100 | .background(Color(self.colors[colorOfRowIndex])) 101 | .clipShape(RoundedRectangle(cornerRadius: showFullView ? 10 :30, style: .continuous)) 102 | .shadow(color: Color(self.colors[colorOfRowIndex]).opacity(0.3), radius: 20, x: 0, y: 20) 103 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) 104 | .gesture( 105 | showFullView ? 106 | DragGesture() 107 | .onChanged{ 108 | value in 109 | guard value.translation.height < 150 else{ return } 110 | guard value.translation.height > 0 else{ return } 111 | self.activeView = value.translation 112 | } 113 | .onEnded{ 114 | value in 115 | if self.activeView.height > 50 { 116 | self.showFullView = false 117 | self.active = false 118 | self.activeIndex = -1 119 | } 120 | self.activeView = .zero 121 | } 122 | : nil //showFullView时开启手势,否则无 123 | ) 124 | .onTapGesture { 125 | self.showFullView.toggle() 126 | self.active.toggle() 127 | 128 | // 获取当前活动状态的卡片索引 129 | if self.showFullView { 130 | print(self.index) 131 | self.activeIndex = self.index 132 | } 133 | else{ 134 | self.activeIndex = -1 135 | } 136 | } 137 | } 138 | .frame(height: showFullView ? screen.height : 280) 139 | .scaleEffect(1 - self.activeView.height / 1000 ) 140 | .rotation3DEffect(Angle(degrees: Double(self.activeView.height / 10)), axis: (x: 0, y: 10, z: 0)) 141 | .hueRotation(Angle(degrees: Double(self.activeView.height))) 142 | .edgesIgnoringSafeArea(.all) 143 | .gesture( 144 | showFullView ? 145 | DragGesture() 146 | .onChanged{ 147 | value in 148 | guard value.translation.height < 150 else{ return } 149 | guard value.translation.height > 0 else{ return } 150 | self.activeView = value.translation 151 | } 152 | .onEnded{ 153 | value in 154 | if self.activeView.height > 50 { 155 | self.showFullView = false 156 | self.active = false 157 | self.activeIndex = -1 158 | } 159 | self.activeView = .zero 160 | } 161 | : nil //showFullView时开启手势,否则无 162 | ) 163 | .animation(.spring(response: 0.5, dampingFraction: 0.9, blendDuration: 0)) 164 | } 165 | } 166 | //struct NoteRowView_Previews: PreviewProvider { 167 | // static var previews: some View { 168 | // NoteRowView() 169 | // } 170 | //} 171 | 172 | extension Array { 173 | /// 从数组中返回一个随机元素 174 | public var sample: Element? { 175 | //如果数组为空,则返回nil 176 | guard count > 0 else { return nil } 177 | let randomIndex = Int(arc4random_uniform(UInt32(count))) 178 | return self[randomIndex] 179 | } 180 | 181 | /// 从数组中从返回指定个数的元素 182 | /// 183 | /// - Parameters: 184 | /// - size: 希望返回的元素个数 185 | /// - noRepeat: 返回的元素是否不可以重复(默认为false,可以重复) 186 | public func sample(size: Int, noRepeat: Bool = false) -> [Element]? { 187 | //如果数组为空,则返回nil 188 | guard !isEmpty else { return nil } 189 | 190 | var sampleElements: [Element] = [] 191 | 192 | //返回的元素可以重复的情况 193 | if !noRepeat { 194 | for _ in 0.. NSFetchRequest { 17 | return NSFetchRequest(entityName: "NoteItem") 18 | } 19 | 20 | @NSManaged public var content: String? 21 | @NSManaged public var createdAt: Date? 22 | @NSManaged public var id: UUID? 23 | @NSManaged public var title: String? 24 | @NSManaged public var modifiedAt: Date? 25 | @NSManaged public var showFullView: Bool 26 | } 27 | -------------------------------------------------------------------------------- /MyNotes/NotesDataModel/NoteItemController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NoteItemController.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/24. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | import Combine 12 | import UIKit 13 | 14 | class NoteItemController: ObservableObject { 15 | @Published var NoteItemDataStore: [NoteItem] = [] 16 | 17 | init(){ 18 | //初始化的时候直接从CoreData获取这个实体的数据,然后把所有内容读入到DataStore数组中 19 | getAllNoteItems() 20 | } 21 | 22 | //获取所有数据 23 | func getAllNoteItems(){ 24 | let fetchRequest: NSFetchRequest = 25 | NoteItem.fetchRequest() 26 | 27 | // moc是ManagedObjectContext 受托上下文 28 | let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 29 | 30 | do{ 31 | NoteItemDataStore = try moc.fetch(fetchRequest) 32 | } catch{ 33 | NSLog("Error fetching tasks: \(error)") 34 | } 35 | } 36 | 37 | //保存 38 | func saveToPersistentStore() { 39 | let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 40 | do { 41 | try moc.save() 42 | getAllNoteItems() 43 | //保存后再读取 44 | } catch { 45 | NSLog("Error saving managed object context: \(error)") 46 | } 47 | } 48 | 49 | //条件查询 50 | func searchNoteItems(contain:String) { 51 | let fetchRequest: NSFetchRequest = NoteItem.fetchRequest() 52 | 53 | //查询条件,包含传入的字符串的项放入DataStore 54 | let pre = NSPredicate(format: "content contains[c] %@", "\(contain)") 55 | fetchRequest.predicate = pre 56 | let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 57 | 58 | do { 59 | NoteItemDataStore = try moc.fetch(fetchRequest) 60 | 61 | } catch { 62 | NSLog("Error fetching tasks: \(error)") 63 | 64 | } 65 | } 66 | 67 | //创建后直接保存 68 | func createNoteItem(title: String, content: String) { 69 | _ = NoteItem(createdAt: Date(), title: title, content: content) 70 | saveToPersistentStore() 71 | } 72 | 73 | //创建后直接保存 74 | func createNoteItem(title: String, content: String, createdAt: Date) { 75 | _ = NoteItem(createdAt: createdAt, title: title, content: content) 76 | saveToPersistentStore() 77 | } 78 | 79 | //更新, 传入一个Item实例对象, 修改这个实例 80 | func updateNoteItem(noteItemInstance: NoteItem, title: String, content: String) { 81 | let date = Date() 82 | noteItemInstance.title = title 83 | noteItemInstance.content = content 84 | noteItemInstance.modifiedAt = date 85 | saveToPersistentStore() 86 | } 87 | 88 | //删除,直接删除实例对象 89 | func deleteNoteItem(noteItemInstance: NoteItem) { 90 | let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 91 | moc.delete(noteItemInstance) 92 | saveToPersistentStore() 93 | } 94 | 95 | //删除,根据索引删除 96 | func deleteNoteItem(at indexSet: IndexSet) { 97 | guard let index = Array(indexSet).first else { return } 98 | //找到索引后定义对象 99 | let noteItemInstance = self.NoteItemDataStore[index] 100 | 101 | deleteNoteItem(noteItemInstance: noteItemInstance) 102 | } 103 | 104 | //删除 105 | func deleteAllNoteItem() { 106 | for noteItem in self.NoteItemDataStore { 107 | deleteNoteItem(noteItemInstance: noteItem) 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /MyNotes/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /MyNotes/TabView/TabBarView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/20. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct TabBarView: View { 12 | @State private var selection = 0 13 | 14 | var body: some View { 15 | TabView(selection: $selection){ 16 | HomeView() 17 | .tabItem { 18 | VStack { 19 | Image(systemName: "house") 20 | Text("Home") 21 | } 22 | } 23 | .tag(0) 24 | 25 | ToDosListView() 26 | .tabItem { 27 | VStack { 28 | Image(systemName: "flag") 29 | Text("Todo") 30 | } 31 | } 32 | .tag(1) 33 | 34 | 35 | NotesTextListView() 36 | .tabItem { 37 | VStack { 38 | Image(systemName: "pencil.and.outline") 39 | Text("Note") 40 | } 41 | } 42 | .tag(3) 43 | 44 | NotesCardListView() 45 | .tabItem { 46 | VStack { 47 | Image(systemName: "creditcard") 48 | Text("NoteCard") 49 | } 50 | } 51 | .tag(4) 52 | 53 | NewsListView() 54 | .tabItem { 55 | VStack { 56 | Image(systemName: "cube.box") 57 | Text("Subscribe") 58 | } 59 | } 60 | .tag(5) 61 | 62 | } 63 | //.edgesIgnoringSafeArea(.top) 64 | } 65 | } 66 | 67 | struct TabBarView_Previews: PreviewProvider { 68 | static var previews: some View { 69 | TabBarView() 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /MyNotes/TestPages/BlurView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlurView.swift 3 | // MyPlan 4 | // 5 | // Created by YES on 2020/2/29. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct BlurView: UIViewRepresentable { 12 | typealias UIViewType = UIView 13 | var style: UIBlurEffect.Style //可以自定义 14 | 15 | // 创建基本UI 16 | func makeUIView(context: UIViewRepresentableContext) -> UIView { 17 | let view = UIView(frame: CGRect.zero) //普通swift视图 18 | view.backgroundColor = .clear 19 | 20 | let blurEffect = UIBlurEffect(style: style) 21 | let blurView = UIVisualEffectView(effect: blurEffect) 22 | blurView.translatesAutoresizingMaskIntoConstraints = false 23 | view.insertSubview(blurView, at: 0) 24 | 25 | NSLayoutConstraint.activate([ 26 | //blurView的约束等于view的宽度和高度 27 | blurView.widthAnchor.constraint(equalTo: view.widthAnchor), 28 | blurView.heightAnchor.constraint(equalTo: view.heightAnchor) 29 | ]) 30 | 31 | return view 32 | } 33 | 34 | // 动画、绑定等内容的UI 35 | func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext) { 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /MyNotes/TestPages/CardsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CardsView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/20. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import UIKit 11 | 12 | struct CardsView: View { 13 | @State var show = false //声明状态,在动画状态间切换 14 | @State var viewState = CGSize.zero //声明状态,使手势可用.CGSize包含一个width和一个height 15 | @State var showCard = false 16 | @State var bottomState = CGSize.zero //底部状态 17 | @State var showFull = false // 底部信息拉开的状态 18 | 19 | @State private var newTodoItem = "Input here" 20 | 21 | @Environment(\.managedObjectContext) var managedObjectContext 22 | // @FetchRequest(fetchRequest: ToDoItem.getAllToDoItems()) var toDoItems:FetchedResults 23 | 24 | 25 | var body: some View { 26 | ZStack { //三维堆叠 27 | TitleView() 28 | .blur(radius: show ? 20: 0 ) 29 | .opacity(showCard ? 0.4 : 1) 30 | .offset(y:showCard ? -200 : 0) 31 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) //时序曲线动画 32 | 33 | 34 | CardView() 35 | .frame(width: showCard ? 375 : 340.0, height: 220.0) //设置Stack大小 36 | .background(Color.black) //设置Stack颜色 37 | //.cornerRadius(20) //设置Stack圆角 38 | .clipShape(RoundedRectangle(cornerRadius: showCard ? 30: 20, style: .continuous)) 39 | //.shadow(radius: 20) //阴影 40 | .offset(x:viewState.width,y:viewState.height) // 卡片位置由状态决定,状态随着拖动被改变 41 | .offset(y:showCard ? -100: 0) 42 | .blendMode(.hardLight) //混合模式(类似PS) 43 | .animation(.spring(response: 0.3, dampingFraction: 0.6, blendDuration: 0)) //.spring 动画,有点反弹的意思,response是响应时间 44 | .onTapGesture { // 单击卡片的手势 45 | //self.show.toggle() //show变量切换 46 | self.showCard.toggle() //showCard变量切换 47 | } 48 | .gesture( 49 | DragGesture().onChanged{ //拖动时更新值 50 | value in 51 | self.viewState = value.translation //用state存储位置 52 | self.show = true // 拖动时展开+模糊 53 | } 54 | .onEnded{ //结束拖动时归零 55 | value in 56 | self.viewState = .zero 57 | self.show = false // 结束时复原 58 | } 59 | ) 60 | 61 | 62 | //底部信息栏,可以拖动并悬停在具体位置-用文本实时显示位置 63 | //Text("\(bottomState.height)").offset(y:-300) 64 | BottomCardView(show: $showCard, text: $newTodoItem) 65 | .offset(x:0, y: showCard ? 360 : 1000) 66 | .offset(y:bottomState.height) // 卡片位置由状态决定,状态随着拖动被改变 67 | .blur(radius: show ? 20 : 0 ) 68 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) //时序曲线动画 69 | .gesture( 70 | DragGesture().onChanged{ //拖动时更新值 71 | value in 72 | self.bottomState = value.translation 73 | if self.showFull{ 74 | self.bottomState.height += -300 // 如果是在full状态,则从-300开始而不是从0开始 75 | } 76 | if self.bottomState.height < -300 { 77 | self.bottomState.height = -300 //不允许拖动超过上限 78 | } 79 | } 80 | .onEnded{ //结束拖动时归零 81 | value in 82 | if self.bottomState.height > 50{ //拖动点向上为负 83 | self.showCard = false //向下拖动到一定就解除 84 | } 85 | if (self.bottomState.height < -100 && !self.showFull) || (self.bottomState.height < -250 && self.showFull) { 86 | self.bottomState.height = -300 87 | self.showFull = true 88 | }else{ 89 | self.bottomState = .zero // 注意这里要else时归回原位 90 | self.showFull = false 91 | } 92 | 93 | 94 | } 95 | ) 96 | 97 | 98 | } 99 | } 100 | } 101 | 102 | struct CardsView_Previews: PreviewProvider { 103 | static var previews: some View { 104 | CardsView() 105 | } 106 | } 107 | 108 | struct CardView: View { 109 | var body: some View { 110 | VStack { //这个VStackb是第一层 111 | HStack { 112 | VStack(alignment: .leading) { 113 | Text("UI Design") 114 | .font(.title) 115 | .fontWeight(.semibold) 116 | .foregroundColor(Color.white) 117 | Text("Certificates") 118 | .foregroundColor(Color("accent")) 119 | } 120 | Spacer() 121 | Image("Logo1") 122 | } 123 | .padding(.horizontal,20)//左右外框边距 124 | .padding(.top,20)//上外框边距 125 | Spacer() 126 | Image("Card1") 127 | .resizable() //图片适应Stack 128 | .aspectRatio(contentMode: .fill) //图片保持比例,并且设置格式fill 129 | .frame(width: 300, height: 110, alignment: .top) //图片填充时的限制 130 | } 131 | } 132 | } 133 | 134 | struct BackCardView: View { 135 | var body: some View { 136 | VStack{ 137 | Spacer() //占位先 138 | } 139 | } 140 | } 141 | 142 | struct TitleView: View { 143 | var body: some View { 144 | VStack { 145 | HStack { 146 | Text("Notes") 147 | .font(.largeTitle) 148 | .fontWeight(.bold) 149 | Spacer() 150 | } 151 | .padding() 152 | Image("Background1") 153 | Spacer() 154 | } 155 | } 156 | } 157 | 158 | struct BottomCardView: View { 159 | // showCard 的时候才显示进度 160 | @Binding var show: Bool 161 | @Binding var text:String 162 | 163 | @Environment(\.managedObjectContext) var managedObjectContext 164 | // @FetchRequest(fetchRequest: ToDoItem.getAllToDoItems()) var toDoItems:FetchedResults 165 | 166 | var body: some View { 167 | VStack(spacing: 20){ 168 | //(spacing:20)为堆栈中的每个元素设置间隔 169 | Rectangle() //小home键 170 | .frame(width: 40, height: 5) 171 | .cornerRadius(3) 172 | .opacity(0.8) 173 | 174 | 175 | VStack(alignment:.leading) { 176 | HStack() { 177 | multiLineTextField(text: $text) 178 | .frame(height: 150) 179 | .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.purple, lineWidth: 2)) 180 | Button(action:{ 181 | print(self.text) 182 | let toDoItem = ToDoItem(context: self.managedObjectContext) 183 | //可以获取到字段 184 | // toDoItem.title = self.text 185 | toDoItem.createdAt = Date() 186 | do{ 187 | //保存被管理对象内容 188 | try self.managedObjectContext.save() 189 | }catch{print(error)} 190 | 191 | self.text = "Done" 192 | 193 | 194 | }){Image(systemName: "plus.circle.fill") 195 | .foregroundColor(.green) 196 | .imageScale(.large) 197 | }.frame(height: 100) 198 | } 199 | Text(self.text) 200 | .multilineTextAlignment(.leading) 201 | .font(.subheadline) 202 | .lineSpacing(4) 203 | } 204 | // 205 | 206 | 207 | Spacer() 208 | 209 | 210 | } 211 | .padding(.top,8) 212 | .padding(.horizontal,20) 213 | .frame(maxWidth:.infinity) //将这个VStack推到最大宽度 214 | .background(BlurView(style: .systemThinMaterial)) 215 | .cornerRadius(30) 216 | .shadow(radius: 20) 217 | } 218 | } 219 | 220 | -------------------------------------------------------------------------------- /MyNotes/TestPages/CourseList.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CourseList.swift 3 | // MyPlan 4 | // 5 | // Created by YES on 2020/2/28. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | //let screen = UIScreen.main.bounds //以后可以调用视图的尺寸信息,不用像素值 11 | 12 | struct CourseList: View { 13 | @State var courses = courseData 14 | @State var active = false 15 | @State var activeIndex = -1 16 | @State var activeView = CGSize.zero 17 | 18 | @State var content = "ContentContentContentContentContentContentContentContentContentContentContent" 19 | 20 | var body: some View { 21 | ZStack { 22 | Color.black.opacity(Double(self.activeView.height / 500)) 23 | .animation(.linear) 24 | .edgesIgnoringSafeArea(.all) 25 | 26 | ScrollView { 27 | VStack(spacing: 30) { 28 | Text("Notes").font(.largeTitle).bold() 29 | .frame(maxWidth: .infinity, alignment: .leading) 30 | .padding(.leading, 30) 31 | .padding(.top, 30) 32 | .blur(radius: active ? 30 : 0) //卡片激活时,标题模糊 33 | 34 | // 使用了数组索引 35 | ForEach(courses.indices, id: \.self) { 36 | index in 37 | GeometryReader { 38 | gemotry in 39 | CourseView( 40 | show: self.$courses[index].show, 41 | course: self.courses[index], 42 | active: self.$active, 43 | index: index, 44 | activeIndex: self.$activeIndex, 45 | activeView: self.$activeView, 46 | text: self.$content) //在GeometrReader中,添加self 47 | .offset(y: self.courses[index].show ? -gemotry.frame(in: .global).minY : 0) //如果show,就移动 -gemotry.xxx的距离,抵消当前gemotry.xx.minY 48 | .opacity(self.activeIndex != index && self.active ? 0 : 1) 49 | .scaleEffect(self.activeIndex != index && self.active ? 0.5 : 1) 50 | .offset(x: self.activeIndex != index && self.active ? screen.width : 0) 51 | } 52 | //.frame(height: self.courses[index].show ? screen.height : 280) 53 | .frame(height: 280) 54 | .frame(maxWidth: self.courses[index].show ? .infinity : screen.width - 60) 55 | .zIndex(self.courses[index].show ? 1 : 0) //show时为z轴索引为1,在0的上面 56 | } 57 | } 58 | .frame(width: screen.width) //ScrollView的宽度 59 | .animation(.spring(response: 0.5, dampingFraction: 0.6, blendDuration: 0)) 60 | // 卡片激活时,隐藏状态栏 61 | .statusBar(hidden: active ? true : false) 62 | .animation(.linear) 63 | } 64 | } 65 | } 66 | } 67 | 68 | 69 | struct CourseList_Previews: PreviewProvider { 70 | static var previews: some View { 71 | CourseList() 72 | } 73 | } 74 | 75 | struct CourseView: View { 76 | @Binding var show: Bool 77 | var course: Course 78 | @Binding var active: Bool // 状态栏显示与否的绑定 79 | 80 | var index: Int 81 | @Binding var activeIndex: Int 82 | 83 | // 卡片展开时的手势拖动 84 | @Binding var activeView: CGSize 85 | @Binding var text: String 86 | @State var showDetail = false 87 | 88 | var body: some View { 89 | ZStack(alignment: .top) { 90 | VStack(alignment: .leading, spacing: 10.0) { 91 | Text("Content") 92 | .font(.title).bold() 93 | 94 | HStack { 95 | Text(text) 96 | Spacer() 97 | } 98 | 99 | Button(action:{self.showDetail.toggle()}) { 100 | Image(systemName: "bell") 101 | .renderingMode(.original) 102 | .font(.system(size: 16, weight: .medium)) 103 | .frame(width:36, height: 36) 104 | .background(Color.white) 105 | .clipShape(Circle()) 106 | .shadow(color: Color.black.opacity(0.1), radius: 1, x: 0, y: 1) 107 | .shadow(color: Color.black.opacity(0.2), radius: 10, x: 0, y: 10) 108 | } 109 | .sheet(isPresented: $showDetail){ //单击按钮时展示内容 110 | ContentView() 111 | } 112 | 113 | 114 | 115 | } 116 | .padding(30) 117 | .offset(y : show ? 330 : 0) 118 | //不show的时候文本藏在上面的VStack下 119 | .frame(maxWidth: show ? .infinity : screen.width - 60, maxHeight: show ? .infinity : 200, alignment: .top) 120 | .background(Color.white) 121 | .clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous)) 122 | .shadow(color: Color.black.opacity(0.2), radius: 20, x: 0, y: 20) 123 | .opacity(show ? 1 : 0) 124 | 125 | 126 | VStack { 127 | HStack(alignment: .top) { 128 | VStack(alignment: .leading, spacing: 8.0) { 129 | Text(course.title) 130 | .font(.system(size: 24, weight: .bold)) 131 | .foregroundColor(Color.white) 132 | Text(course.subtitle) 133 | .foregroundColor(Color.white.opacity(0.7)) 134 | } 135 | Spacer() 136 | 137 | ZStack { 138 | Image(uiImage: course.logo) 139 | .opacity(show ? 0 : 1) 140 | 141 | VStack { 142 | Image(systemName: "xmark") 143 | .font(.system(size: 16, weight: .medium)) 144 | .foregroundColor(.white) 145 | 146 | } 147 | .frame(width: 36, height: 36) 148 | .background(Color.black) 149 | .clipShape(Circle()) 150 | .opacity(show ? 1 : 0) 151 | } 152 | } 153 | Spacer() 154 | Image(uiImage: course.image) 155 | .resizable() 156 | .aspectRatio(contentMode: .fit) 157 | .frame(maxWidth: .infinity) 158 | .frame(height: 140, alignment: .top) 159 | 160 | 161 | } 162 | .padding(show ? 30 : 20) 163 | .padding(.top, show ? 30 : 0) 164 | // .frame(width: show ? screen.width : screen.width - 60 , height: show ? screen.height : 280) 165 | .frame(maxWidth: show ? .infinity : screen.width - 60 , maxHeight: show ? 330 : 280) 166 | .background(Color(course.color)) 167 | .clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous)) 168 | .shadow(color: Color(course.color).opacity(0.3), radius: 20, x: 0, y: 20) 169 | .animation(.spring(response: 0.5, dampingFraction: 0.7, blendDuration: 0)) 170 | .gesture( 171 | show ? 172 | DragGesture() 173 | .onChanged{ 174 | value in 175 | // 保证手势拖动值小于 200,否则结束代码;执行self.activeView = value.translation, 让值保持为translation 176 | guard value.translation.height < 100 else{ return } 177 | 178 | // 保证只能向下拖动 179 | guard value.translation.height > 0 else{ return } 180 | self.activeView = value.translation 181 | // if value.translation.height < 200 { 182 | // self.activeView = value.translation 183 | // } 184 | } 185 | .onEnded{ 186 | value in 187 | if self.activeView.height > 50 { 188 | self.show = false 189 | self.active = false 190 | self.activeIndex = -1 191 | } 192 | self.activeView = .zero 193 | } 194 | : nil //show时开启手势,否则无 195 | ) 196 | .onTapGesture { 197 | self.show.toggle() 198 | self.active.toggle() 199 | 200 | // 获取当前活动状态的卡片索引 201 | if self.show { 202 | self.activeIndex = self.index 203 | } 204 | else{ 205 | self.activeIndex = -1 206 | } 207 | } 208 | } 209 | .frame(height: show ? screen.height : 280) 210 | .scaleEffect(1 - self.activeView.height / 1000 ) 211 | .rotation3DEffect(Angle(degrees: Double(self.activeView.height / 10)), axis: (x: 0, y: 10, z: 0)) 212 | .hueRotation(Angle(degrees: Double(self.activeView.height))) 213 | .edgesIgnoringSafeArea(.all) 214 | .gesture( 215 | show ? 216 | DragGesture() 217 | .onChanged{ 218 | value in 219 | guard value.translation.height < 100 else{ return } 220 | 221 | // 保证只能向下拖动 222 | guard value.translation.height > 0 else{ return } 223 | self.activeView = value.translation 224 | 225 | } 226 | .onEnded{ 227 | value in 228 | if self.activeView.height > 50 { 229 | self.show = false 230 | self.active = false 231 | self.activeIndex = -1 232 | } 233 | self.activeView = .zero 234 | } 235 | : nil //show时开启手势,否则无 236 | ) 237 | .animation(.spring(response: 0.5, dampingFraction: 0.8, blendDuration: 0)) 238 | 239 | } 240 | } 241 | 242 | struct Course: Identifiable { 243 | var id = UUID() 244 | var title: String 245 | var subtitle: String 246 | var image: UIImage 247 | var logo: UIImage 248 | var color: UIColor 249 | var show: Bool //每张卡的状态 250 | } 251 | 252 | var courseData = [ 253 | Course(title: "Prototype Designs in SwiftUI", subtitle: "18 section", image: #imageLiteral(resourceName: "Card4"), logo: #imageLiteral(resourceName: "Logo1"), color: #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1) 254 | , show: false), 255 | Course(title: "SwiftUI Advanced", subtitle: "20 section", image: #imageLiteral(resourceName: "Card5"), logo: #imageLiteral(resourceName: "Logo1"), color: #colorLiteral(red: 0.8549019694, green: 0.250980407, blue: 0.4784313738, alpha: 1) 256 | , show: false), 257 | Course(title: "UI Design for Developer", subtitle: "20 section", image: #imageLiteral(resourceName: "Card2"), logo: #imageLiteral(resourceName: "Logo2"), color: #colorLiteral(red: 0.2588235438, green: 0.7568627596, blue: 0.9686274529, alpha: 1) 258 | , show: false) 259 | ] 260 | 261 | -------------------------------------------------------------------------------- /MyNotes/TestPages/LaunchTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchTest.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/22. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct LaunchTest: View { 12 | var body: some View { 13 | Image("LaunchImage") 14 | } 15 | } 16 | 17 | struct LaunchTest_Previews: PreviewProvider { 18 | static var previews: some View { 19 | LaunchTest() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MyNotes/TestPages/NotesListView_old.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotesList.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/20. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | let screen = UIScreen.main.bounds //以后可以调用视图的尺寸信息,不用像素值 12 | 13 | struct NotesListView_old: View { 14 | @State var notes = NotesData // 用的是实际的数据 15 | @State var active = false 16 | @State var activeIndex = -1 17 | @State var activeView = CGSize.zero 18 | 19 | @State var tmpContent = "ContentContentContentContentContentContentContentContentContentContentContent" 20 | 21 | @State var addNote = false 22 | 23 | //借助控制器获取数据库 24 | @ObservedObject var noteItemController = NoteItemController() 25 | 26 | var body: some View { 27 | ZStack { 28 | Color.black.opacity(Double(self.activeView.height / 500)) 29 | .animation(.linear) 30 | .edgesIgnoringSafeArea(.all) 31 | 32 | ScrollView { 33 | VStack(spacing: 20) { 34 | HStack { 35 | Text("Notes").font(.largeTitle).bold() 36 | Spacer() 37 | 38 | Button(action:{self.addNote.toggle()}) { 39 | Image(systemName: "square.and.pencil") 40 | .renderingMode(.original) 41 | .font(.system(size: 25, weight: .medium)) 42 | .frame(width:45, height: 45) 43 | .background(Color.white) 44 | .clipShape(Circle()) 45 | .shadow(color: Color.black.opacity(0.1), radius: 1, x: 0, y: 1) 46 | } 47 | .sheet(isPresented: $addNote, content:{NoteAddView(noteItemController: self.noteItemController)}) 48 | }.blur(radius: active ? 30 : 0)//卡片激活时,标题模糊 49 | .padding(.top,30) 50 | .padding(.leading,30) 51 | .padding(.trailing,30) 52 | .shadow(color: Color.black.opacity(0.2), radius: 5, x: 5, y: 4) 53 | 54 | // 使用了数组索引 55 | ForEach(notes.indices, id: \.self) { 56 | index in 57 | GeometryReader { 58 | gemotry in 59 | NoteView( 60 | show: self.$notes[index].show, 61 | note: self.notes[index], 62 | active: self.$active, 63 | index: index, 64 | activeIndex: self.$activeIndex, 65 | activeView: self.$activeView, 66 | text: self.$tmpContent) //在GeometrReader中,添加self 67 | .offset(y: self.notes[index].show ? -gemotry.frame(in: .global).minY : 0) //如果show,就移动 -gemotry.xxx的距离,抵消当前gemotry.xx.minY 68 | .opacity(self.activeIndex != index && self.active ? 0 : 1) 69 | .scaleEffect(self.activeIndex != index && self.active ? 0.5 : 1) 70 | .offset(x: self.activeIndex != index && self.active ? screen.width : 0) 71 | } 72 | .frame(height: 180) 73 | .frame(maxWidth: self.notes[index].show ? .infinity : screen.width - 60) 74 | .zIndex(self.notes[index].show ? 1 : 0) //show时为z轴索引为1,在0的上面 75 | } 76 | } 77 | .frame(width: screen.width) //ScrollView的宽度 78 | .animation(.spring(response: 0.5, dampingFraction: 0.6, blendDuration: 0)) 79 | // 卡片激活时,隐藏状态栏 80 | .statusBar(hidden: active ? true : false) 81 | .animation(.linear) 82 | } 83 | } 84 | } 85 | } 86 | 87 | 88 | struct NotesListView_old_Previews: PreviewProvider { 89 | static var previews: some View { 90 | NotesListView_old() 91 | } 92 | } 93 | 94 | 95 | struct NoteView: View { 96 | @Binding var show: Bool 97 | var note: Note 98 | 99 | @Binding var active: Bool // 状态栏显示与否的绑定 100 | 101 | var index: Int 102 | 103 | @Binding var activeIndex: Int 104 | 105 | // 卡片展开时的手势拖动 106 | @Binding var activeView: CGSize 107 | @State var showDetail = false 108 | 109 | @Binding var text: String 110 | 111 | var body: some View { 112 | ZStack(alignment: .top) { 113 | VStack(alignment: .leading, spacing: 10.0) { 114 | HStack{ 115 | Text("Content") 116 | .font(.title).bold() 117 | Spacer() 118 | Button(action:{self.showDetail.toggle()}) { 119 | Image(systemName: "pencil.and.ellipsis.rectangle") 120 | .renderingMode(.original) 121 | .font(.system(size: 16, weight: .medium)) 122 | .frame(width:36, height: 36) 123 | .background(Color.white) 124 | .clipShape(Circle()) 125 | .shadow(color: Color.black.opacity(0.1), radius: 1, x: 0, y: 1) 126 | } 127 | 128 | } 129 | HStack { 130 | Text(text) 131 | Spacer() 132 | } 133 | 134 | } 135 | .padding(30) 136 | .offset(y : show ? 240 : 0) 137 | //不show的时候文本藏在上面的VStack下 138 | .frame(maxWidth: show ? .infinity : screen.width - 60, maxHeight: show ? .infinity : 200, alignment: .top) 139 | .background(Color.white) 140 | .clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous)) 141 | .shadow(color: Color.black.opacity(0.2), radius: 20, x: 0, y: 20) 142 | .opacity(show ? 1 : 0) 143 | 144 | 145 | VStack { 146 | HStack(alignment: .top) { 147 | VStack(alignment: .leading, spacing: 8.0) { 148 | Text(note.title) 149 | .font(.system(size: 24, weight: .bold)) 150 | .foregroundColor(Color.white) 151 | Text(note.subtitle) 152 | .foregroundColor(Color.white.opacity(0.7)) 153 | 154 | } 155 | Spacer() 156 | 157 | ZStack { 158 | VStack { 159 | Image(systemName: "xmark") 160 | .font(.system(size: 16, weight: .medium)) 161 | .foregroundColor(.white) 162 | } 163 | .frame(width: 36, height: 36) 164 | .background(Color.black) 165 | .clipShape(Circle()) 166 | .opacity(show ? 1 : 0) 167 | } 168 | } 169 | Spacer() 170 | } 171 | .padding(show ? 30 : 20) 172 | .padding(.top, show ? 30 : 0) 173 | .frame(maxWidth: show ? .infinity : screen.width - 60 , maxHeight: show ? 240 : 180) 174 | .background(Color(note.color)) 175 | .clipShape(RoundedRectangle(cornerRadius: show ? 10 :30, style: .continuous)) 176 | .shadow(color: Color(note.color).opacity(0.3), radius: 20, x: 0, y: 20) 177 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) 178 | .gesture( 179 | show ? 180 | DragGesture() 181 | .onChanged{ 182 | value in 183 | // 保证手势拖动值小于 200,否则结束代码;执行self.activeView = value.translation, 让值保持为translation 184 | guard value.translation.height < 100 else{ return } 185 | 186 | // 保证只能向下拖动 187 | guard value.translation.height > 0 else{ return } 188 | self.activeView = value.translation 189 | } 190 | .onEnded{ 191 | value in 192 | if self.activeView.height > 50 { 193 | self.show = false 194 | self.active = false 195 | self.activeIndex = -1 196 | } 197 | self.activeView = .zero 198 | } 199 | : nil //show时开启手势,否则无 200 | ) 201 | .onTapGesture { 202 | self.show.toggle() 203 | self.active.toggle() 204 | 205 | // 获取当前活动状态的卡片索引 206 | if self.show { 207 | self.activeIndex = self.index 208 | } 209 | else{ 210 | self.activeIndex = -1 211 | } 212 | } 213 | } 214 | .frame(height: show ? screen.height : 280) 215 | .scaleEffect(1 - self.activeView.height / 1000 ) 216 | .rotation3DEffect(Angle(degrees: Double(self.activeView.height / 10)), axis: (x: 0, y: 10, z: 0)) 217 | .hueRotation(Angle(degrees: Double(self.activeView.height))) 218 | .edgesIgnoringSafeArea(.all) 219 | .gesture( 220 | show ? 221 | DragGesture() 222 | .onChanged{ 223 | value in 224 | guard value.translation.height < 100 else{ return } 225 | // 保证只能向下拖动 226 | guard value.translation.height > 0 else{ return } 227 | self.activeView = value.translation 228 | 229 | } 230 | .onEnded{ 231 | value in 232 | if self.activeView.height > 50 { 233 | self.show = false 234 | self.active = false 235 | self.activeIndex = -1 236 | } 237 | self.activeView = .zero 238 | } 239 | : nil //show时开启手势,否则无 240 | ) 241 | .animation(.spring(response: 0.5, dampingFraction: 0.9, blendDuration: 0)) 242 | } 243 | } 244 | 245 | -------------------------------------------------------------------------------- /MyNotes/TestPages/NotesStore.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotesStore.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/21. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import Combine 11 | 12 | class NotesStore: ObservableObject{ 13 | @Published var notes: [tmpNote] = tmpNotesData 14 | } 15 | 16 | 17 | 18 | //数据模型(结构体) 19 | struct tmpNote: Identifiable { 20 | var id = UUID() 21 | var image:String 22 | var title:String 23 | var subtitle:String 24 | var content:String 25 | var date:Date 26 | } 27 | 28 | let tmpNotesData = [tmpNote(image: "Card1", title: "SwiftUI Advanced", subtitle: "subtitle1",content: "Take your SwiftUI app to the App Store with advanced techniques like API data, packages and CMS.", date: Date()), 29 | tmpNote(image: "Card2", title: "Note 3", subtitle: "subtitle2",content: "Design and animate a high converting landing page with advanced interactions, payments and CMS.", date: Date()), 30 | tmpNote(image: "Card1", title: "Note 3", subtitle: "subtitle3",content: "Quickly prototype advanced animations and interactions for mobile and Web.", date: Date())] 31 | 32 | 33 | struct Note: Identifiable { 34 | var id = UUID() 35 | var title: String 36 | var subtitle: String 37 | var content: String 38 | var color: UIColor 39 | var show: Bool //每张卡的状态 40 | } 41 | 42 | var NotesData = [ 43 | Note(title: "Note 1", subtitle: "My note 1", content: "This is the content of note1", color: #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1), show: false)] 44 | //, 45 | // Note(title: "Note 2", subtitle: "My note 2", content: "This is the content of note2", color: #colorLiteral(red: 0.8549019694, green: 0.250980407, blue: 0.4784313738, alpha: 1), show: false), 46 | // Note(title: "Note 3", subtitle: "My note 3", content: "This is the content of note1", color: #colorLiteral(red: 0.2588235438, green: 0.7568627596, blue: 0.9686274529, alpha: 1), show: false), 47 | // Note(title: "Note 3", subtitle: "My note 4", content: "This is the content of note1", color: #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1), show: false), 48 | // Note(title: "Note 3", subtitle: "My note 5", content: "This is the content of note1", color: #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1), show: false)] 49 | -------------------------------------------------------------------------------- /MyNotes/Timer/TimerController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimerController.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/28. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SwiftUI 11 | 12 | func isNewDay() -> Bool{ 13 | var timeFormatter: String { 14 | //获取当日的年月日 15 | let dateFormatter = DateFormatter() 16 | dateFormatter.dateFormat = "yy-MM-dd" 17 | let dateString = dateFormatter.string(from: Date()) 18 | 19 | return dateString 20 | } 21 | 22 | 23 | let lastLoginDate = UserDefaults.standard.string(forKey: "lastLoginDate") 24 | UserDefaults.standard.set(timeFormatter, forKey: "lastLoginDate") 25 | 26 | if lastLoginDate == timeFormatter { 27 | print(lastLoginDate!) 28 | return false 29 | }else{ 30 | return true 31 | } 32 | 33 | } 34 | 35 | 36 | class TimerController: ObservableObject { 37 | 38 | @Published var timerMode: TimerMode = .initial 39 | @Published var secondsLeft = UserDefaults.standard.integer(forKey: "timerLength") 40 | 41 | @State var showDoneAlert = false 42 | 43 | 44 | var currentLength = 0 45 | var timer = Timer() 46 | 47 | var timeCount = UserDefaults.standard.integer(forKey: "timeCount_test") 48 | var dailyTimeCount = UserDefaults.standard.integer(forKey: "dailyTimeCount") 49 | 50 | 51 | 52 | func start() { 53 | timerMode = .running 54 | timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { timer in 55 | if self.secondsLeft == 1 { 56 | timer.invalidate() 57 | self.done() 58 | } 59 | self.secondsLeft -= 1 60 | }) 61 | } 62 | 63 | func reset() { 64 | self.timerMode = .initial 65 | self.secondsLeft = UserDefaults.standard.integer(forKey: "timerLength") 66 | timer.invalidate() 67 | } 68 | 69 | func pause() { 70 | self.timerMode = .paused 71 | timer.invalidate() 72 | } 73 | 74 | func done(){ 75 | self.timerMode = .done 76 | self.dailyTimeCount += self.currentLength 77 | UserDefaults.standard.set(self.dailyTimeCount, forKey: "dailyTimeCount") 78 | self.dailyTimeCount = UserDefaults.standard.integer(forKey: "dailyTimeCount") 79 | 80 | self.timeCount += self.currentLength 81 | UserDefaults.standard.set(self.timeCount, forKey: "timeCount_test") 82 | self.timeCount = UserDefaults.standard.integer(forKey: "timeCount_test") 83 | 84 | 85 | 86 | //print(self.timeCount) 87 | } 88 | 89 | func setTimerLength(minutes: Int) { 90 | let defaults = UserDefaults.standard 91 | defaults.set(minutes, forKey: "timerLength") 92 | secondsLeft = minutes 93 | currentLength = minutes 94 | } 95 | 96 | } 97 | 98 | 99 | enum TimerMode { 100 | case running 101 | case paused 102 | case initial 103 | case done 104 | } 105 | 106 | func secondsToMinutesAndSeconds (seconds : Int) -> String { 107 | 108 | let minutes = "\((seconds % 3600) / 60)" 109 | let seconds = "\((seconds % 3600) % 60)" 110 | let minuteStamp = minutes.count > 1 ? minutes : "0" + minutes 111 | let secondStamp = seconds.count > 1 ? seconds : "0" + seconds 112 | 113 | return "\(minuteStamp):\(secondStamp)" 114 | } 115 | -------------------------------------------------------------------------------- /MyNotes/Timer/TimerHomeView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimerHomeView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/28. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import UIKit 11 | 12 | 13 | 14 | struct TimerHomeView: View { 15 | 16 | init(){ 17 | UIApplication.shared.isIdleTimerDisabled = true 18 | } 19 | 20 | @ObservedObject var timerController = timerControllerGlobal 21 | 22 | @State var selectedPickerIndex = 0 23 | 24 | let availableMinutes = [1,5,10,15,20,25,30,35,40,45,50,55,60] 25 | 26 | var timeCount = 0 27 | @State var showDoneAlert = false 28 | @State var runningTimer = false 29 | var currentBrightness = UIScreen.main.brightness 30 | 31 | let generator = UINotificationFeedbackGenerator() 32 | 33 | 34 | var body: some View { 35 | VStack { 36 | VStack (spacing:40){ 37 | VStack { 38 | Text("Focus Timer") 39 | .font(.system(size: 40)) 40 | .padding(.top, 20) 41 | .foregroundColor(runningTimer ? Color(.white):Color("TextColor")) 42 | 43 | // Text("今天已经专注了\(timerController.dailyTimeCount / 60)分钟") 44 | // .font(.system(size: 20)) 45 | // .foregroundColor(runningTimer ? Color(.white):Color(.black)) 46 | } 47 | 48 | // 49 | Text(secondsToMinutesAndSeconds(seconds: timerController.secondsLeft)) 50 | .font(.system(size: 50)) 51 | .padding(.top, 10) 52 | .foregroundColor(runningTimer ? Color(.white):Color("TextColor")) 53 | .animation(.none) 54 | 55 | if timerController.timerMode != .done{ 56 | Image(systemName: timerController.timerMode == .running ? "pause.circle.fill" : "play.circle.fill") 57 | .resizable() 58 | .aspectRatio(contentMode: .fill) 59 | .frame(width: 150, height: 150) 60 | .foregroundColor(runningTimer ? Color(.white):Color(.orange)) 61 | .clipShape(Circle()) 62 | .onTapGesture(perform: { 63 | self.runningTimer.toggle() 64 | self.generator.notificationOccurred(.success) 65 | UIScreen.main.brightness = self.runningTimer ? CGFloat(0.4):self.currentBrightness 66 | if self.timerController.timerMode == .initial { 67 | self.timerController.setTimerLength(minutes: self.availableMinutes[self.selectedPickerIndex]*60) 68 | } 69 | self.timerController.timerMode == .running ? self.timerController.pause() : self.timerController.start() 70 | }) 71 | }else{ 72 | Image(systemName: "hand.thumbsup" ) 73 | .resizable() 74 | .aspectRatio(contentMode: .fit) 75 | .scaleEffect(0.7) 76 | .frame(width: 150, height: 150) 77 | .foregroundColor(.white) 78 | .background(Color(.orange)) 79 | .clipShape(Circle()) 80 | .onTapGesture(perform: { 81 | self.timerController.reset() 82 | self.showDoneAlert.toggle() 83 | self.runningTimer.toggle() 84 | }) 85 | } 86 | if timerController.timerMode == .paused { 87 | Image(systemName: "gobackward") 88 | .resizable() 89 | .aspectRatio(contentMode: .fit) 90 | .frame(width: 50, height: 50) 91 | .padding(.top, 40) 92 | .foregroundColor(Color("TextColor")) 93 | .onTapGesture(perform: { 94 | self.timerController.reset() 95 | }) 96 | } 97 | if timerController.timerMode == .initial { 98 | Picker(selection: $selectedPickerIndex, label: Text("How Long?")) { 99 | ForEach(0 ..< availableMinutes.count) { 100 | Text("\(self.availableMinutes[$0]) min") 101 | } 102 | } 103 | .labelsHidden() 104 | .offset(x: 0, y: -60) 105 | } 106 | 107 | if timerController.timerMode == .running { 108 | Text("Keep Doing Your ToDos") 109 | .font(.system(size: 30)) 110 | .padding(.top, 20) 111 | .foregroundColor(runningTimer ? Color(.white):Color("TextColor")) 112 | } 113 | 114 | 115 | Spacer() 116 | } 117 | .alert(isPresented: $showDoneAlert) { 118 | Alert(title: Text("Good job!"), message: Text("Focused \(timerController.dailyTimeCount / 60) min today"), dismissButton: .default(Text("OK!")))} 119 | } 120 | .padding(.top,40) 121 | .frame(maxWidth: .infinity) 122 | .background(runningTimer ? Color(.systemGreen):Color(.systemGray5)) 123 | .edgesIgnoringSafeArea(.all) 124 | .animation(.timingCurve(0.7, 1, 0.3, 1, duration: 1)) 125 | } 126 | 127 | } 128 | 129 | 130 | var timerControllerGlobal = TimerController() 131 | 132 | 133 | 134 | struct TimerHomeView_Previews: PreviewProvider { 135 | static var previews: some View { 136 | TimerHomeView() 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /MyNotes/ToDos/ToDoRowView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToDoRowView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/27. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ToDoRowView: View { 12 | 13 | @ObservedObject var toDoItemController: ToDoItemController 14 | @ObservedObject var toDoItem: ToDoItem 15 | 16 | 17 | @State var done:Bool = false 18 | @Binding var showDone:Bool 19 | 20 | var body: some View { 21 | ZStack { 22 | VStack { 23 | VStack(alignment: .leading) { 24 | HStack { 25 | HStack(spacing:0){ 26 | Button(action:{ 27 | self.done.toggle() 28 | self.toDoItemController.updateToDoItem(ToDoItemInstance: self.toDoItem, done: self.done) 29 | print(self.toDoItem) 30 | if self.done{ 31 | self.showDone = true 32 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1.5) { 33 | self.showDone = false 34 | } 35 | } 36 | }){ 37 | Image(systemName: done ? "checkmark.square.fill":"square") 38 | .resizable() 39 | .frame(width: 24, height: 24) 40 | .foregroundColor(done ? Color(.systemIndigo): Color(.systemIndigo)) 41 | }.padding(.trailing,15) 42 | 43 | 44 | Text(toDoItem.content ?? "There is no content") 45 | .font(.system(size: 18)) 46 | .foregroundColor(done ? Color(.systemGray2): Color("TextColor")) 47 | .strikethrough(done ? true:false, color: Color.black) 48 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) 49 | 50 | Spacer() 51 | Text(done ? "done" : countInterval(date: toDoItem.createdAt ?? Date())) 52 | .font(.system(size: 13)) 53 | .foregroundColor(done ? Color(.systemGray2): Color("TextColor")) 54 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) 55 | 56 | } 57 | .padding(10) 58 | .frame(minHeight:50) 59 | .background(self.done ? Color("RowDoneColor"):Color("RowAnyColor")) 60 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 61 | .shadow(color: Color("ShadowColor"), radius: 2) 62 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) 63 | 64 | } 65 | } 66 | } 67 | }} 68 | 69 | func countInterval(date:Date) -> String { 70 | let day = (date.timeIntervalSinceNow) / 86400 71 | var result:String 72 | let hour:Double 73 | 74 | if Int(day) == 0{ 75 | hour = (date.timeIntervalSinceNow) / 3600 76 | if Int(hour) == 0{ 77 | result = "Just" 78 | } 79 | else{ 80 | result = "\(-Int(hour)) hours ago"} 81 | }else{ 82 | result = "\(-Int(day)) days ago" 83 | } 84 | 85 | return result 86 | } 87 | 88 | } 89 | 90 | struct ToDoRowView_Previews: PreviewProvider { 91 | static var previews: some View { 92 | Group { 93 | ToDoRowView(toDoItemController: ToDoItemController(), toDoItem: ToDoItem(createdAt: Date(), content: "content"), showDone: .constant(false)) 94 | .environment(\.colorScheme, .light) 95 | 96 | ToDoRowView(toDoItemController: ToDoItemController(), toDoItem: ToDoItem(createdAt: Date(), content: "content"), showDone: .constant(false)) 97 | .environment(\.colorScheme, .dark) 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /MyNotes/ToDos/ToDosListView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToDosListView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/27. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import UIKit 11 | 12 | struct ToDosListView: View { 13 | 14 | let generator = UINotificationFeedbackGenerator() 15 | 16 | init() { 17 | UITableView.appearance().tableFooterView = UIView() 18 | UITableView.appearance().separatorStyle = .none 19 | } 20 | 21 | @ObservedObject var toDoItemController = toDoItemControllerGLobal 22 | @Environment(\.presentationMode) var presentationMode 23 | 24 | @State private var content = "" 25 | @State private var emptyAlert = false 26 | @State var showUndoneOnly = UserDefaults.standard.bool(forKey: "showUndoneOnly") 27 | @State var showSearch = false 28 | @State var showDone = false 29 | 30 | var body: some View { 31 | ZStack { 32 | NavigationView{ 33 | List(){ 34 | Section(header: Text("What to do?").font(.system(size: 15)).foregroundColor(Color(.systemGray))){ 35 | HStack{ 36 | Button(action:{ 37 | if !self.content.isEmpty{ 38 | self.toDoItemController.createToDoItem(content: self.content) 39 | self.generator.notificationOccurred(.success) 40 | self.content = "" 41 | self.presentationMode.wrappedValue.dismiss() 42 | }else{ 43 | self.generator.notificationOccurred(.warning) 44 | self.emptyAlert = true 45 | } 46 | }){ 47 | Image(systemName: "plus.app") 48 | .foregroundColor(Color(.systemIndigo)) 49 | .font(.largeTitle) 50 | .padding(.leading,5) 51 | } 52 | TextField("Thing", text: ($content)) 53 | .padding(10) 54 | .background(Color(.systemGray6)) 55 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 56 | .shadow(color: Color("ShadowColor"), radius: 2) 57 | }.padding(.vertical,10) 58 | .alert(isPresented: $emptyAlert) { 59 | Alert(title: Text("Warning"), message: Text("No content"), dismissButton: .default(Text("OK!")))} 60 | } 61 | Section(header:Text("Things to do.").font(.system(size: 15)).foregroundColor(Color(.systemGray))) 62 | { 63 | Toggle(isOn: $showUndoneOnly) { 64 | Text("Hide Done Things") 65 | .foregroundColor(.gray) 66 | }.toggleStyle(SwitchToggleStyle()) 67 | 68 | ForEach(toDoItemController.ToDoItemDataStore, id:\.id){todo in 69 | Group{ 70 | if !self.showUndoneOnly || todo.done == false{ 71 | Button(action: {}){ 72 | ToDoRowView(toDoItemController: self.toDoItemController, toDoItem: todo, done: todo.done,showDone: self.$showDone)} 73 | } 74 | } 75 | }.onDelete(perform: self.toDoItemController.deleteToDoItem) 76 | .padding(.vertical,-3) 77 | 78 | } 79 | 80 | Image("things") 81 | .resizable() 82 | .aspectRatio(contentMode: .fill) 83 | .padding() 84 | 85 | }.navigationBarTitle("ToDos") 86 | .navigationBarItems(trailing: 87 | Button(action:{self.showSearch = true}, 88 | label:{Image(systemName: "doc.text.magnifyingglass") 89 | .font(.largeTitle)}).sheet(isPresented: $showSearch, content: {ToDosSearchView()})) 90 | 91 | }.onAppear{self.toDoItemController.getAllToDoItems() 92 | UserDefaults.standard.set(self.showUndoneOnly,forKey: "showUndoneOnly") 93 | } 94 | 95 | if showDone { 96 | LottieToDoDoneView() 97 | } 98 | } 99 | } 100 | } 101 | 102 | struct ToDosListView_Previews: PreviewProvider { 103 | static var previews: some View { 104 | Group { 105 | ToDosListView() 106 | .environment(\.colorScheme, .light) 107 | 108 | ToDosListView() 109 | .environment(\.colorScheme, .dark) 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /MyNotes/ToDos/ToDosSearchResultRowView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToDosSearchResultRowView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/20. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ToDosSearchResultRowView: View { 12 | 13 | @ObservedObject var toDoItemController: ToDoItemController 14 | @ObservedObject var toDoItem: ToDoItem 15 | @Binding var input: String 16 | @State private var match = false 17 | @State var done:Bool = false 18 | 19 | var body: some View { 20 | VStack { 21 | VStack(alignment: .leading) { 22 | HStack { 23 | HStack(spacing:0){ 24 | Button(action:{ 25 | self.done.toggle() 26 | self.toDoItemController.updateToDoItem(ToDoItemInstance: self.toDoItem, done: self.done) 27 | print(self.toDoItem) 28 | }){ 29 | Image(systemName: done ? "checkmark.square.fill":"square") 30 | .resizable() 31 | .frame(width: 24, height: 24) 32 | .foregroundColor(done ? Color(.systemIndigo): Color(.systemIndigo)) 33 | }.padding(.trailing,15) 34 | 35 | 36 | Text(toDoItem.content ?? "There is no content") 37 | .font(.system(size: 18)) 38 | .foregroundColor(done ? Color(.systemGray2): Color("TextColor")) 39 | .strikethrough(done ? true:false, color: Color.black) 40 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) 41 | 42 | Spacer() 43 | Text(done ? "done" : countInterval(date: toDoItem.createdAt ?? Date())) 44 | .font(.system(size: 13)) 45 | .foregroundColor(done ? Color(.systemGray2): Color("TextColor")) 46 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) 47 | 48 | } 49 | .padding(10) 50 | .frame(minHeight:50) 51 | .background(self.done ? Color("RowDoneColor"):Color("RowAnyColor")) 52 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 53 | .shadow(color: Color("ShadowColor"), radius: 2) 54 | .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.8)) 55 | 56 | } 57 | } 58 | }.onAppear{ 59 | if self.toDoItem.content! == self.input{self.match = true} 60 | } 61 | 62 | } 63 | 64 | func countInterval(date:Date) -> String { 65 | let day = (date.timeIntervalSinceNow) / 86400 66 | var result:String 67 | let hour:Double 68 | 69 | if Int(day) == 0{ 70 | hour = (date.timeIntervalSinceNow) / 3600 71 | if Int(hour) == 0{ 72 | result = "Just" 73 | } 74 | else{ 75 | result = "\(-Int(hour))hours ago"} 76 | }else{ 77 | result = "\(-Int(day))days ago" 78 | } 79 | 80 | return result 81 | } 82 | } 83 | 84 | 85 | 86 | //struct ToDosSearchResultRowView_Previews: PreviewProvider { 87 | // static var previews: some View { 88 | // ToDosSearchResultRowView() 89 | // } 90 | //} 91 | -------------------------------------------------------------------------------- /MyNotes/ToDos/ToDosSearchView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToDosSearchView.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/4/20. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ToDosSearchView: View { 12 | let generator = UINotificationFeedbackGenerator() 13 | 14 | init() { 15 | UITableView.appearance().tableFooterView = UIView() 16 | UITableView.appearance().separatorStyle = .none 17 | } 18 | 19 | @ObservedObject var toDoItemController = toDoItemControllerGLobal 20 | //@Environment(\.presentationMode) var presentationMode 21 | 22 | @State private var emptyAlert = false 23 | // @State var showUndoneOnly = true 24 | 25 | @State private var match:String = "" 26 | @State private var searchText = "" 27 | @State private var searchPredicate: NSPredicate? = NSPredicate(format: "name contains[c] %@", "") 28 | @State var refresh: Bool = false 29 | 30 | 31 | var body: some View { 32 | NavigationView{ 33 | List{ 34 | Section(header: Text("Find ToDos.").font(.system(size: 15)).foregroundColor(Color(.systemGray))){ 35 | HStack{ 36 | Button(action:{ 37 | if !self.match.isEmpty{ 38 | self.toDoItemController.searchToDoItems(contain: self.match) 39 | self.generator.notificationOccurred(.success) 40 | self.match = "" 41 | //self.presentationMode.wrappedValue.dismiss() 42 | self.refresh.toggle() 43 | }else{ 44 | self.generator.notificationOccurred(.warning) 45 | self.emptyAlert = true 46 | } 47 | }){ 48 | Image(systemName: "magnifyingglass") 49 | .foregroundColor(Color(.systemIndigo)) 50 | .font(.largeTitle) 51 | .padding(.leading,5) 52 | } 53 | TextField("Search", text: ($match)) 54 | .padding(10) 55 | .background(Color(.systemGray6)) 56 | .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) 57 | .shadow(color: Color("ShadowColor"), radius: 2) 58 | }.padding(.vertical,10) 59 | .alert(isPresented: $emptyAlert) { 60 | Alert(title: Text("Warning"), message: Text("No content."), dismissButton: .default(Text("OK!")))} 61 | } 62 | Section(header:Text("Results.").font(.system(size: 15)).foregroundColor(Color(.systemGray))){ 63 | if refresh{ 64 | ForEach(toDoItemController.ToDoItemDataStore, id:\.id){ 65 | todo in 66 | ToDosSearchResultRowView(toDoItemController: self.toDoItemController, toDoItem: todo, input: self.$match, done: todo.done) 67 | }.onDelete(perform: self.toDoItemController.deleteToDoItem) 68 | .padding(.vertical,-3) 69 | } 70 | } 71 | 72 | Image("find") 73 | .resizable() 74 | .aspectRatio(contentMode: .fill) 75 | .padding() 76 | 77 | }.navigationBarTitle("Search Your ToDos") 78 | } 79 | //.onAppear{self.toDoItemController.getAllToDoItems()} 80 | } 81 | } 82 | 83 | struct ToDosSearchView_Previews: PreviewProvider { 84 | static var previews: some View { 85 | ToDosSearchView() 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /MyNotes/ToDosDataModel/ToDoItem+Convenience.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToDoItem+Convenience.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/27. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Foundation 11 | import CoreData 12 | 13 | extension ToDoItem { 14 | //取消如果不使用返回值的警告 15 | @discardableResult convenience init(id: UUID = UUID(), createdAt: Date, content: String, done: Bool = false, context: NSManagedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext) { 16 | 17 | self.init(context: context) 18 | 19 | self.id = id 20 | self.content = content 21 | self.createdAt = createdAt 22 | self.done = done 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /MyNotes/ToDosDataModel/ToDoItem+CoreDataClass.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToDoItem+CoreDataClass.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/27. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | // 9 | 10 | import Foundation 11 | import CoreData 12 | 13 | 14 | public class ToDoItem: NSManagedObject { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /MyNotes/ToDosDataModel/ToDoItem+CoreDataProperties.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToDoItem+CoreDataProperties.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/27. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | // 9 | 10 | import Foundation 11 | import CoreData 12 | 13 | 14 | extension ToDoItem { 15 | 16 | @nonobjc public class func fetchRequest() -> NSFetchRequest { 17 | return NSFetchRequest(entityName: "ToDoItem") 18 | } 19 | 20 | @NSManaged public var createdAt: Date? 21 | @NSManaged public var content: String? 22 | @NSManaged public var done: Bool 23 | @NSManaged public var id: UUID? 24 | 25 | } 26 | -------------------------------------------------------------------------------- /MyNotes/ToDosDataModel/ToDoItemController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToDoItemController.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/27. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | import Combine 12 | import UIKit 13 | 14 | class ToDoItemController: ObservableObject { 15 | 16 | // ToDoItem的数组 17 | @Published var ToDoItemDataStore: [ToDoItem] = [] 18 | 19 | //初始化时就把所有数据显先读到DataStore中 20 | init() { 21 | getAllToDoItems() 22 | } 23 | 24 | //读取 25 | func getAllToDoItems() { 26 | let fetchRequest: NSFetchRequest = ToDoItem.fetchRequest() 27 | let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 28 | do { 29 | //获取所有的ToDoItem 30 | ToDoItemDataStore = try moc.fetch(fetchRequest) 31 | 32 | } catch { 33 | NSLog("Error fetching tasks: \(error)") 34 | 35 | } 36 | } 37 | 38 | //保存 39 | func saveToPersistentStore() { 40 | let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 41 | do { 42 | try moc.save() 43 | getAllToDoItems() 44 | } catch { 45 | NSLog("Error saving managed object context: \(error)") 46 | } 47 | } 48 | 49 | //查询 50 | func searchToDoItems(contain:String) { 51 | let fetchRequest: NSFetchRequest = ToDoItem.fetchRequest() 52 | 53 | //ToDoItem.fetchRequest() 就是 NSFetchRequest(entityName: "ToDoItem") 54 | let pre = NSPredicate(format: "content contains[c] %@", "\(contain)") 55 | fetchRequest.predicate = pre 56 | let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 57 | 58 | do { 59 | ToDoItemDataStore = try moc.fetch(fetchRequest) 60 | 61 | } catch { 62 | NSLog("Error fetching tasks: \(error)") 63 | 64 | } 65 | } 66 | 67 | 68 | //创建,传参后直接保存 69 | func createToDoItem(content: String) { 70 | _ = ToDoItem(createdAt: Date(), content: content) 71 | saveToPersistentStore() 72 | } 73 | 74 | //创建,传参后直接保存 75 | func createToDoItem(content: String, done:Bool, createdAt: Date) { 76 | _ = ToDoItem(createdAt:createdAt, content: content, done: done) 77 | saveToPersistentStore() 78 | } 79 | 80 | //更新, 传入一个ToDoItem实例对象 81 | func updateToDoItem(ToDoItemInstance: ToDoItem, content: String) { 82 | ToDoItemInstance.content = content 83 | saveToPersistentStore() 84 | } 85 | 86 | //更新, 传入一个ToDoItem实例对象 87 | func updateToDoItem(ToDoItemInstance: ToDoItem, done:Bool) { 88 | ToDoItemInstance.done = done 89 | saveToPersistentStore() 90 | } 91 | 92 | //删除,直接删除对象 93 | func deleteToDoItem(ToDoItemInstance: ToDoItem) { 94 | let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 95 | moc.delete(ToDoItemInstance) 96 | saveToPersistentStore() 97 | } 98 | 99 | //删除,根据索引删除 100 | func deleteToDoItem(at indexSet: IndexSet) { 101 | guard let index = Array(indexSet).first else { return } 102 | //找到索引后定义对象 103 | let ToDoItem = self.ToDoItemDataStore[index] 104 | 105 | deleteToDoItem(ToDoItemInstance: ToDoItem) 106 | } 107 | 108 | //删除 109 | func deleteAllToDoItem() { 110 | for toDoItem in self.ToDoItemDataStore { 111 | deleteToDoItem(ToDoItemInstance: toDoItem) 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /MyNotes/multiLineTextField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // multiLineTextField.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/20. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import UIKit 11 | 12 | 13 | struct multiLineTextField : UIViewRepresentable { 14 | @Binding var text : String 15 | @State var editable: Bool = true 16 | 17 | func makeCoordinator() -> multiLineTextField.Coordinator { 18 | return multiLineTextField.Coordinator(parent1: self) 19 | } 20 | func makeUIView(context: UIViewRepresentableContext) -> UITextView{ 21 | let textview = UITextView() 22 | textview.font = .systemFont(ofSize: 18) 23 | textview.delegate = context.coordinator 24 | 25 | let toolBar = UIToolbar(frame: CGRect(x:0,y:0,width: textview.frame.size.width, height: 44)) 26 | let doneButton = UIBarButtonItem(title: "done", style: .done, target: self, action: #selector(textview.doneBUttonTapped(button:))) 27 | if editable{ 28 | toolBar.items = [doneButton] 29 | toolBar.setItems([doneButton], animated: true) 30 | textview.inputAccessoryView = toolBar 31 | textview.textColor = .gray 32 | } 33 | else{ 34 | textview.textColor = UIColor(named: "TextColor") 35 | } 36 | //textView透明背景 37 | //textview.backgroundColor = .clear 38 | 39 | textview.isUserInteractionEnabled = true 40 | textview.isEditable = editable 41 | textview.backgroundColor = UIColor(named: "RowAnyColor") 42 | 43 | return textview 44 | } 45 | 46 | func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext) { 47 | uiView.text = text 48 | } 49 | 50 | class Coordinator : NSObject,UITextViewDelegate{ 51 | var parent : multiLineTextField 52 | init(parent1 : multiLineTextField) { 53 | parent = parent1 54 | } 55 | 56 | func textViewDidBeginEditing(_ textView: UITextView) { 57 | 58 | //textView.text = "" 59 | textView.textColor = UIColor(named: "TextColor") 60 | } 61 | 62 | func textViewDidChange(_ textView: UITextView) { 63 | self.parent.text = textView.text 64 | } 65 | } 66 | } 67 | 68 | 69 | extension UITextView{ 70 | @objc func doneBUttonTapped(button:UIBarButtonItem) -> Void{ 71 | self.resignFirstResponder() 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /MyNotes/selectableText.swift: -------------------------------------------------------------------------------- 1 | // 2 | // selectableText.swift 3 | // MyNotes 4 | // 5 | // Created by YES on 2020/3/21. 6 | // Copyright © 2020 YES. All rights reserved. 7 | // 8 | import SwiftUI 9 | import UIKit 10 | 11 | 12 | 13 | /// This subclass is needed since we want to customize the cursor and the context menu 14 | class CustomUITextView: UITextView, UITextViewDelegate { 15 | 16 | /// Binding from the `CustomTextField` so changes of the text can be observed by `SwiftUI` 17 | fileprivate var _textBinding: Binding! 18 | 19 | /// If it is `true` the text field behaves normally. If `false` text cannot be modified only selected, copied and so on. 20 | fileprivate var _isEditable = true 21 | 22 | 23 | // change the cursor to have zero size 24 | override func caretRect(for position: UITextPosition) -> CGRect { 25 | return self._isEditable ? super.caretRect(for: position) : .zero 26 | } 27 | 28 | // override this method to customize the displayed items of 'UIMenuController' (the context menu when selecting text) 29 | override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool { 30 | 31 | // disable 'cut', 'delete', 'paste','_promptForReplace:' 32 | // if it is not editable 33 | if (!_isEditable) { 34 | switch action { 35 | case #selector(cut(_:)), 36 | #selector(delete(_:)), 37 | #selector(paste(_:)): 38 | return false 39 | default: 40 | // do not show 'Replace...' which can also replace text 41 | // Note: This selector is private and may change 42 | if (action == Selector("_promptForReplace:")) { 43 | return false 44 | } 45 | } 46 | } 47 | return super.canPerformAction(action, withSender: sender) 48 | } 49 | 50 | 51 | // === UITextViewDelegate methods 52 | 53 | func textFieldDidChangeSelection(_ textField: UITextView) { 54 | // update the text of the binding 55 | self._textBinding.wrappedValue = textField.text ?? "" 56 | } 57 | 58 | func textField(_ textField: UITextView, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 59 | // Allow changing the text depending on `self._isEditable` 60 | return self._isEditable 61 | } 62 | 63 | } 64 | 65 | struct CustomTextField: UIViewRepresentable { 66 | 67 | @Binding private var text: String 68 | private var isEditable: Bool 69 | 70 | init(text: Binding, isEditable: Bool = true) { 71 | self._text = text 72 | self.isEditable = isEditable 73 | } 74 | 75 | func makeUIView(context: UIViewRepresentableContext) -> CustomUITextView { 76 | let textField = CustomUITextView(frame: .zero) 77 | textField.delegate = textField 78 | textField.text = self.text 79 | textField.setContentHuggingPriority(.defaultHigh, for: .vertical) 80 | return textField 81 | } 82 | 83 | func updateUIView(_ uiView: CustomUITextView, context: UIViewRepresentableContext) { 84 | uiView.text = self.text 85 | uiView._textBinding = self.$text 86 | uiView._isEditable = self.isEditable 87 | } 88 | 89 | func isEditable(editable: Bool) -> CustomTextField { 90 | return CustomTextField(text: self.$text, isEditable: editable) 91 | } 92 | } 93 | 94 | struct selectableText: UIViewRepresentable { 95 | 96 | private var text: String 97 | private var selectable: Bool 98 | 99 | init(_ text: String, selectable: Bool = true) { 100 | self.text = text 101 | self.selectable = selectable 102 | } 103 | 104 | func makeUIView(context: Context) -> CustomUITextView { 105 | let textField = CustomUITextView(frame: .zero) 106 | textField.delegate = textField 107 | textField.text = self.text 108 | textField.setContentHuggingPriority(.defaultHigh, for: .vertical) 109 | textField.setContentHuggingPriority(.defaultHigh, for: .horizontal) 110 | return textField 111 | } 112 | 113 | func updateUIView(_ uiView: CustomUITextView, context: Context) { 114 | uiView.text = self.text 115 | uiView._textBinding = .constant(self.text) 116 | uiView._isEditable = false 117 | //uiView.isEnabled = self.selectable 118 | uiView.font = .systemFont(ofSize: 18) 119 | uiView.textAlignment = .left 120 | uiView.backgroundColor = .clear 121 | } 122 | 123 | func selectable(_ selectable: Bool) -> selectableText { 124 | return selectableText(self.text, selectable: selectable) 125 | } 126 | 127 | } 128 | 129 | 130 | struct TextTestView: View { 131 | 132 | @State private var selectableTag = true 133 | 134 | var body: some View { 135 | VStack { 136 | 137 | // Even though the text should be constant, it is not because the user can select and e.g. 'cut' the text 138 | TextField("", text: .constant("Test SwiftUI TextField")) 139 | .background(Color(red: 0.5, green: 0.5, blue: 1)) 140 | 141 | // This view behaves like the `selectableText` however the layout behaves like a `TextField` 142 | CustomTextField(text: .constant("Test `CustomTextField`")) 143 | .isEditable(editable: false) 144 | .background(Color(red: 0.5, green: 0.5, blue: 1)) 145 | 146 | // A non selectable normal `Text` 147 | Text("Test SwiftUI `Text`") 148 | .background(Color.red) 149 | 150 | // A selectable `text` where the selection ability can be changed by the button below 151 | selectableText("Test `selectableText` maybe selectable") 152 | .selectable(self.selectableTag) 153 | .background(Color.orange) 154 | 155 | Button(action: { 156 | self.selectableTag.toggle() 157 | }) { 158 | Text("`selectableText` can be selected: \(self.selectableTag.description)") 159 | } 160 | 161 | // A selectable `text` which cannot be changed 162 | HStack { 163 | selectableText("Test 'selectableText` always selectableTest `selectableText` always selectable") 164 | .frame(width: 200, height: 50) 165 | Spacer() 166 | } 167 | 168 | }.padding() 169 | } 170 | 171 | } 172 | 173 | struct Selectable_Previews: PreviewProvider { 174 | static var previews: some View { 175 | TextTestView() 176 | } 177 | } 178 | 179 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 2021.1 2 | 基于swiftUI1.0 编写,部分组件在swiftUI2.0下可能会出现位置偏移的小问题,仅作参考 3 | 4 | # NotesApp 5 | 完整的便签本app,支持待办事项、笔记本、专注时长等 6 | 7 | 完全由swiftUI编写,基于CoreData实现本地持久化存储 8 | 9 | ### 实现内容列表: 10 | 11 | * 待办事项 12 | * 笔记本 13 | * CoreData本地持久化存储 14 | * MinCloud登录注册(知晓云Baas) 15 | * MinCloud数据云同步(知晓云Baas) 16 | * 夜间模式 17 | * lottie动效 18 | * 专注计时 19 | 20 | ### App截图 21 | 22 |
23 | 24 | 25 | 26 |
27 | 28 |
29 | 30 | 31 | 32 |
33 | 34 |
35 | 36 | 37 | 38 |
39 | 40 | -------------------------------------------------------------------------------- /showPics/06BCD721F20815F9EC543A270617D2CD.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/showPics/06BCD721F20815F9EC543A270617D2CD.JPG -------------------------------------------------------------------------------- /showPics/4CBCB616F4FE4E2B11071F0708E01276.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/showPics/4CBCB616F4FE4E2B11071F0708E01276.JPG -------------------------------------------------------------------------------- /showPics/5B625FD91844FFFD8B3EE9EC65ECDFA9.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/showPics/5B625FD91844FFFD8B3EE9EC65ECDFA9.JPG -------------------------------------------------------------------------------- /showPics/69A4895D8F226B3086C5FB5FB35451DA.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/showPics/69A4895D8F226B3086C5FB5FB35451DA.JPG -------------------------------------------------------------------------------- /showPics/826E72E45F928DED4157610E79C75039.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/showPics/826E72E45F928DED4157610E79C75039.JPG -------------------------------------------------------------------------------- /showPics/866AF2BF6E8FF415C75D40CCDF9740BD.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/showPics/866AF2BF6E8FF415C75D40CCDF9740BD.JPG -------------------------------------------------------------------------------- /showPics/A17817B53082F53ED584960716FE6053.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/showPics/A17817B53082F53ED584960716FE6053.JPG -------------------------------------------------------------------------------- /showPics/ADA3D4E40B173FB681C7CB35AF397FCF.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/showPics/ADA3D4E40B173FB681C7CB35AF397FCF.JPG -------------------------------------------------------------------------------- /showPics/B601B5A0BA233CAC8161F48E986102EE.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/showPics/B601B5A0BA233CAC8161F48E986102EE.JPG -------------------------------------------------------------------------------- /showPics/BA9D268CD0E878BF5790F646B301DB97.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/showPics/BA9D268CD0E878BF5790F646B301DB97.JPG -------------------------------------------------------------------------------- /showPics/EDB36F7F0AA33E667D8EE9B1A22D9702.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dyeeee/NotesApp/b2de9eb953e78ce1d3cbacdbd68e2705f1e2dd89/showPics/EDB36F7F0AA33E667D8EE9B1A22D9702.JPG -------------------------------------------------------------------------------- /showPics/demo.md: -------------------------------------------------------------------------------- 1 | App pics here 2 | --------------------------------------------------------------------------------