├── Design └── LiveUseful.sketch ├── LICENSE ├── LiveUseful.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── Megabits.xcuserdatad │ │ ├── IDEFindNavigatorScopes.plist │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── Megabits.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── LiveUseful.xcscheme │ └── xcschememanagement.plist ├── LiveUseful ├── Import Action │ ├── ActionViewController.swift │ ├── Base.lproj │ │ └── MainInterface.storyboard │ ├── Import Action.entitlements │ ├── Info.plist │ ├── Media.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── iPhone-20@2x.png │ │ │ ├── iPhone-20@3x.png │ │ │ ├── iPhone-29@2x.png │ │ │ ├── iPhone-29@3x.png │ │ │ ├── iPhone-40@2x.png │ │ │ ├── iPhone-40@3x.png │ │ │ ├── iPhone-60@2x.png │ │ │ ├── iPhone-60@3x.png │ │ │ └── iTunesConnect.png │ │ ├── CancelImport.imageset │ │ │ ├── CancelImport.png │ │ │ ├── CancelImport@2x.png │ │ │ ├── CancelImport@3x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Finish.imageset │ │ │ ├── Contents.json │ │ │ ├── Finish.png │ │ │ ├── Finish@2x.png │ │ │ └── Finish@3x.png │ │ ├── ImportAsImage.imageset │ │ │ ├── Contents.json │ │ │ ├── ImportAsImage.png │ │ │ ├── ImportAsImage@2x.png │ │ │ └── ImportAsImage@3x.png │ │ └── ImportAsLink.imageset │ │ │ ├── Contents.json │ │ │ ├── ImportAsLink.png │ │ │ ├── ImportAsLink@2x.png │ │ │ └── ImportAsLink@3x.png │ ├── PublicType.swift │ ├── ja.lproj │ │ ├── InfoPlist.strings │ │ └── MainInterface.strings │ ├── zh-Hans.lproj │ │ ├── InfoPlist.strings │ │ └── MainInterface.strings │ └── zh-Hant.lproj │ │ ├── InfoPlist.strings │ │ └── MainInterface.strings ├── LiveUseful.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── Megabits.xcuserdatad │ │ │ ├── IDEFindNavigatorScopes.plist │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── Megabits.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── LiveUseful.xcscheme │ │ └── xcschememanagement.plist └── LiveUseful │ ├── AddImageViewController.swift │ ├── AddListViewController.swift │ ├── AddMultipleQRViewController.swift │ ├── AddQRDialogViewController.swift │ ├── AddQRViewController.swift │ ├── AddTextViewController.swift │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── Alert │ │ ├── Contents.json │ │ ├── Error.imageset │ │ │ ├── Contents.json │ │ │ ├── Error.png │ │ │ ├── Error@2x.png │ │ │ └── Error@3x.png │ │ └── Finish.imageset │ │ │ ├── Contents.json │ │ │ ├── Finish.png │ │ │ ├── Finish@2x.png │ │ │ └── Finish@3x.png │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── iPhone-20@2x.png │ │ ├── iPhone-20@3x.png │ │ ├── iPhone-29@2x.png │ │ ├── iPhone-29@3x.png │ │ ├── iPhone-40@2x.png │ │ ├── iPhone-40@3x.png │ │ ├── iPhone-60@2x.png │ │ ├── iPhone-60@3x.png │ │ └── iTunesConnect.png │ ├── Contents.json │ ├── Image │ │ ├── Blur.imageset │ │ │ ├── Blur.png │ │ │ ├── Blur@2x.png │ │ │ ├── Blur@3x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── FullScreen.imageset │ │ │ ├── Contents.json │ │ │ ├── FullScreen.png │ │ │ ├── FullScreen@2x.png │ │ │ └── FullScreen@3x.png │ │ ├── NoBlur.imageset │ │ │ ├── Contents.json │ │ │ ├── NoBlur.png │ │ │ ├── NoBlur@2x.png │ │ │ └── NoBlur@3x.png │ │ ├── OpenImage.imageset │ │ │ ├── Contents.json │ │ │ ├── OpenImage.png │ │ │ ├── OpenImage@2x.png │ │ │ └── OpenImage@3x.png │ │ ├── RectCorner.imageset │ │ │ ├── Contents.json │ │ │ ├── RectCorner.png │ │ │ ├── RectCorner@2x.png │ │ │ └── RectCorner@3x.png │ │ ├── RoundCorner.imageset │ │ │ ├── Contents.json │ │ │ ├── RoundCorner.png │ │ │ ├── RoundCorner@2x.png │ │ │ └── RoundCorner@3x.png │ │ └── Thumbnail.imageset │ │ │ ├── Contents.json │ │ │ ├── Thumbnail.png │ │ │ ├── Thumbnail@2x.png │ │ │ └── Thumbnail@3x.png │ ├── Main Button │ │ ├── Back.imageset │ │ │ ├── Back.png │ │ │ ├── Back@2x.png │ │ │ ├── Back@3x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Crop.imageset │ │ │ ├── Contents.json │ │ │ ├── Crop.png │ │ │ ├── Crop@2x.png │ │ │ └── Crop@3x.png │ │ ├── Help.imageset │ │ │ ├── Contents.json │ │ │ ├── Help.png │ │ │ ├── Help@2x.png │ │ │ └── Help@3x.png │ │ ├── Image.imageset │ │ │ ├── Contents.json │ │ │ ├── Image.png │ │ │ ├── Image@2x.png │ │ │ └── Image@3x.png │ │ ├── QR.imageset │ │ │ ├── Contents.json │ │ │ ├── QR.png │ │ │ ├── QR@2x.png │ │ │ └── QR@3x.png │ │ ├── Save.imageset │ │ │ ├── Contents.json │ │ │ ├── Save.png │ │ │ ├── Save@2x.png │ │ │ └── Save@3x.png │ │ ├── Text.imageset │ │ │ ├── Contents.json │ │ │ ├── Text.png │ │ │ ├── Text@2x.png │ │ │ └── Text@3x.png │ │ └── ToPhotos.imageset │ │ │ ├── Contents.json │ │ │ ├── ToPhotos.png │ │ │ ├── ToPhotos@2x.png │ │ │ └── ToPhotos@3x.png │ ├── Omake.imageset │ │ ├── Contents.json │ │ └── IMG_0999.jpeg │ ├── QR │ │ ├── CancelDialog.imageset │ │ │ ├── Cancel2.png │ │ │ ├── Cancel2@2x.png │ │ │ ├── Cancel2@3x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Multiple.imageset │ │ │ ├── Contents.json │ │ │ ├── Multiple.png │ │ │ ├── Multiple@2x.png │ │ │ └── Multiple@3x.png │ │ ├── OpenQRImage.imageset │ │ │ ├── Contents.json │ │ │ ├── OpenQRImage.png │ │ │ ├── OpenQRImage@2x.png │ │ │ └── OpenQRImage@3x.png │ │ ├── QRBackground.imageset │ │ │ ├── Contents.json │ │ │ ├── QRBackground.png │ │ │ ├── QRBackground@2x.png │ │ │ └── QRBackground@3x.png │ │ ├── Remove.imageset │ │ │ ├── Contents.json │ │ │ ├── Remove.png │ │ │ ├── Remove@2x.png │ │ │ └── Remove@3x.png │ │ ├── ShowBig.imageset │ │ │ ├── Contents.json │ │ │ ├── ShowBig.png │ │ │ ├── ShowBig@2x.png │ │ │ └── ShowBig@3x.png │ │ ├── ShowSmall.imageset │ │ │ ├── Contents.json │ │ │ ├── ShowSmall.png │ │ │ ├── ShowSmall@2x.png │ │ │ └── ShowSmall@3x.png │ │ ├── Single.imageset │ │ │ ├── Contents.json │ │ │ ├── Single.png │ │ │ ├── Single@2x.png │ │ │ └── Single@3x.png │ │ └── TransferQR.imageset │ │ │ ├── Contents.json │ │ │ ├── Transfer QR.png │ │ │ ├── Transfer QR@2x.png │ │ │ └── Transfer QR@3x.png │ ├── Start Page │ │ ├── Contents.json │ │ ├── Icon.imageset │ │ │ ├── Contents.json │ │ │ ├── Icon.png │ │ │ ├── Icon@2x.png │ │ │ └── Icon@3x.png │ │ ├── OpenPhoto.imageset │ │ │ ├── Contents.json │ │ │ ├── OpenPhoto.png │ │ │ ├── OpenPhoto@2x.png │ │ │ └── OpenPhoto@3x.png │ │ └── UseLastPhoto.imageset │ │ │ ├── Contents.json │ │ │ ├── UseLastPhoto.png │ │ │ ├── UseLastPhoto@2x.png │ │ │ └── UseLastPhoto@3x.png │ ├── Text │ │ ├── AddItem.imageset │ │ │ ├── AddItem.png │ │ │ ├── AddItem@2x.png │ │ │ ├── AddItem@3x.png │ │ │ └── Contents.json │ │ ├── AlignCenter.imageset │ │ │ ├── Align Center.png │ │ │ ├── Align Center@2x.png │ │ │ ├── Align Center@3x.png │ │ │ └── Contents.json │ │ ├── AlignJustified.imageset │ │ │ ├── Align Justified.png │ │ │ ├── Align Justified@2x.png │ │ │ ├── Align Justified@3x.png │ │ │ └── Contents.json │ │ ├── AlignLeft.imageset │ │ │ ├── Align Left.png │ │ │ ├── Align Left@2x.png │ │ │ ├── Align Left@3x.png │ │ │ └── Contents.json │ │ ├── AlignRight.imageset │ │ │ ├── Align Right.png │ │ │ ├── Align Right@2x.png │ │ │ ├── Align Right@3x.png │ │ │ └── Contents.json │ │ ├── BackgroundCard.imageset │ │ │ ├── BackgroundCard.png │ │ │ ├── BackgroundCard@2x.png │ │ │ ├── BackgroundCard@3x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── FontSize.imageset │ │ │ ├── Contents.json │ │ │ ├── FontSize.png │ │ │ ├── FontSize@2x.png │ │ │ └── FontSize@3x.png │ │ ├── ListMode.imageset │ │ │ ├── Contents.json │ │ │ ├── ListMode.png │ │ │ ├── ListMode@2x.png │ │ │ └── ListMode@3x.png │ │ └── TextMode.imageset │ │ │ ├── Contents.json │ │ │ ├── TextMode.png │ │ │ ├── TextMode@2x.png │ │ │ └── TextMode@3x.png │ ├── Top Bar │ │ ├── Cancel.imageset │ │ │ ├── Cancel.png │ │ │ ├── Cancel@2x.png │ │ │ ├── Cancel@3x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── OK.imageset │ │ │ ├── Contents.json │ │ │ ├── OK.png │ │ │ ├── OK@2x.png │ │ │ └── OK@3x.png │ └── Tutorials │ │ ├── Contents.json │ │ ├── NextPage.imageset │ │ ├── Contents.json │ │ ├── NextPage.png │ │ ├── NextPage@2x.png │ │ └── NextPage@3x.png │ │ ├── PrevPage.imageset │ │ ├── Contents.json │ │ ├── PrevPage.png │ │ ├── PrevPage@2x.png │ │ └── PrevPage@3x.png │ │ ├── Tutorial1.imageset │ │ ├── Contents.json │ │ └── t1.jpg │ │ ├── Tutorial2.imageset │ │ ├── Contents.json │ │ └── t2.jpg │ │ ├── Tutorial3.imageset │ │ ├── Contents.json │ │ └── t3.jpg │ │ └── Tutorial4.imageset │ │ ├── Contents.json │ │ └── t4.jpg │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── BuildViewController.swift │ ├── CropViewController.swift │ ├── EditViewController.swift │ ├── Extensions.swift │ ├── FileProcess │ ├── BuildLivePhoto.swift │ ├── JPEG.swift │ └── QuickTimeMov.swift │ ├── Info.plist │ ├── LightImageCropperClasses │ ├── LCropBorderView.swift │ ├── LImageCropOverlayView.swift │ ├── LImageCropView.swift │ ├── LImageCropViewController.swift │ ├── LImagePicker.swift │ └── LResizableCropOverlayView.swift │ ├── ListTableViewCell.swift │ ├── LiveUseful.entitlements │ ├── OmakeViewController.swift │ ├── QRView.swift │ ├── ScanQRViewController.swift │ ├── SeeItViewController.swift │ ├── StartViewController.swift │ ├── TutorialsViewController.swift │ ├── en.lproj │ └── Localizable.strings │ ├── ja.lproj │ ├── InfoPlist.strings │ ├── Localizable.strings │ └── Main.strings │ ├── zh-Hans.lproj │ ├── InfoPlist.strings │ ├── Localizable.strings │ └── Main.strings │ └── zh-Hant.lproj │ ├── InfoPlist.strings │ ├── Localizable.strings │ └── Main.strings ├── Preview.jpeg ├── README.md └── icon.png /Design/LiveUseful.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/Design/LiveUseful.sketch -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Megabits_mzq 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /LiveUseful.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LiveUseful.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LiveUseful.xcodeproj/project.xcworkspace/xcuserdata/Megabits.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LiveUseful.xcodeproj/project.xcworkspace/xcuserdata/Megabits.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful.xcodeproj/project.xcworkspace/xcuserdata/Megabits.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LiveUseful.xcodeproj/xcuserdata/Megabits.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /LiveUseful.xcodeproj/xcuserdata/Megabits.xcuserdatad/xcschemes/LiveUseful.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 69 | 70 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /LiveUseful.xcodeproj/xcuserdata/Megabits.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Generate Live Photo.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | LiveUseful.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | C026B5551F7FBE6500D462F3 21 | 22 | primary 23 | 24 | 25 | C0CCA3CD217CBA3D000D531F 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /LiveUseful/Import Action/Import Action.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.liveuseful 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /LiveUseful/Import Action/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Import to LiveUseful 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 2.26 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | NSExtensionActivationRule 28 | 29 | NSExtensionActivationSupportsImageWithMaxCount 30 | 1 31 | NSExtensionActivationSupportsText 32 | 33 | NSExtensionActivationSupportsWebURLWithMaxCount 34 | 1 35 | 36 | 37 | NSExtensionMainStoryboard 38 | MainInterface 39 | NSExtensionPointIdentifier 40 | com.apple.ui-services 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "iPhone-20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "iPhone-20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "iPhone-29@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "iPhone-29@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "iPhone-40@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "iPhone-40@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "iPhone-60@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "iPhone-60@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "idiom" : "ipad", 53 | "size" : "20x20", 54 | "scale" : "1x" 55 | }, 56 | { 57 | "idiom" : "ipad", 58 | "size" : "20x20", 59 | "scale" : "2x" 60 | }, 61 | { 62 | "idiom" : "ipad", 63 | "size" : "29x29", 64 | "scale" : "1x" 65 | }, 66 | { 67 | "idiom" : "ipad", 68 | "size" : "29x29", 69 | "scale" : "2x" 70 | }, 71 | { 72 | "idiom" : "ipad", 73 | "size" : "40x40", 74 | "scale" : "1x" 75 | }, 76 | { 77 | "idiom" : "ipad", 78 | "size" : "40x40", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "idiom" : "ipad", 83 | "size" : "76x76", 84 | "scale" : "1x" 85 | }, 86 | { 87 | "idiom" : "ipad", 88 | "size" : "76x76", 89 | "scale" : "2x" 90 | }, 91 | { 92 | "idiom" : "ipad", 93 | "size" : "83.5x83.5", 94 | "scale" : "2x" 95 | }, 96 | { 97 | "size" : "1024x1024", 98 | "idiom" : "ios-marketing", 99 | "filename" : "iTunesConnect.png", 100 | "scale" : "1x" 101 | } 102 | ], 103 | "info" : { 104 | "version" : 1, 105 | "author" : "xcode" 106 | } 107 | } -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-20@2x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-20@3x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-29@2x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-29@3x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-40@2x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-40@3x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-60@2x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iPhone-60@3x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iTunesConnect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/AppIcon.appiconset/iTunesConnect.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/CancelImport.imageset/CancelImport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/CancelImport.imageset/CancelImport.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/CancelImport.imageset/CancelImport@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/CancelImport.imageset/CancelImport@2x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/CancelImport.imageset/CancelImport@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/CancelImport.imageset/CancelImport@3x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/CancelImport.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "CancelImport.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "CancelImport@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "CancelImport@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/Finish.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Finish.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Finish@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Finish@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/Finish.imageset/Finish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/Finish.imageset/Finish.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/Finish.imageset/Finish@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/Finish.imageset/Finish@2x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/Finish.imageset/Finish@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/Finish.imageset/Finish@3x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/ImportAsImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ImportAsImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ImportAsImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ImportAsImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/ImportAsImage.imageset/ImportAsImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/ImportAsImage.imageset/ImportAsImage.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/ImportAsImage.imageset/ImportAsImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/ImportAsImage.imageset/ImportAsImage@2x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/ImportAsImage.imageset/ImportAsImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/ImportAsImage.imageset/ImportAsImage@3x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/ImportAsLink.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ImportAsLink.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ImportAsLink@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ImportAsLink@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/ImportAsLink.imageset/ImportAsLink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/ImportAsLink.imageset/ImportAsLink.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/ImportAsLink.imageset/ImportAsLink@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/ImportAsLink.imageset/ImportAsLink@2x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/Media.xcassets/ImportAsLink.imageset/ImportAsLink@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/Import Action/Media.xcassets/ImportAsLink.imageset/ImportAsLink@3x.png -------------------------------------------------------------------------------- /LiveUseful/Import Action/PublicType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PublicType.swift 3 | // Import Action 4 | // 5 | // Created by 孟金羽 on 2019/04/02. 6 | // Copyright © 2019 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | let appGroupName = "group.liveuseful" 12 | 13 | enum ImportKeys: String, CaseIterable { 14 | case Text = "import.text" 15 | case URL = "import.url" 16 | case Image = "import.image" 17 | } 18 | 19 | -------------------------------------------------------------------------------- /LiveUseful/Import Action/ja.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "マジックロック にインポート"; 3 | -------------------------------------------------------------------------------- /LiveUseful/Import Action/ja.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | /* Class = "UIButton"; normalTitle = "Import as image"; ObjectID = "0SP-zH-cBV"; */ 2 | "0SP-zH-cBV.normalTitle" = "画像をインポート"; 3 | 4 | /* Class = "UIButton"; normalTitle = "Cancel"; ObjectID = "TXw-bH-OGn"; */ 5 | "TXw-bH-OGn.normalTitle" = "取り消し"; 6 | 7 | /* Class = "UIButton"; normalTitle = "Import as link"; ObjectID = "zb2-Ws-1tk"; */ 8 | "zb2-Ws-1tk.normalTitle" = "QR コードをインポート"; 9 | -------------------------------------------------------------------------------- /LiveUseful/Import Action/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "导入到神奇锁屏"; 3 | -------------------------------------------------------------------------------- /LiveUseful/Import Action/zh-Hans.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | /* Class = "UIButton"; normalTitle = "Import as image"; ObjectID = "0SP-zH-cBV"; */ 2 | "0SP-zH-cBV.normalTitle" = "作为图片导入"; 3 | 4 | /* Class = "UIButton"; normalTitle = "Cancel"; ObjectID = "TXw-bH-OGn"; */ 5 | "TXw-bH-OGn.normalTitle" = "取消"; 6 | 7 | /* Class = "UIButton"; normalTitle = "Import as link"; ObjectID = "zb2-Ws-1tk"; */ 8 | "zb2-Ws-1tk.normalTitle" = "识别二维码导入"; 9 | -------------------------------------------------------------------------------- /LiveUseful/Import Action/zh-Hant.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle display name */ 2 | "CFBundleDisplayName" = "匯入到神奇鎖屏"; 3 | -------------------------------------------------------------------------------- /LiveUseful/Import Action/zh-Hant.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | /* Class = "UIButton"; normalTitle = "Import as image"; ObjectID = "0SP-zH-cBV"; */ 2 | "0SP-zH-cBV.normalTitle" = "作為圖片匯入"; 3 | 4 | /* Class = "UIButton"; normalTitle = "Cancel"; ObjectID = "TXw-bH-OGn"; */ 5 | "TXw-bH-OGn.normalTitle" = "取消"; 6 | 7 | /* Class = "UIButton"; normalTitle = "Import as link"; ObjectID = "zb2-Ws-1tk"; */ 8 | "zb2-Ws-1tk.normalTitle" = "辨識二維碼匯入"; 9 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful.xcodeproj/project.xcworkspace/xcuserdata/Megabits.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful.xcodeproj/project.xcworkspace/xcuserdata/Megabits.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful.xcodeproj/project.xcworkspace/xcuserdata/Megabits.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LiveUseful/LiveUseful.xcodeproj/xcuserdata/Megabits.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful.xcodeproj/xcuserdata/Megabits.xcuserdatad/xcschemes/LiveUseful.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 69 | 70 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful.xcodeproj/xcuserdata/Megabits.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Generate Live Photo.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | Import Action.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | LiveUseful.xcscheme 18 | 19 | orderHint 20 | 0 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | C026B5551F7FBE6500D462F3 26 | 27 | primary 28 | 29 | 30 | C0CCA3CD217CBA3D000D531F 31 | 32 | primary 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/AddQRDialogViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddQRDialogViewController.swift 3 | // LiveUseful 4 | // 5 | // Created by Megabits on 2018/6/16. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol AddQRDialogDelegate: class { 12 | func getResultFromQRDialog(_ qrContent: String, title: String, canceled: Bool) 13 | } 14 | 15 | class AddQRDialogViewController: UIViewController, UITextViewDelegate, QRScannerDelegate { 16 | 17 | @IBOutlet var dialogView: UIView! 18 | @IBOutlet var titleTextView: UITextView! 19 | @IBOutlet var contentTextView: UITextView! 20 | @IBOutlet var backButton: UIButton! 21 | @IBOutlet var okButton: UIButton! 22 | @IBOutlet var contentWordCount: UILabel! 23 | @IBOutlet var titleWordCount: UILabel! 24 | 25 | var defaultContent = "" 26 | var defaultTitle = "" 27 | var stopToggleKeyboard = false 28 | 29 | weak var delegate: AddQRDialogDelegate? 30 | 31 | @IBAction func cancel(_ sender: Any) { 32 | stopToggleKeyboard = true 33 | contentTextView.resignFirstResponder() 34 | titleTextView.resignFirstResponder() 35 | delegate?.getResultFromQRDialog("", title: "", canceled: true) 36 | dismiss(animated: true, completion: {}) 37 | } 38 | 39 | @IBAction func ok(_ sender: Any) { 40 | stopToggleKeyboard = true 41 | contentTextView.resignFirstResponder() 42 | titleTextView.resignFirstResponder() 43 | var title = "" 44 | if titleTextView.text != NSLocalizedString("Input title here (Optional).", comment: "Input title here (Optional).") { 45 | title = titleTextView.text 46 | } 47 | delegate?.getResultFromQRDialog(contentTextView.text, title: title, canceled: false) 48 | dismiss(animated: true, completion: {}) 49 | } 50 | 51 | override func viewDidLoad() { 52 | super.viewDidLoad() 53 | contentTextView.delegate = self 54 | titleTextView.delegate = self 55 | NotificationCenter.default.addObserver(self, selector:#selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) 56 | NotificationCenter.default.addObserver(self, selector:#selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil) 57 | 58 | backButton.accessibilityLabel = NSLocalizedString("Cancel", comment: "Cancel") 59 | okButton.accessibilityLabel = NSLocalizedString("OK", comment: "OK") 60 | 61 | titleTextView.text = NSLocalizedString("Input title here (Optional).", comment: "Input title here (Optional).") 62 | 63 | } 64 | 65 | override func viewWillAppear(_ animated: Bool) { 66 | super.viewDidAppear(animated) 67 | UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: contentTextView) 68 | 69 | if defaultContent != "" { 70 | contentTextView.text = defaultContent 71 | textViewDidChange(contentTextView) 72 | defaultContent = "" 73 | } 74 | 75 | if defaultTitle != "" { 76 | titleTextView.text = defaultTitle 77 | textViewDidChange(titleTextView) 78 | defaultTitle = "" 79 | } 80 | } 81 | 82 | override func viewWillDisappear(_ animated: Bool) { 83 | tapticGenerator.impactOccurred() 84 | super.viewWillDisappear(animated) 85 | } 86 | 87 | override func viewDidLayoutSubviews() { 88 | if !titleTextView.isFirstResponder && !stopToggleKeyboard { 89 | contentTextView.becomeFirstResponder() 90 | } 91 | 92 | } 93 | 94 | override var prefersHomeIndicatorAutoHidden: Bool { 95 | return true 96 | } 97 | 98 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 99 | if let qrVC = segue.destination as? ScanQRViewController { 100 | qrVC.delegate = self 101 | } 102 | } 103 | 104 | override func accessibilityPerformEscape() -> Bool { 105 | cancel(self) 106 | return true 107 | } 108 | 109 | @objc func keyboardWillShow(_ notif:Notification) { 110 | //Raise dialog when keyboard show 111 | dialogView.translatesAutoresizingMaskIntoConstraints = true 112 | let userInfo:NSDictionary = (notif as NSNotification).userInfo! as NSDictionary 113 | let keyBoardInfo: AnyObject? = userInfo.object(forKey: UIResponder.keyboardFrameEndUserInfoKey) as AnyObject? 114 | let keyBoardHeight = (keyBoardInfo?.cgRectValue.size.height)! 115 | let toolsYWithoutKeyboard = view.frame.height/2 - dialogView.frame.height/2 116 | if keyBoardHeight > 10 { 117 | UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: { 118 | self.dialogView.frame.origin.y = toolsYWithoutKeyboard - keyBoardHeight/3 119 | }) 120 | } 121 | } 122 | 123 | @objc func keyboardWillHide() { 124 | //Reset dialog position 125 | UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: { 126 | self.dialogView.frame.origin.y = self.view.frame.height/2 - self.dialogView.frame.height/2 127 | }) 128 | } 129 | 130 | func textViewDidChange(_ textView: UITextView) { 131 | if textView == contentTextView { 132 | let range = textView.markedTextRange 133 | if range == nil { 134 | if textView.text.trimmingCharacters(in: CharacterSet.whitespaces) != "" { 135 | let length = textView.text.utf8.count 136 | contentWordCount.text = "\(length)/150" 137 | if length > 150 { 138 | contentWordCount.textColor = UIColor.red 139 | okButton.isEnabled = false 140 | } else { 141 | contentWordCount.textColor = UIColor.black 142 | okButton.isEnabled = true 143 | } 144 | } else { 145 | okButton.isEnabled = false 146 | } 147 | } 148 | } else if textView == titleTextView { 149 | let length = textView.text.count 150 | titleWordCount.text = "\(length)/10" 151 | if length > 150 { 152 | titleWordCount.textColor = UIColor.red 153 | okButton.isEnabled = false 154 | } else { 155 | if contentTextView.text != "" { 156 | titleWordCount.textColor = UIColor.black 157 | okButton.isEnabled = true 158 | } 159 | } 160 | } 161 | } 162 | 163 | func textViewDidEndEditing(_ textView: UITextView) { 164 | if textView == contentTextView { 165 | if textView.text.trimmingCharacters(in: CharacterSet.whitespaces) == ""{ 166 | textView.text = "" 167 | okButton.isEnabled = false 168 | } 169 | } else if textView == titleTextView { 170 | if textView.text.trimmingCharacters(in: CharacterSet.whitespaces) == ""{ 171 | textView.text = NSLocalizedString("Input title here (Optional).", comment: "Input title here (Optional).") 172 | } 173 | } 174 | } 175 | 176 | func textViewDidBeginEditing(_ textView: UITextView) { 177 | if textView.text == NSLocalizedString("Input title here (Optional).", comment: "Input title here (Optional).") { 178 | textView.text = "" 179 | } 180 | } 181 | 182 | func getResultFromQRScanner(_ qrContent: String) { 183 | contentTextView.text = qrContent 184 | textViewDidChange(contentTextView) 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // UsefulLive 4 | // 5 | // Created by Megabits on 2017/9/30. 6 | // Copyright © 2017 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | let livePhotoBuilder = BuildLivePhoto() 12 | let tapticGenerator = UIImpactFeedbackGenerator(style:.light) 13 | 14 | //Output 15 | var origenalImage: UIImage? = nil 16 | var croppedImage: UIImage? = nil 17 | var sequenceImages = [Data]() 18 | 19 | //Common 20 | var targetSize: CGSize! //Will be set in StartVC. 21 | let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] 22 | 23 | //Text 24 | var tempText = "" 25 | var tempTextCardStyle = 0 26 | var tempTextAlign = 0 27 | var tempMaximumFontSize: CGFloat = 35 28 | 29 | //List 30 | var list = [(tag: Int,text: String)]() 31 | 32 | //QR 33 | var tempQR = "" 34 | var tempMultipleQR = [(image: UIImage, content: String, title: String)]() 35 | var tempQRCardStyle = 0 36 | var tempCurrentSize = true 37 | var qrCardViewSmallOriginY: CGFloat = 0 38 | var qrCardViewSmallOriginYLimit: CGFloat = 0 39 | 40 | //Image 41 | var tempImage:UIImage? = nil 42 | var tempImageRound:UIImage? = nil 43 | var tempIsRoundCorner = true 44 | var tempIsBlur = false 45 | var tempContentMode = true 46 | var tempScroll = CGPoint(x: 0,y: 0) 47 | var tempZoom: CGFloat = 1 48 | var tempStackMode = true 49 | 50 | //Other 51 | var cropViewController: CropViewController? 52 | var editViewController: EditViewController? 53 | var startViewController: StartViewController? 54 | 55 | var isUsingLastImage = false 56 | 57 | //import 58 | enum importTypes: Int { 59 | case text = 0 60 | case link = 1 61 | case image = 2 62 | case longBreak = 3 63 | } 64 | var importType: ImportKeys? = nil 65 | 66 | var isTutorialsReaded = UserDefaults.standard.bool(forKey: "tutorialsReaded") { 67 | didSet{ 68 | UserDefaults.standard.set(isTutorialsReaded, forKey: "tutorialsReaded") 69 | } 70 | } 71 | var rateCount = UserDefaults.standard.integer(forKey: "rateCount") { 72 | didSet { 73 | UserDefaults.standard.set(rateCount, forKey: "rateCount") 74 | } 75 | } 76 | var isSeeItBanned = UserDefaults.standard.bool(forKey: "isSeeItBanned") 77 | var isNotSaveList = UserDefaults.standard.bool(forKey: "isNotSaveList") { 78 | didSet{ 79 | UserDefaults.standard.set(isNotSaveList, forKey: "isNotSaveList") 80 | } 81 | } 82 | 83 | //Colors 84 | let colorRed = UIColor(red: 255/255, green: 121/255, blue: 100/255, alpha: 1) 85 | let colorYellow = UIColor(red: 255/255, green: 188/255, blue: 103/255, alpha: 1) 86 | let colorBlue = UIColor(red: 155/255, green: 193/255, blue: 224/255, alpha: 1) 87 | let colorPurple = UIColor(red: 226/255, green: 128/255, blue: 228/255, alpha: 1) 88 | let colorGray = UIColor(red: 170/255, green: 170/255, blue: 170/255, alpha: 1) 89 | 90 | @UIApplicationMain 91 | class AppDelegate: UIResponder, UIApplicationDelegate { 92 | 93 | var window: UIWindow? 94 | 95 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 96 | //Load list 97 | if UserDefaults.standard.array(forKey: "list") != nil { 98 | let dataToOpen = UserDefaults.standard.array(forKey: "list") as! [[String]] 99 | for item in dataToOpen { 100 | list.append((tag: Int(item[0])!, text: item[1])) 101 | } 102 | } 103 | 104 | tapticGenerator.prepare() 105 | 106 | return true 107 | } 108 | 109 | func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { 110 | 111 | if let svc = startViewController { 112 | svc.dismiss(animated: false, completion: nil) 113 | } 114 | resetAll() 115 | 116 | let urlString = url.absoluteString.urlDecoded() 117 | let queryArray = urlString.components(separatedBy: "/") 118 | let typeString = queryArray[2] 119 | 120 | for type in ImportKeys.allCases { 121 | if type.rawValue == typeString { 122 | importType = type 123 | return true 124 | } 125 | } 126 | return true 127 | } 128 | 129 | func applicationWillResignActive(_ application: UIApplication) { } 130 | 131 | func applicationDidEnterBackground(_ application: UIApplication) { } 132 | 133 | func applicationWillEnterForeground(_ application: UIApplication) { } 134 | 135 | func applicationDidBecomeActive(_ application: UIApplication) { } 136 | 137 | func applicationWillTerminate(_ application: UIApplication) { 138 | resetAll() 139 | } 140 | 141 | func resetAll() { 142 | //Clear all before return to CropVC 143 | isUsingLastImage = false 144 | isSeeItBanned = UserDefaults.standard.bool(forKey: "isSeeItBanned") 145 | sequenceImages.removeAll() 146 | 147 | //Text 148 | tempText = "" 149 | tempTextCardStyle = 0 150 | tempTextAlign = 0 151 | tempMaximumFontSize = 35 152 | 153 | //refresh list storage 154 | var dataToSave = [[String]]() 155 | if !isNotSaveList { 156 | for item in list { 157 | dataToSave.append(["\(item.tag)", item.text]) 158 | } 159 | UserDefaults.standard.set(dataToSave, forKey: "list") 160 | } else { 161 | list = [(tag: Int,text: String)]() 162 | UserDefaults.standard.set(dataToSave, forKey: "list") 163 | } 164 | 165 | //QR 166 | tempQR = "" 167 | tempMultipleQR.removeAll() 168 | tempQRCardStyle = 0 169 | tempCurrentSize = true 170 | qrCardViewSmallOriginY = 0 171 | 172 | //Image 173 | tempImage = nil 174 | tempImageRound = nil 175 | tempIsRoundCorner = false 176 | tempIsBlur = false 177 | tempContentMode = true 178 | tempScroll = CGPoint(x: 0,y: 0) 179 | tempZoom = 1 180 | tempStackMode = true 181 | 182 | //Clear file cache 183 | livePhotoBuilder.clean() 184 | } 185 | } 186 | 187 | extension String { 188 | //将编码后的url转换回原始的url 189 | func urlDecoded() -> String { 190 | return self.removingPercentEncoding ?? "" 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Alert/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Alert/Error.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Error.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Error@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Error@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Alert/Error.imageset/Error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Alert/Error.imageset/Error.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Alert/Error.imageset/Error@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Alert/Error.imageset/Error@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Alert/Error.imageset/Error@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Alert/Error.imageset/Error@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Alert/Finish.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Finish.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Finish@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Finish@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Alert/Finish.imageset/Finish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Alert/Finish.imageset/Finish.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Alert/Finish.imageset/Finish@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Alert/Finish.imageset/Finish@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Alert/Finish.imageset/Finish@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Alert/Finish.imageset/Finish@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "iPhone-20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "iPhone-20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "iPhone-29@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "iPhone-29@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "iPhone-40@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "iPhone-40@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "iPhone-60@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "iPhone-60@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "1024x1024", 53 | "idiom" : "ios-marketing", 54 | "filename" : "iTunesConnect.png", 55 | "scale" : "1x" 56 | } 57 | ], 58 | "info" : { 59 | "version" : 1, 60 | "author" : "xcode" 61 | } 62 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-20@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-20@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-29@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-29@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-40@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-40@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-60@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iPhone-60@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iTunesConnect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/AppIcon.appiconset/iTunesConnect.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/Blur.imageset/Blur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/Blur.imageset/Blur.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/Blur.imageset/Blur@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/Blur.imageset/Blur@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/Blur.imageset/Blur@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/Blur.imageset/Blur@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/Blur.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Blur.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Blur@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Blur@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/FullScreen.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "FullScreen.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "FullScreen@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "FullScreen@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/FullScreen.imageset/FullScreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/FullScreen.imageset/FullScreen.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/FullScreen.imageset/FullScreen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/FullScreen.imageset/FullScreen@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/FullScreen.imageset/FullScreen@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/FullScreen.imageset/FullScreen@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/NoBlur.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "NoBlur.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "NoBlur@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "NoBlur@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/NoBlur.imageset/NoBlur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/NoBlur.imageset/NoBlur.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/NoBlur.imageset/NoBlur@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/NoBlur.imageset/NoBlur@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/NoBlur.imageset/NoBlur@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/NoBlur.imageset/NoBlur@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/OpenImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "OpenImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "OpenImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "OpenImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/OpenImage.imageset/OpenImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/OpenImage.imageset/OpenImage.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/OpenImage.imageset/OpenImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/OpenImage.imageset/OpenImage@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/OpenImage.imageset/OpenImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/OpenImage.imageset/OpenImage@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/RectCorner.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "RectCorner.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "RectCorner@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "RectCorner@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/RectCorner.imageset/RectCorner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/RectCorner.imageset/RectCorner.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/RectCorner.imageset/RectCorner@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/RectCorner.imageset/RectCorner@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/RectCorner.imageset/RectCorner@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/RectCorner.imageset/RectCorner@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/RoundCorner.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "RoundCorner.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "RoundCorner@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "RoundCorner@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/RoundCorner.imageset/RoundCorner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/RoundCorner.imageset/RoundCorner.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/RoundCorner.imageset/RoundCorner@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/RoundCorner.imageset/RoundCorner@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/RoundCorner.imageset/RoundCorner@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/RoundCorner.imageset/RoundCorner@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/Thumbnail.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Thumbnail.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Thumbnail@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Thumbnail@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/Thumbnail.imageset/Thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/Thumbnail.imageset/Thumbnail.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/Thumbnail.imageset/Thumbnail@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/Thumbnail.imageset/Thumbnail@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Image/Thumbnail.imageset/Thumbnail@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Image/Thumbnail.imageset/Thumbnail@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Back.imageset/Back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Back.imageset/Back.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Back.imageset/Back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Back.imageset/Back@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Back.imageset/Back@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Back.imageset/Back@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Back.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Back.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Back@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Back@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Crop.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Crop.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Crop@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Crop@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Crop.imageset/Crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Crop.imageset/Crop.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Crop.imageset/Crop@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Crop.imageset/Crop@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Crop.imageset/Crop@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Crop.imageset/Crop@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Help.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Help.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Help@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Help@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Help.imageset/Help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Help.imageset/Help.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Help.imageset/Help@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Help.imageset/Help@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Help.imageset/Help@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Help.imageset/Help@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Image.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Image@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Image@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Image.imageset/Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Image.imageset/Image.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Image.imageset/Image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Image.imageset/Image@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Image.imageset/Image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Image.imageset/Image@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/QR.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QR.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "QR@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "QR@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/QR.imageset/QR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/QR.imageset/QR.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/QR.imageset/QR@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/QR.imageset/QR@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/QR.imageset/QR@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/QR.imageset/QR@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Save.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Save.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Save@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Save@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Save.imageset/Save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Save.imageset/Save.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Save.imageset/Save@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Save.imageset/Save@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Save.imageset/Save@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Save.imageset/Save@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Text.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Text.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Text@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Text@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Text.imageset/Text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Text.imageset/Text.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Text.imageset/Text@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Text.imageset/Text@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/Text.imageset/Text@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/Text.imageset/Text@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/ToPhotos.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ToPhotos.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ToPhotos@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ToPhotos@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/ToPhotos.imageset/ToPhotos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/ToPhotos.imageset/ToPhotos.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/ToPhotos.imageset/ToPhotos@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/ToPhotos.imageset/ToPhotos@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Main Button/ToPhotos.imageset/ToPhotos@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Main Button/ToPhotos.imageset/ToPhotos@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Omake.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "IMG_0999.jpeg", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Omake.imageset/IMG_0999.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Omake.imageset/IMG_0999.jpeg -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/CancelDialog.imageset/Cancel2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/CancelDialog.imageset/Cancel2.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/CancelDialog.imageset/Cancel2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/CancelDialog.imageset/Cancel2@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/CancelDialog.imageset/Cancel2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/CancelDialog.imageset/Cancel2@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/CancelDialog.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Cancel2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Cancel2@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Cancel2@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Multiple.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Multiple.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Multiple@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Multiple@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Multiple.imageset/Multiple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/Multiple.imageset/Multiple.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Multiple.imageset/Multiple@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/Multiple.imageset/Multiple@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Multiple.imageset/Multiple@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/Multiple.imageset/Multiple@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/OpenQRImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "OpenQRImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "OpenQRImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "OpenQRImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/OpenQRImage.imageset/OpenQRImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/OpenQRImage.imageset/OpenQRImage.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/OpenQRImage.imageset/OpenQRImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/OpenQRImage.imageset/OpenQRImage@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/OpenQRImage.imageset/OpenQRImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/OpenQRImage.imageset/OpenQRImage@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/QRBackground.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QRBackground.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "QRBackground@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "QRBackground@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/QRBackground.imageset/QRBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/QRBackground.imageset/QRBackground.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/QRBackground.imageset/QRBackground@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/QRBackground.imageset/QRBackground@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/QRBackground.imageset/QRBackground@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/QRBackground.imageset/QRBackground@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Remove.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Remove.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Remove@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Remove@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Remove.imageset/Remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/Remove.imageset/Remove.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Remove.imageset/Remove@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/Remove.imageset/Remove@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Remove.imageset/Remove@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/Remove.imageset/Remove@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/ShowBig.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ShowBig.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ShowBig@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ShowBig@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/ShowBig.imageset/ShowBig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/ShowBig.imageset/ShowBig.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/ShowBig.imageset/ShowBig@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/ShowBig.imageset/ShowBig@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/ShowBig.imageset/ShowBig@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/ShowBig.imageset/ShowBig@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/ShowSmall.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ShowSmall.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ShowSmall@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ShowSmall@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/ShowSmall.imageset/ShowSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/ShowSmall.imageset/ShowSmall.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/ShowSmall.imageset/ShowSmall@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/ShowSmall.imageset/ShowSmall@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/ShowSmall.imageset/ShowSmall@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/ShowSmall.imageset/ShowSmall@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Single.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Single.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Single@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Single@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Single.imageset/Single.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/Single.imageset/Single.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Single.imageset/Single@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/Single.imageset/Single@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/Single.imageset/Single@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/Single.imageset/Single@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/TransferQR.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Transfer QR.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Transfer QR@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Transfer QR@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/TransferQR.imageset/Transfer QR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/TransferQR.imageset/Transfer QR.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/TransferQR.imageset/Transfer QR@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/TransferQR.imageset/Transfer QR@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/QR/TransferQR.imageset/Transfer QR@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/QR/TransferQR.imageset/Transfer QR@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/Icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Icon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Icon@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Icon@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/Icon.imageset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Start Page/Icon.imageset/Icon.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/Icon.imageset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Start Page/Icon.imageset/Icon@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/Icon.imageset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Start Page/Icon.imageset/Icon@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/OpenPhoto.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "OpenPhoto.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "OpenPhoto@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "OpenPhoto@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/OpenPhoto.imageset/OpenPhoto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Start Page/OpenPhoto.imageset/OpenPhoto.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/OpenPhoto.imageset/OpenPhoto@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Start Page/OpenPhoto.imageset/OpenPhoto@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/OpenPhoto.imageset/OpenPhoto@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Start Page/OpenPhoto.imageset/OpenPhoto@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/UseLastPhoto.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "UseLastPhoto.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "UseLastPhoto@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "UseLastPhoto@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/UseLastPhoto.imageset/UseLastPhoto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Start Page/UseLastPhoto.imageset/UseLastPhoto.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/UseLastPhoto.imageset/UseLastPhoto@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Start Page/UseLastPhoto.imageset/UseLastPhoto@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Start Page/UseLastPhoto.imageset/UseLastPhoto@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Start Page/UseLastPhoto.imageset/UseLastPhoto@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AddItem.imageset/AddItem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AddItem.imageset/AddItem.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AddItem.imageset/AddItem@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AddItem.imageset/AddItem@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AddItem.imageset/AddItem@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AddItem.imageset/AddItem@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AddItem.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "AddItem.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "AddItem@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "AddItem@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignCenter.imageset/Align Center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignCenter.imageset/Align Center.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignCenter.imageset/Align Center@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignCenter.imageset/Align Center@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignCenter.imageset/Align Center@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignCenter.imageset/Align Center@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignCenter.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Align Center.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Align Center@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Align Center@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignJustified.imageset/Align Justified.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignJustified.imageset/Align Justified.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignJustified.imageset/Align Justified@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignJustified.imageset/Align Justified@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignJustified.imageset/Align Justified@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignJustified.imageset/Align Justified@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignJustified.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Align Justified.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Align Justified@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Align Justified@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignLeft.imageset/Align Left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignLeft.imageset/Align Left.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignLeft.imageset/Align Left@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignLeft.imageset/Align Left@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignLeft.imageset/Align Left@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignLeft.imageset/Align Left@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignLeft.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Align Left.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Align Left@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Align Left@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignRight.imageset/Align Right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignRight.imageset/Align Right.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignRight.imageset/Align Right@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignRight.imageset/Align Right@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignRight.imageset/Align Right@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/AlignRight.imageset/Align Right@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/AlignRight.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Align Right.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Align Right@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Align Right@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/BackgroundCard.imageset/BackgroundCard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/BackgroundCard.imageset/BackgroundCard.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/BackgroundCard.imageset/BackgroundCard@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/BackgroundCard.imageset/BackgroundCard@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/BackgroundCard.imageset/BackgroundCard@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/BackgroundCard.imageset/BackgroundCard@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/BackgroundCard.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "BackgroundCard.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "BackgroundCard@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "BackgroundCard@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/FontSize.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "FontSize.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "FontSize@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "FontSize@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/FontSize.imageset/FontSize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/FontSize.imageset/FontSize.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/FontSize.imageset/FontSize@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/FontSize.imageset/FontSize@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/FontSize.imageset/FontSize@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/FontSize.imageset/FontSize@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/ListMode.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ListMode.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ListMode@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ListMode@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/ListMode.imageset/ListMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/ListMode.imageset/ListMode.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/ListMode.imageset/ListMode@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/ListMode.imageset/ListMode@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/ListMode.imageset/ListMode@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/ListMode.imageset/ListMode@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/TextMode.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "TextMode.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "TextMode@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "TextMode@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/TextMode.imageset/TextMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/TextMode.imageset/TextMode.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/TextMode.imageset/TextMode@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/TextMode.imageset/TextMode@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Text/TextMode.imageset/TextMode@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Text/TextMode.imageset/TextMode@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Top Bar/Cancel.imageset/Cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Top Bar/Cancel.imageset/Cancel.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Top Bar/Cancel.imageset/Cancel@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Top Bar/Cancel.imageset/Cancel@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Top Bar/Cancel.imageset/Cancel@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Top Bar/Cancel.imageset/Cancel@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Top Bar/Cancel.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Cancel.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Cancel@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Cancel@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Top Bar/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Top Bar/OK.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "OK.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "OK@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "OK@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Top Bar/OK.imageset/OK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Top Bar/OK.imageset/OK.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Top Bar/OK.imageset/OK@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Top Bar/OK.imageset/OK@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Top Bar/OK.imageset/OK@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Top Bar/OK.imageset/OK@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/NextPage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "NextPage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "NextPage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "NextPage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/NextPage.imageset/NextPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Tutorials/NextPage.imageset/NextPage.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/NextPage.imageset/NextPage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Tutorials/NextPage.imageset/NextPage@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/NextPage.imageset/NextPage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Tutorials/NextPage.imageset/NextPage@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/PrevPage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "PrevPage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "PrevPage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "PrevPage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/PrevPage.imageset/PrevPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Tutorials/PrevPage.imageset/PrevPage.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/PrevPage.imageset/PrevPage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Tutorials/PrevPage.imageset/PrevPage@2x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/PrevPage.imageset/PrevPage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Tutorials/PrevPage.imageset/PrevPage@3x.png -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "t1.jpg", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial1.imageset/t1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial1.imageset/t1.jpg -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "t2.jpg", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial2.imageset/t2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial2.imageset/t2.jpg -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "t3.jpg", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial3.imageset/t3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial3.imageset/t3.jpg -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "t4.jpg", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial4.imageset/t4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/LiveUseful/LiveUseful/Assets.xcassets/Tutorials/Tutorial4.imageset/t4.jpg -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/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 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/BuildViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BuildViewController.swift 3 | // LiveUseful 4 | // 5 | // Created by Megabits on 2017/12/27. 6 | // Copyright © 2017 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import PhotosUI 11 | 12 | class BuildViewController: UIViewController, PHLivePhotoViewDelegate{ 13 | 14 | @IBOutlet var livePhotoView: PHLivePhotoView! 15 | @IBOutlet var imageView: UIImageView! 16 | @IBOutlet var toolbarView: UIView! 17 | @IBOutlet var alertBackground: UIVisualEffectView! 18 | @IBOutlet var alertView: UIView! 19 | @IBOutlet var tipView: UIView! 20 | @IBOutlet var loading: UIActivityIndicatorView! 21 | @IBOutlet var saveButton: UIButton! 22 | 23 | var saved = false 24 | 25 | @IBAction func back(_ sender: Any) { 26 | let appDelegate = UIApplication.shared.delegate as! AppDelegate 27 | appDelegate.resetAll() 28 | //Hide views in previous VC 29 | cropViewController?.toolbarView.isHidden = true 30 | editViewController?.toolbarView.isHidden = true 31 | editViewController?.toolbarStackView.isHidden = true 32 | startViewController!.dismiss(animated: true, completion: {}) 33 | } 34 | 35 | @IBAction func save(_ sender: UIButton) { 36 | if saved { //Change button to "Open Photos" after saved 37 | let url = "photos-redirect://" 38 | UIApplication.shared.open(NSURL(string: url)! as URL, options: [:], completionHandler: nil) 39 | return 40 | } 41 | 42 | tapticGenerator.impactOccurred() 43 | 44 | //Rate counter 45 | if rateCount < 2 { 46 | rateCount += 1 47 | } 48 | alertBackground.isHidden = false 49 | 50 | //Change to "Open Photos" 51 | sender.setImage(#imageLiteral(resourceName: "ToPhotos"), for: .normal) 52 | sender.accessibilityLabel = NSLocalizedString("Open photos", comment: "Open photos") 53 | saved = true 54 | 55 | //Save file if "never show alert" was set 56 | if isSeeItBanned { 57 | livePhotoBuilder.save() 58 | UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: { 59 | self.alertBackground.effect = UIBlurEffect(style: .extraLight) 60 | self.alertView.alpha = 1 61 | }, completion: { (finished: Bool) in 62 | UIView.animate(withDuration: 0.3, delay: 0.3, options: .curveEaseOut, animations: { 63 | self.alertBackground.effect = .none 64 | self.alertView.alpha = 0 65 | }, completion: { (finished: Bool) in 66 | self.alertBackground.isHidden = true 67 | }) 68 | }) 69 | } else { 70 | performSegue(withIdentifier: "seeIt", sender: self) 71 | } 72 | } 73 | 74 | override func viewDidLoad() { 75 | super.viewDidLoad() 76 | 77 | livePhotoView.delegate = self 78 | NotificationCenter.default.addObserver(self, selector: #selector(backWhenEnterForeground), name: UIApplication.willEnterForegroundNotification, object:nil) 79 | 80 | imageView.image = croppedImage 81 | alertBackground.effect = .none 82 | 83 | //Save last background image 84 | if !isUsingLastImage { 85 | DispatchQueue.global().async { 86 | let imageURL = URL(fileURLWithPath: (documentsPath as NSString).appendingPathComponent("last.jpg")) 87 | do{ 88 | try croppedImage!.jpegData(compressionQuality: 1)?.write(to: imageURL) 89 | } catch { 90 | print(error) 91 | } 92 | } 93 | } 94 | 95 | //Build files 96 | livePhotoBuilder.build(coverImage: croppedImage!, sequenceImage: sequenceImages, {(livePhoto) -> Void in 97 | self.livePhotoView.livePhoto = livePhoto 98 | tapticGenerator.impactOccurred() 99 | UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseOut, animations: { 100 | self.livePhotoView.alpha = 1 101 | self.toolbarView.alpha = 1 102 | self.tipView.alpha = 0.6 103 | }, completion: { (finished: Bool) in 104 | self.loading.isHidden = true 105 | }) 106 | }) 107 | sequenceImages.removeAll() 108 | } 109 | 110 | override func viewDidAppear(_ animated: Bool) { 111 | super.viewDidAppear(animated) 112 | UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: saveButton) 113 | 114 | //Show saved message when back from SeeItVC 115 | UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: { 116 | self.alertBackground.effect = UIBlurEffect(style: .extraLight) 117 | self.alertView.alpha = 1 118 | }, completion: { (finished: Bool) in 119 | UIView.animate(withDuration: 0.3, delay: 0.3, options: .curveEaseOut, animations: { 120 | self.alertBackground.effect = .none 121 | self.alertView.alpha = 0 122 | }, completion: { (finished: Bool) in 123 | self.alertBackground.isHidden = true 124 | }) 125 | }) 126 | } 127 | 128 | override var prefersHomeIndicatorAutoHidden: Bool { 129 | return true 130 | } 131 | 132 | //Hide tips when press screen 133 | func livePhotoView(_ livePhotoView: PHLivePhotoView, didEndPlaybackWith playbackStyle: PHLivePhotoViewPlaybackStyle) { 134 | UIView.animate(withDuration: 0.1, animations: { 135 | self.tipView.alpha = 0.6 136 | }) 137 | } 138 | 139 | func livePhotoView(_ livePhotoView: PHLivePhotoView, willBeginPlaybackWith playbackStyle: PHLivePhotoViewPlaybackStyle) { 140 | UIView.animate(withDuration: 0.3, animations: { 141 | self.tipView.alpha = 0 142 | }) 143 | } 144 | 145 | //Back to startVC if saved 146 | @objc func backWhenEnterForeground() { 147 | if saved { 148 | back(self) 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/CropViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CropViewController.swift 3 | // UsefulLive 4 | // 5 | // Created by Megabits on 2017/12/9. 6 | // Copyright © 2017 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CropViewController: UIViewController, UIScrollViewDelegate { 12 | 13 | @IBOutlet var scrollView: UIScrollView! 14 | @IBOutlet var toolbarView: UIView! 15 | @IBOutlet weak var importAlertView: UIView! 16 | 17 | @IBAction func removeImport(_ sender: Any) { 18 | importType = nil 19 | importAlertView.isHidden = true 20 | } 21 | 22 | @IBAction func pop(_ sender: Any) { 23 | tapticGenerator.impactOccurred() 24 | dismiss(animated: true, completion: {}) 25 | } 26 | 27 | @IBAction func crop(_ sender: Any) { 28 | let croppedCGImage = fixOrientation(img: imageView.image!).cgImage?.cropping(to: cropArea) 29 | //Make sure the image is stable 30 | croppedImage = UIImage(cgImage: croppedCGImage!) 31 | if abs(croppedImage!.size.width / view.frame.size.width - croppedImage!.size.height / view.frame.size.height) < 0.01{ 32 | performSegue(withIdentifier: "toEdit", sender: self) 33 | } 34 | } 35 | 36 | let imageView = UIImageView(frame: CGRect(origin: CGPoint(x:0, y:0), size: origenalImage!.size)) 37 | 38 | var cropArea:CGRect{ 39 | get{ 40 | let scale = 1/scrollView.zoomScale 41 | let x = scrollView.contentOffset.x * scale 42 | let y = scrollView.contentOffset.y * scale 43 | let width = view.frame.size.width * scale 44 | let height = view.frame.size.height * scale 45 | return CGRect(x: x, y: y, width: width, height: height) 46 | } 47 | } 48 | 49 | var tempOriginY: CGFloat = 0 50 | 51 | override func viewDidLoad() { 52 | super.viewDidLoad() 53 | 54 | scrollView.delegate = self 55 | cropViewController = self 56 | 57 | imageView.image = origenalImage 58 | scrollView.addSubview(imageView) 59 | 60 | //scale to fill 61 | let widthMinimumScale = view.frame.width / origenalImage!.size.width 62 | let heightMinimumScale = view.frame.height / origenalImage!.size.height 63 | var minimumZoomScale:CGFloat = 1.0 64 | 65 | if widthMinimumScale < 1 { 66 | if heightMinimumScale < 1 { 67 | minimumZoomScale = max(widthMinimumScale,heightMinimumScale) 68 | } else { 69 | minimumZoomScale = heightMinimumScale 70 | } 71 | } else { 72 | if heightMinimumScale < 1 { 73 | minimumZoomScale = widthMinimumScale 74 | } else { 75 | minimumZoomScale = max(widthMinimumScale,heightMinimumScale) 76 | } 77 | } 78 | 79 | //fix images in the wrong position 80 | if #available(iOS 11.0, *) { 81 | scrollView.contentInsetAdjustmentBehavior = .never 82 | } else { 83 | automaticallyAdjustsScrollViewInsets = false 84 | } 85 | 86 | scrollView.minimumZoomScale = minimumZoomScale 87 | scrollView.maximumZoomScale = 10 88 | scrollView.zoomScale = minimumZoomScale 89 | scrollView.contentOffset.x = origenalImage!.size.width * minimumZoomScale / 2 - view.frame.width / 2 90 | scrollView.contentOffset.y = origenalImage!.size.height * minimumZoomScale / 2 - view.frame.height / 2 91 | 92 | NotificationCenter.default.addObserver(self, selector: #selector(becomeActive), name: UIApplication.didBecomeActiveNotification, object: nil) 93 | 94 | becomeActive() 95 | 96 | } 97 | 98 | override var prefersHomeIndicatorAutoHidden: Bool { 99 | return true 100 | } 101 | 102 | override func viewWillAppear(_ animated: Bool) { 103 | super.viewDidAppear(animated) 104 | 105 | tempOriginY = toolbarView.frame.origin.y 106 | toolbarView.frame.origin.y = view.frame.height 107 | UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseOut, animations: { 108 | self.toolbarView.frame.origin.y = self.tempOriginY 109 | }) 110 | } 111 | 112 | override func viewWillDisappear(_ animated: Bool) { 113 | UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: { 114 | self.toolbarView.frame.origin.y = self.view.frame.height 115 | }, completion: { (finished: Bool) in 116 | self.view.setNeedsLayout() 117 | }) 118 | super.viewWillDisappear(animated) 119 | } 120 | 121 | //Draw "Z" with two fingers 122 | override func accessibilityPerformEscape() -> Bool { 123 | pop(self) 124 | return true 125 | } 126 | 127 | override func accessibilityPerformMagicTap() -> Bool { 128 | crop(self) 129 | return true 130 | } 131 | 132 | @objc func becomeActive() { 133 | if importType != nil { 134 | importAlertView.isHidden = false 135 | } else { 136 | importAlertView.isHidden = true 137 | } 138 | } 139 | 140 | func viewForZooming(in scrollView: UIScrollView) -> UIView? { 141 | return imageView 142 | } 143 | 144 | //Some photos' orientation is just in the metadata, so rotate it first 145 | func fixOrientation(img: UIImage) -> UIImage { 146 | if (img.imageOrientation == .up) { 147 | return img 148 | } 149 | UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale) 150 | let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height) 151 | img.draw(in: rect) 152 | 153 | let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()! 154 | UIGraphicsEndImageContext() 155 | 156 | return normalizedImage 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/EditViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditViewController.swift 3 | // LiveUseful 4 | // 5 | // Created by Megabits on 2017/12/9. 6 | // Copyright © 2017 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import StoreKit 11 | 12 | class EditViewController: UIViewController { 13 | 14 | @IBOutlet var toolbarView: UIView! 15 | @IBOutlet var imageView: UIImageView! 16 | @IBOutlet var toolbarStackView: UIStackView! 17 | @IBOutlet var addThingsToolbarView: UIView! 18 | 19 | var tempOriginY: CGFloat = 0 20 | var addThingstempOrigin = CGPoint() 21 | var isShowTools = false 22 | 23 | @IBAction func pop(_ sender: Any) { 24 | let appDelegate = UIApplication.shared.delegate as! AppDelegate 25 | appDelegate.resetAll() 26 | tempText = "" 27 | showAndHideTools({}) 28 | self.dismiss(animated: true, completion: {}) 29 | } 30 | 31 | @IBAction func helpAndInfo(_ sender: Any) { 32 | tapticGenerator.impactOccurred() 33 | performSegue(withIdentifier: "toAbout", sender: self) 34 | } 35 | 36 | @IBAction func toText(_ sender: Any) { 37 | showAndHideTools({ 38 | self.isShowTools = false 39 | self.performSegue(withIdentifier: "toText", sender: self) 40 | }) 41 | } 42 | 43 | @IBAction func toImage(_ sender: Any) { 44 | showAndHideTools({ 45 | self.isShowTools = false 46 | self.performSegue(withIdentifier: "toImage", sender: self) 47 | }) 48 | } 49 | 50 | @IBAction func toQR(_ sender: Any) { 51 | showAndHideTools({ 52 | self.isShowTools = false 53 | self.performSegue(withIdentifier: "toQR", sender: self) 54 | }) 55 | } 56 | 57 | override func viewDidLoad() { 58 | super.viewDidLoad() 59 | 60 | editViewController = self 61 | 62 | tempOriginY = toolbarView.frame.origin.y 63 | addThingstempOrigin = addThingsToolbarView.frame.origin 64 | 65 | imageView.image = croppedImage 66 | 67 | } 68 | 69 | override var prefersHomeIndicatorAutoHidden: Bool { 70 | return true 71 | } 72 | 73 | override func viewWillAppear(_ animated: Bool) { 74 | super.viewDidAppear(animated) 75 | 76 | toolbarView.isHidden = true 77 | toolbarStackView.isHidden = true 78 | let appGroupName = "group.liveuseful" 79 | 80 | //准备内容,如果存在导入则不显示 UI 元素 81 | switch importType { 82 | case .Text?: 83 | tempText = UserDefaults(suiteName: appGroupName)!.string(forKey: ImportKeys.Text.rawValue) ?? "" 84 | importType = nil 85 | self.performSegue(withIdentifier: "toText", sender: self) 86 | return 87 | case .URL?: 88 | tempQR = UserDefaults(suiteName: appGroupName)!.url(forKey: ImportKeys.URL.rawValue)?.absoluteString ?? "" 89 | importType = nil 90 | self.performSegue(withIdentifier: "toQR", sender: self) 91 | return 92 | case .Image?: 93 | tempImage = UIImage(data: UserDefaults(suiteName: appGroupName)!.data(forKey: ImportKeys.Image.rawValue)!) 94 | tempImageRound = tempImage!.roundedImage 95 | self.performSegue(withIdentifier: "toImage", sender: self) 96 | return 97 | default: break 98 | } 99 | 100 | toolbarView.isHidden = false 101 | toolbarStackView.isHidden = false 102 | 103 | showAndHideTools({ 104 | if rateCount == 2 { 105 | SKStoreReviewController.requestReview() 106 | rateCount = 0 107 | } 108 | }) 109 | } 110 | 111 | override func accessibilityPerformEscape() -> Bool { 112 | pop(self) 113 | return true 114 | } 115 | 116 | func showAndHideTools(_ afterAnimation: @escaping () -> ()) { 117 | tapticGenerator.impactOccurred() 118 | if isShowTools { 119 | UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseOut, animations: { 120 | self.toolbarView.frame.origin = CGPoint(x:self.toolbarView.frame.origin.x, y:self.view.frame.height) 121 | self.addThingsToolbarView.frame.origin = CGPoint(x:self.addThingsToolbarView.frame.origin.x, y:self.view.frame.height) 122 | self.addThingsToolbarView.alpha = 0 123 | }, completion: { (finished: Bool) in 124 | self.isShowTools = false 125 | afterAnimation() 126 | }) 127 | } else { 128 | view.setNeedsLayout() 129 | toolbarView.frame.origin.y = view.frame.height 130 | addThingsToolbarView.frame.origin = CGPoint(x:addThingstempOrigin.x, y:view.frame.height) 131 | 132 | UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseOut, animations: { 133 | self.addThingsToolbarView.frame.origin = self.addThingstempOrigin 134 | self.toolbarView.frame.origin.y = self.tempOriginY 135 | self.addThingsToolbarView.alpha = 1 136 | }, completion: { (finished: Bool) in 137 | self.isShowTools = true 138 | afterAnimation() 139 | }) 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // LiveUseful 4 | // 5 | // Created by Megabits on 2018/2/4. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | //Refresh view order for voiceover 12 | extension UIView { 13 | func updateOrder(_ direction: Bool = true) { 14 | var tempElements: [Any]? = [Any]() 15 | let views = (direction) ? subviews : subviews.reversed() 16 | for aView in views { 17 | tempElements?.append(aView) 18 | } 19 | accessibilityElements = tempElements 20 | } 21 | } 22 | 23 | class ReorderAccessibilityByStoryBoardView: UIView { 24 | override func didAddSubview(_ subview: UIView) { 25 | updateOrder() 26 | } 27 | } 28 | 29 | extension UIImage { 30 | 31 | public convenience init?(color: UIColor, size: CGSize) { //Round corner button background 32 | UIGraphicsBeginImageContextWithOptions(size, false, 1) 33 | let rect = CGRect(origin: CGPoint(x: 1, y:1), size: CGSize(width: size.width - 2, height: size.height - 2)) 34 | let path = UIBezierPath(roundedRect: rect, byRoundingCorners: .allCorners,cornerRadii: CGSize(width: rect.size.width/2, height: rect.size.height/2)) 35 | path.lineWidth = 2 36 | color.setStroke() 37 | path.stroke() 38 | UIGraphicsGetCurrentContext()?.addPath(path.cgPath) 39 | let image = UIGraphicsGetImageFromCurrentImageContext() 40 | UIGraphicsEndImageContext() 41 | guard let cgImage = image?.cgImage else { return nil } 42 | self.init(cgImage: cgImage) 43 | } 44 | 45 | func generateQR(text: String) -> UIImage { 46 | let data = text.data(using: String.Encoding.utf8)! 47 | 48 | let qr = CIFilter(name: "CIQRCodeGenerator", parameters: ["inputMessage": data, "inputCorrectionLevel": "M"])! 49 | let qrColorChanged = CIFilter(name: "CIFalseColor", parameters: ["inputImage": qr.outputImage!, "inputColor0": CIColor.black, "inputColor1": CIColor.clear])! 50 | let sizeTransform = CGAffineTransform(scaleX: 20, y: 20) 51 | let qrImage = qrColorChanged.outputImage!.transformed(by: sizeTransform) 52 | 53 | var qrUIImage = UIImage(ciImage: qrImage) 54 | UIGraphicsBeginImageContextWithOptions(qrUIImage.size, false, qrUIImage.scale) 55 | qrUIImage.draw(at: CGPoint.zero) 56 | qrUIImage = UIGraphicsGetImageFromCurrentImageContext()! 57 | UIGraphicsEndImageContext() 58 | 59 | return qrUIImage 60 | } 61 | 62 | var roundedImage: UIImage { 63 | let rect = CGRect(origin:CGPoint(x: 0, y: 0), size: self.size) 64 | UIGraphicsBeginImageContextWithOptions(self.size, false, 1) 65 | let scale = max(self.size.width,self.size.height) / UIScreen.main.bounds.size.width 66 | UIBezierPath( 67 | roundedRect: rect, 68 | cornerRadius: 10 * scale 69 | ).addClip() 70 | self.draw(in: rect) 71 | return UIGraphicsGetImageFromCurrentImageContext()! 72 | } 73 | } 74 | 75 | //fade images when press 76 | extension UIButton { 77 | 78 | override open func touchesBegan(_ touches: Set, with event: UIEvent?) { 79 | if self.tag == 1 { 80 | self.alpha = 0.5 81 | } 82 | super.touchesBegan(touches, with: event) 83 | } 84 | 85 | override open func touchesEnded(_ touches: Set, with event: UIEvent?) { 86 | if self.tag == 1 { 87 | self.alpha = 1 88 | } 89 | super.touchesEnded(touches, with: event) 90 | } 91 | 92 | override open func touchesCancelled(_ touches: Set, with event: UIEvent?) { 93 | if self.tag == 1 { 94 | self.alpha = 1 95 | } 96 | super.touchesCancelled(touches, with: event) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/FileProcess/BuildLivePhoto.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BuildLivePhoto.swift 3 | // LiveUseful 4 | // 5 | // Created by Megabits on 2018/2/15. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | 12 | class BuildLivePhoto { 13 | let assetIdentifier = UUID().uuidString 14 | var imageURL: URL! 15 | var videoURL: URL! 16 | 17 | init() { 18 | imageURL = URL(fileURLWithPath: (documentsPath as NSString).appendingPathComponent("cover.jpg")) 19 | videoURL = URL(fileURLWithPath: (documentsPath as NSString).appendingPathComponent("videoClip.mov")) 20 | // print(videoURL) 21 | } 22 | 23 | func clean() { 24 | //Clear cache 25 | do { 26 | try FileManager.default.removeItem(at: imageURL) 27 | try FileManager.default.removeItem(at: videoURL) 28 | } catch { } 29 | } 30 | 31 | func build(coverImage: UIImage, sequenceImage: [Data], _ afterBuild: @escaping (_ livePhoto:PHLivePhoto?) -> ()) { 32 | clean() 33 | //Cover 34 | JPEG(image: coverImage.cgImage!).write(imageURL, assetIdentifier: self.assetIdentifier) 35 | //Video 36 | QuickTimeMov(image: sequenceImage).write(videoURL, assetIdentifier: self.assetIdentifier) 37 | //Combine LivePhoto 38 | PHLivePhoto.request(withResourceFileURLs: [imageURL, videoURL], placeholderImage: nil, targetSize: targetSize, contentMode: PHImageContentMode.aspectFit, resultHandler: { (livePhoto, info) -> Void in 39 | afterBuild(livePhoto) 40 | // print(info) 41 | }) 42 | } 43 | 44 | func save() { 45 | //Find album "LivePhoto" 46 | let fetchOptions = PHFetchOptions() 47 | fetchOptions.predicate = NSPredicate(format: "title = %@", "LiveUseful") 48 | var collection = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions) 49 | 50 | func savePhoto() { 51 | PHPhotoLibrary.shared().performChanges({ () -> Void in 52 | let creationRequest = PHAssetCreationRequest.forAsset() 53 | let options = PHAssetResourceCreationOptions() 54 | creationRequest.addResource(with: PHAssetResourceType.photo, fileURL: self.imageURL, options: options) 55 | creationRequest.addResource(with: PHAssetResourceType.pairedVideo, fileURL: self.videoURL, options: options) 56 | 57 | let albumChangeRequest = PHAssetCollectionChangeRequest(for: collection.firstObject!) 58 | let placeHolder = creationRequest.placeholderForCreatedAsset 59 | albumChangeRequest?.addAssets([placeHolder!] as NSArray) 60 | }, completionHandler: { (success, error) -> Void in 61 | if !success { 62 | print(error!) 63 | } 64 | }) 65 | } 66 | 67 | if collection.firstObject == nil { 68 | PHPhotoLibrary.shared().performChanges({ //Create album 69 | PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: "LiveUseful") 70 | }) { success, _ in 71 | if success { 72 | collection = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions) 73 | savePhoto() 74 | } 75 | } 76 | } else { 77 | savePhoto() 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/FileProcess/JPEG.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BuildLivePhoto.swift 3 | // LiveUseful 4 | // 5 | // Created by Megabits on 2018/2/15. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import MobileCoreServices 11 | import ImageIO 12 | 13 | class JPEG { 14 | fileprivate let kFigAppleMakerNote_AssetIdentifier = "17" 15 | fileprivate let image : CGImage 16 | 17 | init(image : CGImage) { 18 | self.image = image 19 | } 20 | 21 | func write(_ dest : URL, assetIdentifier : String) { 22 | guard let dest = CGImageDestinationCreateWithURL(dest as CFURL, kUTTypeJPEG, 1, nil) 23 | else { return } 24 | defer { CGImageDestinationFinalize(dest) } 25 | 26 | let makerNote = NSMutableDictionary() 27 | let metadata = NSMutableDictionary() 28 | makerNote.setObject(assetIdentifier, forKey: kFigAppleMakerNote_AssetIdentifier as NSCopying) 29 | metadata.setObject(makerNote, forKey: kCGImagePropertyMakerAppleDictionary as String as String as NSCopying) 30 | CGImageDestinationAddImage(dest, image, metadata) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/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 | APPL 17 | CFBundleShortVersionString 18 | 2.26 19 | CFBundleURLTypes 20 | 21 | 22 | CFBundleTypeRole 23 | Editor 24 | CFBundleURLName 25 | liveuseful 26 | CFBundleURLSchemes 27 | 28 | liveuseful 29 | 30 | 31 | 32 | CFBundleVersion 33 | 1 34 | ITSAppUsesNonExemptEncryption 35 | 36 | LSRequiresIPhoneOS 37 | 38 | NSCameraUsageDescription 39 | Scan QR codes for import. 40 | NSPhotoLibraryUsageDescription 41 | Save Live Photos to your camera roll. 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIMainStoryboardFile 45 | Main 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UIRequiresFullScreen 51 | 52 | UIStatusBarHidden 53 | 54 | UISupportedInterfaceOrientations 55 | 56 | UIInterfaceOrientationPortrait 57 | 58 | UISupportedInterfaceOrientations~ipad 59 | 60 | UIInterfaceOrientationPortrait 61 | UIInterfaceOrientationPortraitUpsideDown 62 | UIInterfaceOrientationLandscapeLeft 63 | UIInterfaceOrientationLandscapeRight 64 | 65 | UIViewControllerBasedStatusBarAppearance 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/LightImageCropperClasses/LCropBorderView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LCropBorderView.swift 3 | // LImagePicker 4 | // 5 | // Created by Jinyu Meng on 2018/6/9. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class LCropBorderView: UIView { 12 | private let kNumberOfBorderHandles: CGFloat = 8 13 | private let kHandleDiameter: CGFloat = 24 14 | 15 | private var accessibilityHandleLabels = [UILabel]() 16 | 17 | override init(frame: CGRect) { 18 | super.init(frame: frame) 19 | 20 | self.backgroundColor = UIColor.clear 21 | } 22 | 23 | required init?(coder aDecoder: NSCoder) { 24 | super.init(coder: aDecoder) 25 | } 26 | 27 | override func draw(_ rect: CGRect) { 28 | let context = UIGraphicsGetCurrentContext() 29 | 30 | context!.setStrokeColor(UIColor(red: 1, green: 1, blue: 1, alpha: 0.5).cgColor) 31 | context!.setLineWidth(1.5) 32 | context!.addRect(CGRect(x:kHandleDiameter / 2, y:kHandleDiameter / 2, width:rect.size.width - kHandleDiameter, height:rect.size.height - kHandleDiameter)) 33 | context!.strokePath() 34 | 35 | context!.setFillColor(red: 1, green: 1, blue: 1, alpha: 0.95) 36 | for handleRect in calculateAllNeededHandleRects() { 37 | context!.fillEllipse(in: handleRect) 38 | } 39 | } 40 | 41 | private func calculateAllNeededHandleRects() -> [CGRect] { 42 | 43 | let width = self.frame.width 44 | let height = self.frame.height 45 | 46 | let leftColX: CGFloat = 0 47 | let rightColX = width - kHandleDiameter 48 | let centerColX = rightColX / 2 49 | 50 | let topRowY: CGFloat = 0 51 | let bottomRowY = height - kHandleDiameter 52 | let middleRowY = bottomRowY / 2 53 | 54 | //starting with the upper left corner and then following clockwise 55 | let topLeft = CGRect(x:leftColX, y:topRowY, width:kHandleDiameter, height:kHandleDiameter) 56 | let topCenter = CGRect(x:centerColX, y:topRowY, width:kHandleDiameter, height:kHandleDiameter) 57 | let topRight = CGRect(x:rightColX, y:topRowY, width:kHandleDiameter, height:kHandleDiameter) 58 | let middleLeft = CGRect(x:leftColX, y:middleRowY, width:kHandleDiameter, height:kHandleDiameter) 59 | let middleRight = CGRect(x:rightColX, y:middleRowY, width:kHandleDiameter, height:kHandleDiameter) 60 | let bottomLeft = CGRect(x:leftColX, y:bottomRowY, width:kHandleDiameter, height:kHandleDiameter) 61 | let bottomCenter = CGRect(x:centerColX, y:bottomRowY, width:kHandleDiameter, height:kHandleDiameter) 62 | let bottomRight = CGRect(x:rightColX, y:bottomRowY, width:kHandleDiameter, height:kHandleDiameter) 63 | 64 | return [topLeft, topCenter, topRight, middleRight, bottomRight, bottomCenter, bottomLeft, 65 | middleLeft] 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/LightImageCropperClasses/LImageCropOverlayView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LImageCropOverlayView.swift 3 | // LImagePicker 4 | // 5 | // Created by Jinyu Meng on 2018/6/9. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class LImageCropOverlayView: UIView { 12 | 13 | var cropSize: CGSize! 14 | var toolbar: UIToolbar! 15 | 16 | override init(frame: CGRect) { 17 | super.init(frame: frame) 18 | 19 | self.backgroundColor = UIColor.clear 20 | self.isUserInteractionEnabled = true 21 | } 22 | 23 | required init?(coder aDecoder: NSCoder) { 24 | super.init(coder: aDecoder) 25 | 26 | self.backgroundColor = UIColor.clear 27 | self.isUserInteractionEnabled = true 28 | } 29 | 30 | override func draw(_ rect: CGRect) { 31 | 32 | let toolbarSize: CGFloat = 54 33 | 34 | let width = self.frame.width 35 | let height = self.frame.height - toolbarSize 36 | 37 | let heightSpan = floor(height / 2 - self.cropSize.height / 2) 38 | let widthSpan = floor(width / 2 - self.cropSize.width / 2) 39 | 40 | // fill outer rect 41 | UIColor(red: 0, green: 0, blue: 0, alpha: 0.5).set() 42 | UIRectFill(self.bounds) 43 | 44 | // fill inner border 45 | UIColor(red: 1, green: 1, blue: 1, alpha: 0.5).set() 46 | UIRectFrame(CGRect(x:widthSpan - 2, y:heightSpan - 2, width:self.cropSize.width + 4, height:self.cropSize.height + 4)) 47 | 48 | // fill inner rect 49 | UIColor.clear.set() 50 | UIRectFill(CGRect(x:widthSpan, y:heightSpan, width:self.cropSize.width, height:self.cropSize.height)) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/LightImageCropperClasses/LImageCropViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LImageCropViewController.swift 3 | // LImagePicker 4 | // 5 | // Created by Jinyu Meng on 2018/6/9. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CoreGraphics 11 | 12 | protocol LImageCropControllerDelegate: class { 13 | func imageCropController(imageCropController: LImageCropViewController, didFinishWithCroppedImage croppedImage: UIImage) 14 | } 15 | 16 | class LImageCropViewController: UIViewController { 17 | 18 | var sourceImage: UIImage! 19 | weak var delegate: LImageCropControllerDelegate? 20 | 21 | private var croppedImage: UIImage! 22 | 23 | private var imageCropView: LImageCropView! 24 | private var toolbar: UIToolbar! 25 | private var useButton: UIButton! 26 | private var cancelButton: UIButton! 27 | 28 | override func viewDidLoad() { 29 | super.viewDidLoad() 30 | 31 | self.navigationController?.isNavigationBarHidden = true 32 | self.automaticallyAdjustsScrollViewInsets = false 33 | self.setupCropView() 34 | self.setupToolbar() 35 | } 36 | 37 | //Prevent notification center activating by accident in iOS 11 38 | override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge { 39 | return .top 40 | } 41 | 42 | override var prefersHomeIndicatorAutoHidden: Bool { 43 | return true 44 | } 45 | 46 | override var prefersStatusBarHidden: Bool { 47 | return true 48 | } 49 | 50 | override func viewWillLayoutSubviews() { 51 | super.viewWillLayoutSubviews() 52 | 53 | self.imageCropView.frame = self.view.bounds 54 | self.toolbar?.frame = CGRect(x:0, y:self.view.frame.height - 54, width:self.view.frame.size.width, height:54) 55 | } 56 | 57 | override func viewDidAppear(_ animated: Bool) { 58 | UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: useButton) 59 | } 60 | 61 | @objc func actionCancel(sender: AnyObject) { 62 | self.navigationController?.popViewController(animated: true) 63 | } 64 | 65 | @objc func actionUse(sender: AnyObject) { 66 | self.croppedImage = self.imageCropView.croppedImage() 67 | self.delegate?.imageCropController(imageCropController: self, didFinishWithCroppedImage: self.croppedImage) 68 | } 69 | 70 | private func setupCropView() { 71 | 72 | self.imageCropView = LImageCropView(frame: self.view.bounds) 73 | self.imageCropView.imageToCrop = sourceImage 74 | self.view.addSubview(self.imageCropView) 75 | } 76 | 77 | private func setupCancelButton() { 78 | 79 | self.cancelButton = UIButton() 80 | self.cancelButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16) 81 | self.cancelButton.titleLabel?.shadowOffset = CGSize(width:0, height:-1) 82 | self.cancelButton.frame = CGRect(x:0, y:0, width:58, height:30) 83 | self.cancelButton.setTitle(NSLocalizedString("Cancel", comment: "Cancel"), for: .normal) 84 | self.cancelButton.setTitleShadowColor( 85 | UIColor(red: 0.118, green: 0.247, blue: 0.455, alpha: 1), for: .normal) 86 | self.cancelButton.addTarget(self, action: #selector(actionCancel), for: .touchUpInside) 87 | } 88 | 89 | private func setupUseButton() { 90 | 91 | self.useButton = UIButton() 92 | self.useButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16) 93 | self.useButton.titleLabel?.shadowOffset = CGSize(width:0, height:-1) 94 | self.useButton.frame = CGRect(x:0, y:0, width:58, height:30) 95 | self.useButton.setTitle(NSLocalizedString("OK", comment: "OK"), for: .normal) 96 | self.useButton.setTitleShadowColor( 97 | UIColor(red: 0.118, green: 0.247, blue: 0.455, alpha: 1), for: .normal) 98 | self.useButton.addTarget(self, action: #selector(actionUse), for: .touchUpInside) 99 | } 100 | 101 | private func toolbarBackgroundImage() -> UIImage { 102 | 103 | let components: [CGFloat] = [1, 1, 1, 1, 123.0 / 255.0, 125.0 / 255.0, 132.0 / 255.0, 1] 104 | 105 | UIGraphicsBeginImageContextWithOptions(CGSize(width:320, height:54), true, 0) 106 | let context = UIGraphicsGetCurrentContext() 107 | let colorSpace = CGColorSpaceCreateDeviceRGB() 108 | let gradient = CGGradient(colorSpace: colorSpace, colorComponents: components, locations: nil, count: 2) 109 | context!.drawLinearGradient(gradient!, start: CGPoint(x:0, y:0), end: CGPoint(x:0, y:54), options: []) 110 | 111 | let viewImage = UIGraphicsGetImageFromCurrentImageContext() 112 | UIGraphicsEndImageContext() 113 | 114 | return viewImage! 115 | } 116 | 117 | private func setupToolbar() { 118 | self.toolbar = UIToolbar(frame: CGRect.zero) 119 | self.toolbar.isTranslucent = true 120 | self.toolbar.barStyle = .black 121 | self.view.addSubview(self.toolbar) 122 | 123 | self.setupCancelButton() 124 | self.setupUseButton() 125 | 126 | let info = UILabel(frame: CGRect.zero) 127 | info.text = "" 128 | info.textColor = UIColor(red: 0.173, green: 0.173, blue: 0.173, alpha: 1) 129 | info.backgroundColor = UIColor.clear 130 | info.shadowColor = UIColor(red: 0.827, green: 0.731, blue: 0.839, alpha: 1) 131 | info.shadowOffset = CGSize(width:0, height:1) 132 | info.font = UIFont.boldSystemFont(ofSize: 18) 133 | info.sizeToFit() 134 | 135 | let cancel = UIBarButtonItem(customView: self.cancelButton) 136 | let flex = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) 137 | let label = UIBarButtonItem(customView: info) 138 | let use = UIBarButtonItem(customView: self.useButton) 139 | 140 | self.toolbar.setItems([cancel, flex, label, flex, use], animated: false) 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/LightImageCropperClasses/LImagePicker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LImagePicker.swift 3 | // LImagePicker 4 | // 5 | // Created by Jinyu Meng on 2018/6/9. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol LImagePickerDelegate: class { 12 | func imagePicker(imagePicker: LImagePicker, pickedImage: UIImage) 13 | func imagePickerDidCancel(imagePicker: LImagePicker) 14 | } 15 | 16 | public class LImagePicker: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate, LImageCropControllerDelegate { 17 | 18 | public weak var delegate: LImagePickerDelegate? 19 | 20 | private var _imagePickerController: UIImagePickerController! 21 | 22 | public var imagePickerController: UIImagePickerController { 23 | return _imagePickerController 24 | } 25 | 26 | override public init() { 27 | super.init() 28 | 29 | _imagePickerController = UIImagePickerController() 30 | _imagePickerController.delegate = self 31 | _imagePickerController.sourceType = .photoLibrary 32 | _imagePickerController.modalTransitionStyle = .crossDissolve 33 | } 34 | 35 | private func hideController() { 36 | self._imagePickerController.dismiss(animated: true, completion: nil) 37 | } 38 | 39 | public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 40 | 41 | if self.delegate?.imagePickerDidCancel != nil { 42 | self.delegate?.imagePickerDidCancel(imagePicker: self) 43 | } else { 44 | self.hideController() 45 | } 46 | picker.dismiss(animated: true, completion: nil) 47 | } 48 | 49 | public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { 50 | let cropController = LImageCropViewController() 51 | let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage 52 | cropController.sourceImage = image 53 | cropController.delegate = self 54 | picker.pushViewController(cropController, animated: true) 55 | } 56 | 57 | func imageCropController(imageCropController: LImageCropViewController, didFinishWithCroppedImage croppedImage: UIImage) { 58 | self.delegate?.imagePicker(imagePicker: self, pickedImage: croppedImage) 59 | imagePickerController.dismiss(animated: true, completion: nil) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/ListTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ListTableViewCell.swift 3 | // PomoNow 4 | // 5 | // Created by Megabits on 2018/2/20. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ListTableViewCell: UITableViewCell { 12 | 13 | @IBOutlet weak var Label: UILabel! 14 | @IBOutlet weak var colorTag: UIView! 15 | 16 | var tagColor = 0 { 17 | didSet { 18 | switch tagColor { 19 | case 0: 20 | colorTag.backgroundColor = colorRed 21 | colorTag.accessibilityLabel = NSLocalizedString("Red color tag",comment:"Red color tag") 22 | case 1: 23 | colorTag.backgroundColor = colorYellow 24 | colorTag.accessibilityLabel = NSLocalizedString("Yellow color tag",comment:"Yellow color tag") 25 | case 2: 26 | colorTag.backgroundColor = colorBlue 27 | colorTag.accessibilityLabel = NSLocalizedString("Blue color tag",comment:"Blue color tag") 28 | case 3: 29 | colorTag.backgroundColor = colorPurple 30 | colorTag.accessibilityLabel = NSLocalizedString("Purple color tag",comment:"Purple color tag") 31 | case 4: 32 | colorTag.backgroundColor = colorGray 33 | colorTag.accessibilityLabel = NSLocalizedString("Gray color tag",comment:"Gray color tag") 34 | default:break 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/LiveUseful.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.liveuseful 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/OmakeViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OmakeViewController.swift 3 | // LiveUseful 4 | // 5 | // Created by 孟金羽 on 2019/02/09. 6 | // Copyright © 2019 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class OmakeViewController: UIViewController { 12 | @IBOutlet weak var imageView: UIImageView! 13 | 14 | @IBAction func back(_ sender: Any) { 15 | tapticGenerator.impactOccurred() 16 | dismiss(animated: true, completion: {}) 17 | } 18 | 19 | @IBAction func save(_ sender: Any) { 20 | tapticGenerator.impactOccurred() 21 | let activityViewController = UIActivityViewController(activityItems: [imageView.image!] as [Any], applicationActivities: nil) 22 | activityViewController.popoverPresentationController?.sourceView = self.view 23 | self.present(activityViewController, animated: true, completion: nil) 24 | } 25 | 26 | override func viewDidLoad() { 27 | super.viewDidLoad() 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/QRView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // QRView.swift 3 | // LiveUseful 4 | // 5 | // Created by Megabits on 2018/6/16. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol QRViewDelegate: class { 12 | func removeItem(id: Int) 13 | func editItem(id: Int) 14 | } 15 | 16 | class QRView: UIView { 17 | var qrImage: UIImage? = nil { 18 | didSet{ 19 | qrImageView.image = qrImage 20 | } 21 | } 22 | var id = 0 { 23 | didSet{ 24 | tapToEditLabel.text = NSLocalizedString("Edit", comment: "Edit") + ",ID\(id)" 25 | removeButton.accessibilityLabel = NSLocalizedString("Remove", comment: "Remove") + ",ID\(id)" 26 | } 27 | } 28 | 29 | private var tapToEditLabel = UILabel() 30 | private var bgImageView = UIImageView(frame: CGRect.zero) 31 | private var qrImageView = UIImageView(frame: CGRect.zero) 32 | private var removeButton = UIButton(frame: CGRect.zero) 33 | private var tapGestureRecognizer: UITapGestureRecognizer! 34 | 35 | weak var delegate: QRViewDelegate? 36 | 37 | init(frame: CGRect, qrImage: UIImage) { 38 | super.init(frame: frame) 39 | self.qrImage = qrImage 40 | 41 | backgroundColor = .clear 42 | isOpaque = false 43 | isUserInteractionEnabled = true 44 | shouldGroupAccessibilityChildren = true 45 | 46 | let squareLayout = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 1, constant: 1) 47 | addConstraint(squareLayout) 48 | 49 | //Focus for VoiceOver 50 | tapToEditLabel.text = NSLocalizedString("Edit", comment: "Edit") + ",ID\(id)" 51 | addSubview(tapToEditLabel) 52 | 53 | //White square 54 | bgImageView.backgroundColor = .clear 55 | bgImageView.image = #imageLiteral(resourceName: "QRBackground") 56 | bgImageView.contentMode = .scaleAspectFill 57 | addSubview(bgImageView) 58 | 59 | //QR image 60 | qrImageView.image = qrImage 61 | qrImageView.isUserInteractionEnabled = true 62 | tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(edit)) 63 | qrImageView.addGestureRecognizer(tapGestureRecognizer) 64 | addSubview(qrImageView) 65 | 66 | //Remove button 67 | removeButton.setImage(#imageLiteral(resourceName: "Remove"), for: .normal) 68 | removeButton.addTarget(self, action: #selector(remove), for: .touchUpInside) 69 | removeButton.accessibilityLabel = NSLocalizedString("Remove", comment: "Remove") + ",ID\(id)" 70 | addSubview(removeButton) 71 | } 72 | 73 | required init?(coder aDecoder: NSCoder) { 74 | fatalError("init(coder:) has not been implemented") 75 | } 76 | 77 | override func draw(_ rect: CGRect) { 78 | tapToEditLabel.frame = CGRect(x: 30, y: 30, width: frame.width - 60, height: frame.width - 60) 79 | bgImageView.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.width) 80 | qrImageView.frame = CGRect(x: frame.width * 0.125, y: frame.width * 0.125, width: frame.width * 0.75, height: frame.width * 0.75) 81 | removeButton.frame = CGRect(x: frame.width * 0.77, y: frame.width * 0.03, width: frame.width * 0.2, height: frame.width * 0.2) 82 | } 83 | 84 | @objc func edit() { 85 | self.delegate?.editItem(id: self.id) 86 | } 87 | 88 | @objc func remove() { 89 | UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: { 90 | self.alpha = 0 91 | }, completion: { (finished: Bool) in 92 | self.delegate?.removeItem(id: self.id) 93 | }) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/ScanQRViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScanQRViewController.swift 3 | // LiveUseful 4 | // 5 | // Created by Megabits on 2018/1/21. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import AVFoundation 11 | 12 | protocol QRScannerDelegate: class { 13 | func getResultFromQRScanner(_ qrContent: String) 14 | } 15 | 16 | class ScanQRViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate { 17 | 18 | @IBOutlet var toolsBackgroundView: UIView! 19 | @IBOutlet var backButton: UIButton! 20 | @IBOutlet var openImageButton: UIButton! 21 | @IBOutlet var alertBackground: UIVisualEffectView! 22 | @IBOutlet var alertView: UIView! 23 | @IBOutlet var errorLabel: UILabel! 24 | 25 | //Prepare 26 | var captureSession = AVCaptureSession() 27 | var videoPreviewLayer: AVCaptureVideoPreviewLayer? 28 | var qrCodeFrameView: UIView? 29 | let supportedCodeTypes = [ 30 | AVMetadataObject.ObjectType.upce, 31 | AVMetadataObject.ObjectType.code39, 32 | AVMetadataObject.ObjectType.code39Mod43, 33 | AVMetadataObject.ObjectType.code93, 34 | AVMetadataObject.ObjectType.code128, 35 | AVMetadataObject.ObjectType.ean8, 36 | AVMetadataObject.ObjectType.ean13, 37 | AVMetadataObject.ObjectType.aztec, 38 | AVMetadataObject.ObjectType.pdf417, 39 | AVMetadataObject.ObjectType.itf14, 40 | AVMetadataObject.ObjectType.dataMatrix, 41 | AVMetadataObject.ObjectType.interleaved2of5, 42 | AVMetadataObject.ObjectType.qr 43 | ] 44 | 45 | let imagePicker = UIImagePickerController() 46 | 47 | weak var delegate: QRScannerDelegate? 48 | 49 | @IBAction func cancel(_ sender: Any) { 50 | self.dismiss(animated: true, completion: {}) 51 | } 52 | 53 | @IBAction func openImage(_ sender: Any) { 54 | self.present(imagePicker, animated: true, completion: { 55 | () -> Void in 56 | }) 57 | } 58 | 59 | override func viewDidLoad() { 60 | super.viewDidLoad() 61 | 62 | imagePicker.delegate = self 63 | imagePicker.sourceType = .photoLibrary 64 | imagePicker.allowsEditing = true 65 | imagePicker.preferredContentSize = UIScreen.main.bounds.size 66 | imagePicker.modalTransitionStyle = .crossDissolve 67 | alertBackground.effect = .none 68 | 69 | backButton.accessibilityLabel = NSLocalizedString("Back", comment: "Back") 70 | 71 | //Camera session 72 | let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back) 73 | guard let captureDevice = deviceDiscoverySession.devices.first else { 74 | print("No camera") 75 | return 76 | } 77 | 78 | do { 79 | let input = try AVCaptureDeviceInput(device: captureDevice) 80 | captureSession.addInput(input) 81 | let captureMetadataOutput = AVCaptureMetadataOutput() 82 | captureSession.addOutput(captureMetadataOutput) 83 | captureMetadataOutput.setMetadataObjectsDelegate(self , queue: DispatchQueue.main) 84 | captureMetadataOutput.metadataObjectTypes = supportedCodeTypes 85 | } catch { 86 | //No permissions 87 | print(error) 88 | errorLabel.isHidden = false 89 | return 90 | } 91 | 92 | //Start capture 93 | videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 94 | videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill 95 | videoPreviewLayer?.frame = view.layer.bounds 96 | view.layer.addSublayer(videoPreviewLayer!) 97 | 98 | captureSession.startRunning() 99 | 100 | //Bring other views to front 101 | view.bringSubviewToFront(toolsBackgroundView) 102 | view.bringSubviewToFront(alertBackground) 103 | 104 | qrCodeFrameView = UIView() 105 | 106 | //Mark the QR code with a square 107 | if let qrCodeFrameView = qrCodeFrameView { 108 | qrCodeFrameView.layer.borderColor = UIColor.green.cgColor 109 | qrCodeFrameView.layer.borderWidth = 2 110 | view.addSubview(qrCodeFrameView) 111 | view.bringSubviewToFront(qrCodeFrameView) 112 | } 113 | } 114 | 115 | override func viewWillDisappear(_ animated: Bool) { 116 | tapticGenerator.impactOccurred() 117 | super.viewWillDisappear(animated) 118 | } 119 | 120 | override var prefersHomeIndicatorAutoHidden: Bool { 121 | return true 122 | } 123 | 124 | override func accessibilityPerformEscape() -> Bool { 125 | cancel(self) 126 | return true 127 | } 128 | 129 | func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { 130 | let image = info[UIImagePickerController.InfoKey.editedImage] as! UIImage 131 | picker.dismiss(animated: false, completion: { 132 | () -> Void in 133 | let qrString = self.readQRImage(image) 134 | if qrString != "" { 135 | self.delegate?.getResultFromQRScanner(qrString) 136 | self.dismiss(animated: true, completion: {}) 137 | } 138 | }) 139 | } 140 | 141 | func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { 142 | if metadataObjects.count == 0 { 143 | qrCodeFrameView?.frame = CGRect.zero 144 | return 145 | } 146 | let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject 147 | if supportedCodeTypes.contains(metadataObj.type) { 148 | let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj) 149 | qrCodeFrameView?.frame = barCodeObject!.bounds 150 | 151 | //QR code found 152 | if metadataObj.stringValue != nil { 153 | self.delegate?.getResultFromQRScanner(metadataObj.stringValue!) 154 | self.dismiss(animated: true, completion: {}) 155 | 156 | } 157 | } 158 | } 159 | 160 | func readQRImage(_ image:UIImage) -> String{ 161 | let ciImage: CIImage = CIImage(image: image)! 162 | let context = CIContext(options: nil) 163 | let detector: CIDetector = CIDetector(ofType: CIDetectorTypeQRCode, context: context, options: [CIDetectorAccuracy:CIDetectorAccuracyHigh])! 164 | let features = detector.features(in: ciImage) 165 | //Use the last one 166 | var stringValue: String = "" 167 | if features.count != 0 { 168 | for feature in features as! [CIQRCodeFeature] { 169 | if feature.messageString != "" { 170 | stringValue = feature.messageString! 171 | } 172 | } 173 | } else { 174 | tapticGenerator.impactOccurred() 175 | UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: { 176 | self.alertBackground.effect = UIBlurEffect(style: .extraLight) 177 | self.alertView.alpha = 1 178 | }, completion: { (finished: Bool) in 179 | UIView.animate(withDuration: 0.3, delay: 0.5, options: .curveEaseOut, animations: { 180 | self.alertBackground.effect = .none 181 | self.alertView.alpha = 0 182 | }, completion: { (finished: Bool) in 183 | UIAccessibility.post(notification: UIAccessibility.Notification.announcement, argument: NSLocalizedString("QR Code Not Found", comment: "QR Code Not Found")) 184 | }) 185 | }) 186 | } 187 | return stringValue 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/SeeItViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SeeItViewController.swift 3 | // LiveUseful 4 | // 5 | // Created by Megabits on 2018/2/15. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SeeItViewController: UIViewController { 12 | 13 | @IBOutlet var okButton: UIButton! 14 | @IBOutlet var timerLabel: UILabel! 15 | @IBOutlet var iSeeButton: UIButton! 16 | 17 | var timer: Timer? 18 | var timeRemaining = 5 19 | 20 | @IBAction func ok(_ sender: Any) { 21 | dismiss() 22 | } 23 | 24 | @IBAction func iSee(_ sender: Any) { 25 | UserDefaults.standard.set(true, forKey: "isSeeItBanned") 26 | dismiss() 27 | } 28 | 29 | func dismiss() { 30 | livePhotoBuilder.save() 31 | isSeeItBanned = true 32 | tapticGenerator.impactOccurred() 33 | self.dismiss(animated: true, completion: {}) 34 | } 35 | 36 | override func viewDidLoad() { 37 | super.viewDidLoad() 38 | okButton.setBackgroundImage(UIImage(color:UIColor.black,size:okButton.frame.size), for: .normal) 39 | timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true) 40 | } 41 | 42 | override var prefersHomeIndicatorAutoHidden: Bool { 43 | return true 44 | } 45 | 46 | @objc func updateTimer() { 47 | timeRemaining -= 1 48 | timerLabel.text = "\(timeRemaining)s" 49 | if timeRemaining == 0 { 50 | timer?.invalidate() 51 | timer = nil 52 | okButton.isEnabled = true 53 | iSeeButton.isEnabled = true 54 | timerLabel.isHidden = true 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/StartViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // UsefulLive 4 | // 5 | // Created by Megabits on 2017/9/30. 6 | // Copyright © 2017 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | 12 | class StartViewController: UIViewController, UIScrollViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate { 13 | @IBOutlet var cantSaveImageTip: UIVisualEffectView! 14 | @IBOutlet var openPhotoView: UIView! 15 | @IBOutlet var openPhotoButton: UIButton! 16 | @IBOutlet var useLastPhotoButton: UIButton! 17 | @IBOutlet weak var importAlertView: UIView! 18 | 19 | let imagePicker = UIImagePickerController() 20 | var omakeCount = 0 21 | 22 | @IBAction func removeImport(_ sender: Any) { 23 | importType = nil 24 | importAlertView.isHidden = true 25 | } 26 | 27 | @IBAction func showOmake(_ sender: Any) { 28 | omakeCount += 1 29 | if omakeCount == 9 { 30 | omakeCount = 0 31 | performSegue(withIdentifier: "toOmake", sender: self) 32 | } 33 | } 34 | 35 | @IBAction func openSettings(_ sender: Any) { 36 | if let url = URL(string: UIApplication.openSettingsURLString) { 37 | UIApplication.shared.open(url) 38 | } 39 | } 40 | 41 | @IBAction func selectImage(_ sender: Any) { 42 | tapticGenerator.impactOccurred() 43 | self.present(imagePicker, animated: true, completion: { 44 | () -> Void in 45 | }) 46 | } 47 | 48 | @IBAction func useLastPhoto(_ sender: Any) { 49 | isUsingLastImage = true 50 | performSegue(withIdentifier: "toEditDirect", sender: self) 51 | } 52 | 53 | override func viewDidLoad() { 54 | super.viewDidLoad() 55 | 56 | //Set output size 57 | targetSize = CGSize(width: view.frame.width * 1.5, height: view.frame.height * 1.5) 58 | 59 | imagePicker.delegate = self 60 | imagePicker.sourceType = .photoLibrary 61 | imagePicker.allowsEditing = false 62 | imagePicker.preferredContentSize = UIScreen.main.bounds.size 63 | imagePicker.modalTransitionStyle = .crossDissolve 64 | 65 | openPhotoButton.setBackgroundImage(UIImage(color:UIColor.black,size:openPhotoButton.frame.size), for: .normal) 66 | 67 | startViewController = self 68 | 69 | NotificationCenter.default.addObserver(self, selector: #selector(becomeActive), name: UIApplication.didBecomeActiveNotification, object: nil) 70 | } 71 | 72 | override func viewWillAppear(_ animated: Bool) { 73 | super.viewDidAppear(animated) 74 | becomeActive() 75 | if isTutorialsReaded == true { 76 | getAuthorization() 77 | } else { 78 | performSegue(withIdentifier: "showTutorials", sender: self) 79 | } 80 | } 81 | 82 | override func accessibilityPerformMagicTap() -> Bool { 83 | if useLastPhotoButton.isEnabled == true { 84 | useLastPhoto(self) 85 | } else { 86 | selectImage(self) 87 | } 88 | return true 89 | } 90 | 91 | @objc func becomeActive() { 92 | if importType != nil { 93 | importAlertView.isHidden = false 94 | } else { 95 | importAlertView.isHidden = true 96 | } 97 | } 98 | 99 | func getAuthorization() { 100 | let authStatus = PHPhotoLibrary.authorizationStatus() 101 | if authStatus == .notDetermined { 102 | PHPhotoLibrary.requestAuthorization { (status:PHAuthorizationStatus) -> Void in 103 | if status != .authorized { 104 | DispatchQueue.main.async { 105 | self.cantSaveImageTip.isHidden = false 106 | self.openPhotoView.isHidden = true 107 | } 108 | } 109 | } 110 | } else if authStatus == .authorized { 111 | cantSaveImageTip.isHidden = true 112 | openPhotoView.isHidden = false 113 | //Get the background image saved last time 114 | if let lastPhoto = UIImage(contentsOfFile: documentsPath + "/last.jpg") { 115 | self.useLastPhotoButton.isEnabled = true 116 | croppedImage = lastPhoto 117 | } 118 | } else { 119 | cantSaveImageTip.isHidden = false 120 | openPhotoView.isHidden = true 121 | } 122 | } 123 | 124 | func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { 125 | let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage 126 | origenalImage = image 127 | picker.dismiss(animated: false, completion: { 128 | () -> Void in 129 | }) 130 | 131 | //fix picker animation 132 | let snapshotView = picker.view.snapshotView(afterScreenUpdates: true)! 133 | view.addSubview(snapshotView) 134 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { 135 | snapshotView.removeFromSuperview() 136 | } 137 | performSegue(withIdentifier: "toCrop", sender: self) 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/TutorialsViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TutorialsViewController.swift 3 | // LiveUseful 4 | // 5 | // Created by Megabits on 2018/2/1. 6 | // Copyright © 2018 Jinyu Meng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TutorialsViewController: UIViewController { 12 | 13 | 14 | @IBOutlet var image1: UIImageView! 15 | @IBOutlet var image2: UIImageView! 16 | @IBOutlet var image3: UIImageView! 17 | @IBOutlet var image4: UIImageView! 18 | @IBOutlet var mask: UIView! 19 | @IBOutlet var bigText: UILabel! 20 | @IBOutlet var smallText: UILabel! 21 | @IBOutlet var nextPage: UIButton! 22 | @IBOutlet var prevPage: UIButton! 23 | @IBOutlet var swipePrev: UISwipeGestureRecognizer! 24 | @IBOutlet var swipeNext: UISwipeGestureRecognizer! 25 | 26 | var page = 0 { 27 | didSet{ 28 | switch page { 29 | case 0: 30 | bigText.text = NSLocalizedString("AD 1 Title", comment: "AD 1 Title") 31 | smallText.text = NSLocalizedString("AD 1 Subtitle", comment: "AD 1 Subtitle") 32 | UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseIn, animations: { 33 | if !isTutorialsReaded { 34 | self.prevPage.alpha = 0 35 | self.swipePrev.isEnabled = false 36 | } 37 | self.image2.alpha = 0 38 | }) 39 | case 1: 40 | bigText.text = NSLocalizedString("AD 2 Title", comment: "AD 2 Title") 41 | smallText.text = "" 42 | UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseIn, animations: { 43 | self.prevPage.alpha = 1 44 | self.swipePrev.isEnabled = true 45 | self.image2.alpha = 1 46 | self.mask.alpha = 0 47 | }) 48 | case 2: 49 | bigText.text = NSLocalizedString("AD 3 Title", comment: "AD 3 Title") 50 | smallText.text = "" 51 | UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseIn, animations: { 52 | self.mask.alpha = 1 53 | self.image4.alpha = 0 54 | }) 55 | case 3: 56 | bigText.text = NSLocalizedString("AD 4 Title", comment: "AD 4 Title") 57 | smallText.text = "" 58 | UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseIn, animations: { 59 | self.image4.alpha = 1 60 | }) 61 | default: 62 | if page < 0 { 63 | page = 0 64 | if isTutorialsReaded { 65 | dismiss(animated: true, completion: {}) 66 | } 67 | } else { //case >3 68 | isTutorialsReaded = true 69 | dismiss(animated: true, completion: {}) 70 | } 71 | } 72 | } 73 | } 74 | 75 | @IBAction func nextPage(_ sender: Any) { 76 | nextPage.isEnabled = false 77 | prevPage.isEnabled = false 78 | UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: bigText) 79 | UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseOut, animations: { 80 | self.bigText.alpha = 0 81 | self.smallText.alpha = 0 82 | }, completion: { (finished: Bool) in 83 | self.page += 1 84 | }) 85 | UIView.animate(withDuration: 0.3, delay: 0.2, options: .curveEaseIn, animations: { 86 | self.bigText.alpha = 1 87 | self.smallText.alpha = 1 88 | }, completion: { (finished: Bool) in 89 | self.nextPage.isEnabled = true 90 | self.prevPage.isEnabled = true 91 | }) 92 | } 93 | 94 | @IBAction func prevPage(_ sender: Any) { 95 | nextPage.isEnabled = false 96 | prevPage.isEnabled = false 97 | UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: bigText) 98 | UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseOut, animations: { 99 | self.bigText.alpha = 0 100 | self.smallText.alpha = 0 101 | }, completion: { (finished: Bool) in 102 | self.page -= 1 103 | }) 104 | UIView.animate(withDuration: 0.3, delay: 0.2, options: .curveEaseIn, animations: { 105 | self.bigText.alpha = 1 106 | self.smallText.alpha = 1 107 | }, completion: { (finished: Bool) in 108 | self.nextPage.isEnabled = true 109 | self.prevPage.isEnabled = true 110 | }) 111 | 112 | } 113 | 114 | override func viewDidLoad() { 115 | if isTutorialsReaded { 116 | self.prevPage.alpha = 1 117 | self.swipePrev.isEnabled = true 118 | } 119 | page = 0 //Refresh button state 120 | } 121 | 122 | override func accessibilityPerformEscape() -> Bool { 123 | if isTutorialsReaded { 124 | dismiss(animated: true, completion: {}) 125 | } 126 | return true 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Accessibility Warning Message */ 2 | "Accessibility Warning Message" = "A Live Photo containing multiple QR-Codes may be difficult to use for the visually impaired."; 3 | 4 | /* AD 1 Title */ 5 | "AD 1 Title" = "Welcome to LiveUseful!\nHide text, list, image and QR code in your lock screen wallpaper."; 6 | 7 | /* AD 1 Subtitle */ 8 | "AD 1 Subtitle" = "Only show them when you press the screen."; 9 | 10 | /* AD 2 Title */ 11 | "AD 2 Title" = "Change card style, font size and text-alignment."; 12 | 13 | /* AD 3 Title */ 14 | "AD 3 Title" = "Scan from the camera or an image when adding QR code."; 15 | 16 | /* AD 4 Title */ 17 | "AD 4 Title" = "Add an Image. Use your imagination, lock screen can do anything."; 18 | 19 | "Move QR Tip" = "Double-tap and hold to move QR code up and down."; 20 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/ja.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleDisplayName" = "マジックロック"; 3 | 4 | /* Privacy - Camera Usage Description */ 5 | "NSCameraUsageDescription" = "QR コードをスキャンしてインポートします。"; 6 | 7 | /* Privacy - Photo Library Usage Description */ 8 | "NSPhotoLibraryUsageDescription" = "Live Photo をカメラロールに保存します。"; 9 | 10 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/ja.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Accessibility Warning */ 2 | "Accessibility Warning" = "アクセシビリティ警告"; 3 | 4 | /* Accessibility Warning Message */ 5 | "Accessibility Warning Message" = "複数の QR コードを持つ Live Photo は、目の不自由な人が使う出来ない場合ありますので、ご注意下さい。"; 6 | 7 | /* AD 1 Subtitle */ 8 | "AD 1 Subtitle" = "画面を押すときにのみ表示します。"; 9 | 10 | /* AD 1 Title */ 11 | "AD 1 Title" = "マジックロック へようこそ!\nロック画面の壁紙にテキスト、リスト、画像、QRコードを隠すためのアプリです。"; 12 | 13 | /* AD 2 Title */ 14 | "AD 2 Title" = "カードのスタイル、フォントサイズ、テキストの配置を変更することができます。"; 15 | 16 | /* AD 3 Title */ 17 | "AD 3 Title" = "QR コードを追加するときは、カメラまたは画像からスキャンすることができます。"; 18 | 19 | /* AD 4 Title */ 20 | "AD 4 Title" = "あなたの想像力次第、画像を追加し、ロック画面は沢山のことができます。"; 21 | 22 | /* Add New Item */ 23 | "Add New Item" = "項目の追加"; 24 | 25 | /* Back */ 26 | "Back" = "戻る"; 27 | 28 | /* Background blur */ 29 | "Background blur" = "背景をぼやける"; 30 | 31 | /* Big */ 32 | "Big" = "大きい"; 33 | 34 | /* Blue color tag */ 35 | "Blue color tag" = "青いタグ"; 36 | 37 | /* Cancel */ 38 | "Cancel" = "キャンセル"; 39 | 40 | /* Card Style */ 41 | "Card Style" = "カードスタイル"; 42 | 43 | /* Center */ 44 | "Center" = "中央揃え"; 45 | 46 | /* Dark */ 47 | "Dark" = "黒い"; 48 | 49 | /* Edit */ 50 | "Edit" = "編集"; 51 | 52 | /* Extra light */ 53 | "Extra light" = "白い"; 54 | 55 | /* Gray color tag */ 56 | "Gray color tag" = "グレータグ"; 57 | 58 | /* Hide keyboard */ 59 | "Hide keyboard" = "キーボードを非表示"; 60 | 61 | /* Input some text here. */ 62 | "Input some text here." = "テキストを入力してください。"; 63 | 64 | /* Input text or URL here. */ 65 | "Input text or URL here." = "テキストまたは URL を入力してください。"; 66 | 67 | /* Input title here (Optional). */ 68 | "Input title here (Optional)." = "タイトルを入力して下さい(オプション)。"; 69 | 70 | /* Justified */ 71 | "Justified" = "両端揃え"; 72 | 73 | /* Left */ 74 | "Left" = "左揃え"; 75 | 76 | /* Light */ 77 | "Light" = "透明と白い"; 78 | 79 | /* Move QR Tip */ 80 | "Move QR Tip" = "QRコードを垂直方向に移動するには、ダブルタップして押さえたままに指を移動してください。"; 81 | 82 | /* OK */ 83 | "OK" = "OK"; 84 | 85 | /* Open photos */ 86 | "Open photos" = "写真を開く"; 87 | 88 | /* Purple color tag */ 89 | "Purple color tag" = "紫タグ"; 90 | 91 | /* QR Code Not Found */ 92 | "QR Code Not Found" = "QR コードが見つかりません"; 93 | 94 | /* QR size */ 95 | "QR size" = "QR コードサーズ"; 96 | 97 | /* Red color tag */ 98 | "Red color tag" = "赤いタグ"; 99 | 100 | /* Remove */ 101 | "Remove" = "削除"; 102 | 103 | /* Right */ 104 | "Right" = "右揃え"; 105 | 106 | /* Scale to fill */ 107 | "Scale to fill" = "拡大サイズ"; 108 | 109 | /* Scale to fit */ 110 | "Scale to fit" = "フィットサイズ"; 111 | 112 | /* Set Maximum Font Size */ 113 | "Set Maximum Font Size" = "最大フォントサイズ"; 114 | 115 | /* Small */ 116 | "Small" = "小さい"; 117 | 118 | /* Text alignment */ 119 | "Text alignment" = "テキストの配置"; 120 | 121 | /* Yellow color tag */ 122 | "Yellow color tag" = "黄色のタグ"; 123 | 124 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleDisplayName" = "神奇锁屏"; 3 | 4 | /* Privacy - Camera Usage Description */ 5 | "NSCameraUsageDescription" = "扫描导入二维码。"; 6 | 7 | /* Privacy - Photo Library Usage Description */ 8 | "NSPhotoLibraryUsageDescription" = "保存 Live Photo 到照片库。"; 9 | 10 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Accessibility Warning */ 2 | "Accessibility Warning" = "无障碍提示"; 3 | 4 | /* Accessibility Warning Message */ 5 | "Accessibility Warning Message" = "带有多个二维码的 Live Photo 可能很难在看不到屏幕的状态下使用。"; 6 | 7 | /* AD 1 Subtitle */ 8 | "AD 1 Subtitle" = "只会在你用力按屏幕时显示出来。"; 9 | 10 | /* AD 1 Title */ 11 | "AD 1 Title" = "欢迎使用 神奇锁屏!\n在锁屏壁纸中隐藏文字、列表、图片和二维码。"; 12 | 13 | /* AD 2 Title */ 14 | "AD 2 Title" = "设置卡片样式、文字大小及对齐。"; 15 | 16 | /* AD 3 Title */ 17 | "AD 3 Title" = "添加二维码时从相机或图片扫描。"; 18 | 19 | /* AD 4 Title */ 20 | "AD 4 Title" = "添加图片。发挥你的想象力,你的锁屏壁纸潜力无限。"; 21 | 22 | /* Add New Item */ 23 | "Add New Item" = "添加项目"; 24 | 25 | /* Back */ 26 | "Back" = "返回"; 27 | 28 | /* Background blur */ 29 | "Background blur" = "背景虚化"; 30 | 31 | /* Big */ 32 | "Big" = "大"; 33 | 34 | /* Blue color tag */ 35 | "Blue color tag" = "蓝色标签"; 36 | 37 | /* Cancel */ 38 | "Cancel" = "取消"; 39 | 40 | /* Card Style */ 41 | "Card Style" = "卡片样式"; 42 | 43 | /* Center */ 44 | "Center" = "居中对齐"; 45 | 46 | /* Dark */ 47 | "Dark" = "暗色"; 48 | 49 | /* Edit */ 50 | "Edit" = "编辑"; 51 | 52 | /* Extra light */ 53 | "Extra light" = "亮色"; 54 | 55 | /* Gray color tag */ 56 | "Gray color tag" = "灰色标签"; 57 | 58 | /* Hide keyboard */ 59 | "Hide keyboard" = "隐藏键盘"; 60 | 61 | /* Input some text here. */ 62 | "Input some text here." = "在这里输入一些文字。"; 63 | 64 | /* Input text or URL here. */ 65 | "Input text or URL here." = "在这里输入文字或链接。"; 66 | 67 | /* Input title here (Optional). */ 68 | "Input title here (Optional)." = "在这里输入标题(可选)。"; 69 | 70 | /* Justified */ 71 | "Justified" = "两端对齐"; 72 | 73 | /* Left */ 74 | "Left" = "左对齐"; 75 | 76 | /* Light */ 77 | "Light" = "较亮"; 78 | 79 | /* Move QR Tip */ 80 | "Move QR Tip" = "轻点两下并按住以上下移动二维码。"; 81 | 82 | /* OK */ 83 | "OK" = "确定"; 84 | 85 | /* Open photos */ 86 | "Open photos" = "打开图片"; 87 | 88 | /* Purple color tag */ 89 | "Purple color tag" = "紫色标签"; 90 | 91 | /* QR Code Not Found */ 92 | "QR Code Not Found" = "没有找到二维码"; 93 | 94 | /* QR size */ 95 | "QR size" = "二维码尺寸"; 96 | 97 | /* Red color tag */ 98 | "Red color tag" = "红色标签"; 99 | 100 | /* Remove */ 101 | "Remove" = "移除"; 102 | 103 | /* Right */ 104 | "Right" = "右对齐"; 105 | 106 | /* Scale to fill */ 107 | "Scale to fill" = "放大填充"; 108 | 109 | /* Scale to fit */ 110 | "Scale to fit" = "适合大小"; 111 | 112 | /* Set Maximum Font Size */ 113 | "Set Maximum Font Size" = "选择最大字号"; 114 | 115 | /* Small */ 116 | "Small" = "小"; 117 | 118 | /* Text alignment */ 119 | "Text alignment" = "对齐方式"; 120 | 121 | /* Yellow color tag */ 122 | "Yellow color tag" = "黄色标签"; 123 | 124 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/zh-Hant.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleDisplayName" = "神奇鎖屏"; 3 | 4 | /* Privacy - Camera Usage Description */ 5 | "NSCameraUsageDescription" = "掃描匯入二維碼。"; 6 | 7 | /* Privacy - Photo Library Usage Description */ 8 | "NSPhotoLibraryUsageDescription" = "保存 Live Photo 到照片庫。"; 9 | 10 | -------------------------------------------------------------------------------- /LiveUseful/LiveUseful/zh-Hant.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* Accessibility Warning */ 2 | "Accessibility Warning" = "無障礙提示"; 3 | 4 | /* Accessibility Warning Message */ 5 | "Accessibility Warning Message" = "帶有多個二維碼的 Live Photo 可能很難在看不到螢幕的狀態下使用。"; 6 | 7 | /* AD 1 Subtitle */ 8 | "AD 1 Subtitle" = "只會在你用力按螢幕時顯示出來。"; 9 | 10 | /* AD 1 Title */ 11 | "AD 1 Title" = "歡迎使用神奇鎖屏!\n在鎖屏壁紙中隱藏文字、列表、圖片和二維碼。"; 12 | 13 | /* AD 2 Title */ 14 | "AD 2 Title" = "設置卡片樣式、文字大小及對齊。"; 15 | 16 | /* AD 3 Title */ 17 | "AD 3 Title" = "添加二維碼時從相機或圖片掃描。"; 18 | 19 | /* AD 4 Title */ 20 | "AD 4 Title" = "添加圖片。發揮你的想象力,你的鎖定畫面潛力無限。"; 21 | 22 | /* Add New Item */ 23 | "Add New Item" = "添加項目"; 24 | 25 | /* Back */ 26 | "Back" = "返回"; 27 | 28 | /* Background blur */ 29 | "Background blur" = "背景虛化"; 30 | 31 | /* Big */ 32 | "Big" = "大"; 33 | 34 | /* Blue color tag */ 35 | "Blue color tag" = "藍色標籤"; 36 | 37 | /* Cancel */ 38 | "Cancel" = "取消"; 39 | 40 | /* Card Style */ 41 | "Card Style" = "卡片樣式"; 42 | 43 | /* Center */ 44 | "Center" = "居中對齊"; 45 | 46 | /* Dark */ 47 | "Dark" = "暗色"; 48 | 49 | /* Edit */ 50 | "Edit" = "編輯"; 51 | 52 | /* Extra light */ 53 | "Extra light" = "亮色"; 54 | 55 | /* Gray color tag */ 56 | "Gray color tag" = "灰色標籤"; 57 | 58 | /* Hide keyboard */ 59 | "Hide keyboard" = "隱藏鍵盤"; 60 | 61 | /* Input some text here. */ 62 | "Input some text here." = "在這裡輸入一些文字。"; 63 | 64 | /* Input text or URL here. */ 65 | "Input text or URL here." = "在這裡輸入文字或連結。"; 66 | 67 | /* Input title here (Optional). */ 68 | "Input title here (Optional)." = "在這裡輸入標題(可選)。"; 69 | 70 | /* Justified */ 71 | "Justified" = "兩端對齊"; 72 | 73 | /* Left */ 74 | "Left" = "左對齊"; 75 | 76 | /* Light */ 77 | "Light" = "較亮"; 78 | 79 | /* Move QR Tip */ 80 | "Move QR Tip" = "輕點兩下並按住以上下移動二維碼。"; 81 | 82 | /* OK */ 83 | "OK" = "確定"; 84 | 85 | /* Open photos */ 86 | "Open photos" = "打開圖片"; 87 | 88 | /* Purple color tag */ 89 | "Purple color tag" = "紫色標籤"; 90 | 91 | /* QR Code Not Found */ 92 | "QR Code Not Found" = "沒有找到二維碼"; 93 | 94 | /* QR size */ 95 | "QR size" = "二維碼尺寸"; 96 | 97 | /* Red color tag */ 98 | "Red color tag" = "紅色標籤"; 99 | 100 | /* Remove */ 101 | "Remove" = "移除"; 102 | 103 | /* Right */ 104 | "Right" = "右對齊"; 105 | 106 | /* Scale to fill */ 107 | "Scale to fill" = "放大填充"; 108 | 109 | /* Scale to fit */ 110 | "Scale to fit" = "適合大小"; 111 | 112 | /* Set Maximum Font Size */ 113 | "Set Maximum Font Size" = "選擇最大字號"; 114 | 115 | /* Small */ 116 | "Small" = "小"; 117 | 118 | /* Text alignment */ 119 | "Text alignment" = "對齊方式"; 120 | 121 | /* Yellow color tag */ 122 | "Yellow color tag" = "黃色標籤"; 123 | 124 | -------------------------------------------------------------------------------- /Preview.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/Preview.jpeg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LiveUseful - Make your lock screen useful! 2 | ![Use for iOS](https://img.shields.io/badge/platform-iOS-green.svg) [![Made with Swift](https://img.shields.io/badge/language-swift4.0-orange.svg)](https://github.com/apple/swift) [![Use MIT license](https://img.shields.io/badge/license-MIT¿-blue.svg)](https://opensource.org/licenses/MIT) 3 | 4 | ![](Preview.jpeg) 5 | 6 | ## About 7 | 8 | LiveUseful is the first universal tool that inserts various hidden information into a Live Photo. Use these Live Photos, you can hide important things in your lock screen, and show them with 3D Touch. 9 | 10 | See more details on App Store: [LiveUseful - Make your lock screen useful!](https://itunes.apple.com/us/app/id1329941178) 11 | 12 | There are some apps in the App Store copied my idea(a universal tool that inserts various hidden information into a Live Photo). I have killed some of them, but there are still some apps I can't take them off. Even Apple now decide not to reply to any mail from me. I really have no idea, so I decide to make my app opensource. I hope you can use my code to make a unique lock screen card for your app, or just run my code and have fun. ^_^ 13 | 14 | ## About the code 15 | 16 | The core of LiveUseful is Live Photo。The App takes a screenshot of the view, then make a video from this image contain only one frame. Convert this video to Live Photo with a cover image as the background. When you press the screen with 3D Touch, it will start to play the video, display the image with hidden content. Because Live Photo has a built-in fade animation, the process will be very smooth. 17 | 18 | A Live Photo is made from two parts: a JPEG image and a QuickTime video. You need to generate them separately then combine them as a Live Photo. And you also need to add some metadata to the files in order to join them together. 19 | 20 | ### Take screenshots 21 | 22 | The video will be generated from a screenshot of the snapshotView. This view containing the background image and a card view above it. 23 | 24 | To make this screenshot, you need to make a UIGraphicsImageContext. With drawHierarchy() function, you can get a screenshot of a view and ignore anything above it. In this case, I want the editing tools to be ignored. 25 | 26 | ```Swift 27 | UIGraphicsBeginImageContextWithOptions(targetSize, false, 1) 28 | self.snapshotView.drawHierarchy(in: CGRect(origin: CGPoint.zero, size: targetSize), afterScreenUpdates: true) 29 | let aImage = UIGraphicsGetImageFromCurrentImageContext()!.jpegData(compressionQuality: 1)! 30 | sequenceImages.append(aImage) 31 | UIGraphicsEndImageContext() 32 | ``` 33 | 34 | See "AddTextViewController.swift" to learn more. 35 | 36 | ### Add metadata to files 37 | 38 | For the image, you need to add some metadata to the file in order to link it with the video. 39 | 40 | First, you need to generate a unique identifier. In my app, I use the UUID of the device. 41 | 42 | Then set kCGImagePropertyMakerAppleDictionary to it. The dictionary now looks like: [17:assetIdentifier]. 17 means kFigAppleMakerNote_AssetIdentifier. 43 | 44 | ```Swift 45 | makerNote.setObject(assetIdentifier, forKey: kFigAppleMakerNote_AssetIdentifier as NSCopying) 46 | metadata.setObject(makerNote, forKey: kCGImagePropertyMakerAppleDictionary as String as String as NSCopying) 47 | CGImageDestinationAddImage(dest, image, metadata) 48 | ``` 49 | 50 | See "FileProcess/JPEG.swift" to learn more. 51 | 52 | For the video, you need to pass a metadata adapter to the asset writer. 53 | 54 | ```Swift 55 | let spec : NSDictionary = [ 56 | kCMMetadataFormatDescriptionMetadataSpecificationKey_Identifier as NSString: 57 | "\(kKeySpaceQuickTimeMetadata)/\(kKeyStillImageTime)", 58 | kCMMetadataFormatDescriptionMetadataSpecificationKey_DataType as NSString: 59 | "com.apple.metadata.datatype.int8" 60 | ``` 61 | 62 | This app is using AVFoundation to generate video from images. To understand what's happening in this step, you may need to learn AVFoundation. 63 | 64 | See "FileProcess/QuickTimeMov.swift" to learn more. 65 | 66 | ### Make Live Photos 67 | 68 | To make a Live Photo use for Live Photo view, you need to save the image and video to file first. Then you can pass the URL to PHLivePhoto.request() function. 69 | 70 | ```Swift 71 | PHLivePhoto.request(withResourceFileURLs: [imageURL, videoURL], placeholderImage: nil, targetSize: targetSize, contentMode: PHImageContentMode.aspectFit, resultHandler: { (livePhoto, info) -> Void in 72 | doSomethingWithResult(livePhoto) 73 | print(info) 74 | }) 75 | ``` 76 | 77 | To make a Live Photo for saving, you need to do the same thing with PHAssetCreationRequest.forAsset() function. 78 | 79 | ```Swift 80 | let creationRequest = PHAssetCreationRequest.forAsset() 81 | let options = PHAssetResourceCreationOptions() 82 | creationRequest.addResource(with: PHAssetResourceType.photo, fileURL: self.imageURL, options: options) 83 | creationRequest.addResource(with: PHAssetResourceType.pairedVideo, fileURL: self.videoURL, options: options) 84 | ``` 85 | 86 | Then save the file with PHPhotoLibrary.shared().performChanges() function. 87 | 88 | See "BuildLivePhoto.swift" to learn more. 89 | 90 | ## Design 91 | 92 | LiveUseful was designed using Sketch. You can download the .sketch file in the "Design" folder. 93 | 94 | ![Screenshot](https://i.imgur.com/hh3GyTT.png) 95 | 96 | ## Support 97 | 98 | For app support, you can email to app.megabitsenmzq@gmail.com . 99 | 100 | ## Licence - MIT 101 | 102 | LiveUseful is using MIT as open source license. But with an additional term: You could use part of the code, but do not upload this whole app to App Store by yourself. 103 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/megabitsenmzq/LiveUseful/c4cdb244da7e2f3962eb862ab35757b7cb8f8c32/icon.png --------------------------------------------------------------------------------