diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index 95c4320..c0fe704 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,22 @@ +# osX files .DS_Store +.Trashes + +## Xcode Patch +*.xcworkspace +*.xcodeproj/* +!*.xcodeproj/project.pbxproj +!*.xcodeproj/xcshareddata/ +!*.xcworkspace/contents.xcworkspacedata +/*.gcno + +### Xcode Patch ### +**/xcshareddata/WorkspaceSettings.xcsettings + +# Swift Package Manager +.swiftpm /.build -/Packages -/*.xcodeproj -xcuserdata/ + +## Build generated +build/ +DerivedData/ \ No newline at end of file diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a..0000000 --- a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/ALProgressRing.podspec b/ALProgressView.podspec old mode 100644 new mode 100755 similarity index 65% rename from ALProgressRing.podspec rename to ALProgressView.podspec index 5d1ac04..8091eb2 --- a/ALProgressRing.podspec +++ b/ALProgressView.podspec @@ -1,10 +1,10 @@ Pod::Spec.new do |spec| -spec.name = "ALProgressRing" -spec.version = "1.1.0" +spec.name = "ALProgressView" +spec.version = "2.0.0" spec.summary = "Animated and fully customizable progress ring with gradient" -spec.homepage = "https://github.com/alxrguz/ALProgressRing" -spec.source = { :git => "https://github.com/alxrguz/ALProgressRing.git", :tag => "#{spec.version}" } +spec.homepage = "https://github.com/alxrguz/ALProgressView" +spec.source = { :git => "https://github.com/alxrguz/ALProgressView.git", :tag => "#{spec.version}" } spec.license = { :type => "MIT", :file => "LICENSE" } spec.author = { "Alexandr Guzenko" => "alxrguz@icloud.com" } @@ -14,6 +14,6 @@ spec.ios.framework = 'UIKit' spec.swift_version = ['4.2', '5.0'] spec.ios.deployment_target = "10.0" -spec.source_files = "Sources/ALProgressRing/**/*.swift" +spec.source_files = "Sources/ALProgressView/**/*.swift" end \ No newline at end of file diff --git a/Assets/ALProgressRing.sketch b/Assets/ALProgressRing.sketch old mode 100644 new mode 100755 index 200dc56..265e5b8 Binary files a/Assets/ALProgressRing.sketch and b/Assets/ALProgressRing.sketch differ diff --git a/Assets/PreviewBanner.gif b/Assets/PreviewBanner.gif old mode 100644 new mode 100755 diff --git a/Assets/PreviewBanner.psd b/Assets/PreviewBanner.psd old mode 100644 new mode 100755 diff --git a/Assets/SocialBanner.png b/Assets/SocialBanner.png old mode 100644 new mode 100755 index 40667e7..4fe06c9 Binary files a/Assets/SocialBanner.png and b/Assets/SocialBanner.png differ diff --git a/Assets/timingFunctions.png b/Assets/timingFunctions.png old mode 100644 new mode 100755 diff --git a/ExampleApp/ALRingView Example.xcodeproj/project.pbxproj b/ExampleApp/ALRingView Example.xcodeproj/project.pbxproj new file mode 100644 index 0000000..98e851e --- /dev/null +++ b/ExampleApp/ALRingView Example.xcodeproj/project.pbxproj @@ -0,0 +1,377 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 52; + objects = { + +/* Begin PBXBuildFile section */ + BB3959F724EA71EE00B965F5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3959F624EA71EE00B965F5 /* AppDelegate.swift */; }; + BB3959FB24EA71EE00B965F5 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3959FA24EA71EE00B965F5 /* ViewController.swift */; }; + BB395A0024EA71F200B965F5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BB3959FF24EA71F200B965F5 /* Assets.xcassets */; }; + BB395A0324EA71F200B965F5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BB395A0124EA71F200B965F5 /* LaunchScreen.storyboard */; }; + BB65E1FF266669ED009B68D4 /* ALProgressView in Frameworks */ = {isa = PBXBuildFile; productRef = BB65E1FE266669ED009B68D4 /* ALProgressView */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + BB3959F324EA71EE00B965F5 /* iOS App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "iOS App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + BB3959F624EA71EE00B965F5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + BB3959FA24EA71EE00B965F5 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + BB3959FF24EA71F200B965F5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + BB395A0224EA71F200B965F5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + BB395A0424EA71F200B965F5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BB65E1FC266669DF009B68D4 /* ALProgressView */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ALProgressView; path = ..; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + BB3959F024EA71EE00B965F5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BB65E1FF266669ED009B68D4 /* ALProgressView in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + BB3959EA24EA71EE00B965F5 = { + isa = PBXGroup; + children = ( + BB65E1FC266669DF009B68D4 /* ALProgressView */, + BB3959F524EA71EE00B965F5 /* iOS App */, + BB3959F424EA71EE00B965F5 /* Products */, + BB65E1FD266669ED009B68D4 /* Frameworks */, + ); + sourceTree = ""; + }; + BB3959F424EA71EE00B965F5 /* Products */ = { + isa = PBXGroup; + children = ( + BB3959F324EA71EE00B965F5 /* iOS App.app */, + ); + name = Products; + sourceTree = ""; + }; + BB3959F524EA71EE00B965F5 /* iOS App */ = { + isa = PBXGroup; + children = ( + BB3959F624EA71EE00B965F5 /* AppDelegate.swift */, + BB395A0A24EA722A00B965F5 /* Controllers */, + BB395A0B24EA723800B965F5 /* Sources */, + ); + path = "iOS App"; + sourceTree = ""; + }; + BB395A0A24EA722A00B965F5 /* Controllers */ = { + isa = PBXGroup; + children = ( + BB395A0D24EA727000B965F5 /* Launch */, + BB3959FA24EA71EE00B965F5 /* ViewController.swift */, + ); + path = Controllers; + sourceTree = ""; + }; + BB395A0B24EA723800B965F5 /* Sources */ = { + isa = PBXGroup; + children = ( + BB3959FF24EA71F200B965F5 /* Assets.xcassets */, + BB395A0424EA71F200B965F5 /* Info.plist */, + ); + path = Sources; + sourceTree = ""; + }; + BB395A0D24EA727000B965F5 /* Launch */ = { + isa = PBXGroup; + children = ( + BB395A0124EA71F200B965F5 /* LaunchScreen.storyboard */, + ); + path = Launch; + sourceTree = ""; + }; + BB65E1FD266669ED009B68D4 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + BB3959F224EA71EE00B965F5 /* iOS App */ = { + isa = PBXNativeTarget; + buildConfigurationList = BB395A0724EA71F200B965F5 /* Build configuration list for PBXNativeTarget "iOS App" */; + buildPhases = ( + BB3959EF24EA71EE00B965F5 /* Sources */, + BB3959F024EA71EE00B965F5 /* Frameworks */, + BB3959F124EA71EE00B965F5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "iOS App"; + packageProductDependencies = ( + BB65E1FE266669ED009B68D4 /* ALProgressView */, + ); + productName = "Panda School"; + productReference = BB3959F324EA71EE00B965F5 /* iOS App.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + BB3959EB24EA71EE00B965F5 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1160; + LastUpgradeCheck = 1160; + ORGANIZATIONNAME = alxrguz; + TargetAttributes = { + BB3959F224EA71EE00B965F5 = { + CreatedOnToolsVersion = 11.6; + }; + }; + }; + buildConfigurationList = BB3959EE24EA71EE00B965F5 /* Build configuration list for PBXProject "ALRingView Example" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = BB3959EA24EA71EE00B965F5; + packageReferences = ( + ); + productRefGroup = BB3959F424EA71EE00B965F5 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + BB3959F224EA71EE00B965F5 /* iOS App */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + BB3959F124EA71EE00B965F5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BB395A0324EA71F200B965F5 /* LaunchScreen.storyboard in Resources */, + BB395A0024EA71F200B965F5 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + BB3959EF24EA71EE00B965F5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BB3959FB24EA71EE00B965F5 /* ViewController.swift in Sources */, + BB3959F724EA71EE00B965F5 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + BB395A0124EA71F200B965F5 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + BB395A0224EA71F200B965F5 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + BB395A0524EA71F200B965F5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.6; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + BB395A0624EA71F200B965F5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.6; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + BB395A0824EA71F200B965F5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RW83L2JUQB; + INFOPLIST_FILE = "iOS App/Sources/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = alxrguz.alringview.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + BB395A0924EA71F200B965F5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RW83L2JUQB; + INFOPLIST_FILE = "iOS App/Sources/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = alxrguz.alringview.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + BB3959EE24EA71EE00B965F5 /* Build configuration list for PBXProject "ALRingView Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BB395A0524EA71F200B965F5 /* Debug */, + BB395A0624EA71F200B965F5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + BB395A0724EA71F200B965F5 /* Build configuration list for PBXNativeTarget "iOS App" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BB395A0824EA71F200B965F5 /* Debug */, + BB395A0924EA71F200B965F5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCSwiftPackageProductDependency section */ + BB65E1FE266669ED009B68D4 /* ALProgressView */ = { + isa = XCSwiftPackageProductDependency; + productName = ALProgressView; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = BB3959EB24EA71EE00B965F5 /* Project object */; +} diff --git a/ExampleApp/ALRingView Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ExampleApp/ALRingView Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..2abaa1c --- /dev/null +++ b/ExampleApp/ALRingView Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ExampleApp/ALRingView Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from .swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to ExampleApp/ALRingView Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/ExampleApp/ALRingView Example.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ExampleApp/ALRingView Example.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ExampleApp/ALRingView Example.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ExampleApp/ALRingView Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ExampleApp/ALRingView Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..f2ab4b4 --- /dev/null +++ b/ExampleApp/ALRingView Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,34 @@ +{ + "object": { + "pins": [ + { + "package": "ALDevKit", + "repositoryURL": "https://github.com/alxrguz/ALDevKit", + "state": { + "branch": "master", + "revision": "bf6a336574e6deabd4383307fe6254285bc87d97", + "version": null + } + }, + { + "package": "SnapKit", + "repositoryURL": "https://github.com/SnapKit/SnapKit", + "state": { + "branch": "develop", + "revision": "80cc5696a4862be87b49bdda83b3e6514b10fb16", + "version": null + } + }, + { + "package": "SparrowKit", + "repositoryURL": "https://github.com/varabeis/SparrowKit", + "state": { + "branch": "main", + "revision": "9621aaf9698e91d540f0e67a44077c88cae630a3", + "version": null + } + } + ] + }, + "version": 1 +} diff --git a/ExampleApp/ALRingView Example.xcodeproj/xcshareddata/xcschemes/iOS App.xcscheme b/ExampleApp/ALRingView Example.xcodeproj/xcshareddata/xcschemes/iOS App.xcscheme new file mode 100644 index 0000000..def057f --- /dev/null +++ b/ExampleApp/ALRingView Example.xcodeproj/xcshareddata/xcschemes/iOS App.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ExampleApp/ALRingView Example.xcodeproj/xcuserdata/alxrguz.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/ExampleApp/ALRingView Example.xcodeproj/xcuserdata/alxrguz.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..06b8492 --- /dev/null +++ b/ExampleApp/ALRingView Example.xcodeproj/xcuserdata/alxrguz.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/ExampleApp/ALRingView Example.xcodeproj/xcuserdata/alxrguz.xcuserdatad/xcschemes/xcschememanagement.plist b/ExampleApp/ALRingView Example.xcodeproj/xcuserdata/alxrguz.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..e3836b5 --- /dev/null +++ b/ExampleApp/ALRingView Example.xcodeproj/xcuserdata/alxrguz.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,64 @@ + + + + + SchemeUserState + + SnapKitPlayground (Playground) 1.xcscheme + + isShown + + orderHint + 3 + + SnapKitPlayground (Playground) 2.xcscheme + + isShown + + orderHint + 4 + + SnapKitPlayground (Playground) 3.xcscheme + + isShown + + orderHint + 4 + + SnapKitPlayground (Playground) 4.xcscheme + + isShown + + orderHint + 5 + + SnapKitPlayground (Playground) 5.xcscheme + + isShown + + orderHint + 6 + + SnapKitPlayground (Playground).xcscheme + + isShown + + orderHint + 1 + + iOS App.xcscheme_^#shared#^_ + + orderHint + 1 + + + SuppressBuildableAutocreation + + BB3959F224EA71EE00B965F5 + + primary + + + + + diff --git a/ExampleApp/iOS App/AppDelegate.swift b/ExampleApp/iOS App/AppDelegate.swift new file mode 100644 index 0000000..56f002a --- /dev/null +++ b/ExampleApp/iOS App/AppDelegate.swift @@ -0,0 +1,20 @@ +// +// AppDelegate.swift +// +// Created by Alexandr Guzenko on 17.08.2020. +// Copyright © 2020. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + window = UIWindow() + window?.rootViewController = MainViewController() + window?.makeKeyAndVisible() + return true + } +} + diff --git a/ExampleApp/iOS App/Controllers/Launch/Base.lproj/LaunchScreen.storyboard b/ExampleApp/iOS App/Controllers/Launch/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/ExampleApp/iOS App/Controllers/Launch/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ExampleApp/iOS App/Controllers/ViewController.swift b/ExampleApp/iOS App/Controllers/ViewController.swift new file mode 100644 index 0000000..ee426b8 --- /dev/null +++ b/ExampleApp/iOS App/Controllers/ViewController.swift @@ -0,0 +1,88 @@ +// +// ViewController.swift +// +// Created by Alexandr Guzenko on 17.08.2020. +// Copyright © 2020. All rights reserved. +// + +import UIKit +import ALProgressView + +class MainViewController: UIViewController { + + // MARK: - UIElements + + private lazy var progressRing = ALProgressRing() + private lazy var progressBar = ALProgressBar() + private lazy var titleLabel = UILabel() + private lazy var subtitleLabel = UILabel() + private lazy var emojiLabel = UILabel() + + override func viewDidLoad() { + super.viewDidLoad() + setupView() + setupConstraints() + } +} + +// MARK: - Setup Layout + +private extension MainViewController { + func setupColors() { + view.backgroundColor = .systemBackground + titleLabel.textColor = .label + subtitleLabel.textColor = .secondaryLabel + } + + func setupView() { + setupColors() + + progressRing.lineWidth = 15 + progressRing.setProgress(0.8, animated: true) + + progressBar.setProgress(0.6, animated: true) + + + emojiLabel.text = "✌️" + emojiLabel.font = .systemFont(ofSize: 80, weight: .regular) + + titleLabel.text = "ALProgressView" + titleLabel.font = .systemFont(ofSize: 32, weight: .bold) + + subtitleLabel.text = "Easy, simple, customizable" + subtitleLabel.font = .systemFont(ofSize: 21, weight: .regular) + } + + func setupConstraints() { + view.addSubview(progressRing) + progressRing.addSubview(emojiLabel) + view.addSubview(titleLabel) + view.addSubview(subtitleLabel) + view.addSubview(progressBar) + + progressRing.translatesAutoresizingMaskIntoConstraints = false + progressRing.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + progressRing.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -100).isActive = true + progressRing.widthAnchor.constraint(equalToConstant: 180).isActive = true + progressRing.heightAnchor.constraint(equalToConstant: 180).isActive = true + + emojiLabel.translatesAutoresizingMaskIntoConstraints = false + emojiLabel.centerXAnchor.constraint(equalTo: progressRing.centerXAnchor).isActive = true + emojiLabel.centerYAnchor.constraint(equalTo: progressRing.centerYAnchor).isActive = true + + titleLabel.translatesAutoresizingMaskIntoConstraints = false + titleLabel.topAnchor.constraint(equalTo: progressRing.bottomAnchor, constant: 40).isActive = true + titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + + subtitleLabel.translatesAutoresizingMaskIntoConstraints = false + subtitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8).isActive = true + subtitleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + + progressBar.translatesAutoresizingMaskIntoConstraints = false + progressBar.topAnchor.constraint(equalTo: subtitleLabel.bottomAnchor, constant: 20).isActive = true + progressBar.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + progressBar.widthAnchor.constraint(equalTo: titleLabel.widthAnchor).isActive = true + progressBar.heightAnchor.constraint(equalToConstant: 10).isActive = true + + } +} diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2fb912e --- /dev/null +++ b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "filename" : "iphone-20x20@2x.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "filename" : "iphone-20x20@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "filename" : "iphone-29x29@2x.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "filename" : "iphone-29x29@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "filename" : "iphone-40x40@2x.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "filename" : "iphone-40x40@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "filename" : "iphone-60x60@2x.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "filename" : "iphone-60x60@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "filename" : "ipad-20x20.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "filename" : "ipad-20x20@2x.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "filename" : "ipad-29x29.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "filename" : "ipad-29x29@2x.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "filename" : "ipad-40x40.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "filename" : "ipad-40x40@2x.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "filename" : "ipad-76x76.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "filename" : "ipad-76x76@2x.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "filename" : "ipad-83.5x83.5@2x.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "filename" : "ios-marketing-1024x1024.png", + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ios-marketing-1024x1024.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ios-marketing-1024x1024.png new file mode 100644 index 0000000..4e2f7b6 Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ios-marketing-1024x1024.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-20x20.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-20x20.png new file mode 100644 index 0000000..80b065a Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-20x20.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-20x20@2x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-20x20@2x.png new file mode 100644 index 0000000..0c83c2a Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-20x20@2x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-29x29.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-29x29.png new file mode 100644 index 0000000..0c17be3 Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-29x29.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-29x29@2x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-29x29@2x.png new file mode 100644 index 0000000..86a3fd5 Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-29x29@2x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-40x40.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-40x40.png new file mode 100644 index 0000000..0c83c2a Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-40x40.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-40x40@2x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-40x40@2x.png new file mode 100644 index 0000000..a1af3af Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-40x40@2x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-76x76.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-76x76.png new file mode 100644 index 0000000..133e73c Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-76x76.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-76x76@2x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-76x76@2x.png new file mode 100644 index 0000000..889e558 Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-76x76@2x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-83.5x83.5@2x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-83.5x83.5@2x.png new file mode 100644 index 0000000..c891e59 Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/ipad-83.5x83.5@2x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-20x20@2x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-20x20@2x.png new file mode 100644 index 0000000..0c83c2a Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-20x20@2x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-20x20@3x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-20x20@3x.png new file mode 100644 index 0000000..b4cded0 Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-20x20@3x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-29x29@2x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-29x29@2x.png new file mode 100644 index 0000000..86a3fd5 Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-29x29@2x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-29x29@3x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-29x29@3x.png new file mode 100644 index 0000000..066a6c1 Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-29x29@3x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-40x40@2x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-40x40@2x.png new file mode 100644 index 0000000..a1af3af Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-40x40@2x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-40x40@3x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-40x40@3x.png new file mode 100644 index 0000000..0c41939 Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-40x40@3x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-60x60@2x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-60x60@2x.png new file mode 100644 index 0000000..0c41939 Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-60x60@2x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-60x60@3x.png b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-60x60@3x.png new file mode 100644 index 0000000..6095fc7 Binary files /dev/null and b/ExampleApp/iOS App/Sources/Assets.xcassets/AppIcon.appiconset/iphone-60x60@3x.png differ diff --git a/ExampleApp/iOS App/Sources/Assets.xcassets/Contents.json b/ExampleApp/iOS App/Sources/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/ExampleApp/iOS App/Sources/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ExampleApp/iOS App/Sources/Info.plist b/ExampleApp/iOS App/Sources/Info.plist new file mode 100644 index 0000000..696faf0 --- /dev/null +++ b/ExampleApp/iOS App/Sources/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + ALProgressView + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/Package.swift b/Package.swift old mode 100644 new mode 100755 index 1c51fc4..7a55a2b --- a/Package.swift +++ b/Package.swift @@ -4,14 +4,14 @@ import PackageDescription let package = Package( - name: "ALProgressRing", + name: "ALProgressView", platforms: [ .iOS(.v10) ], products: [ - .library(name: "ALProgressRing", targets: ["ALProgressRing"]), + .library(name: "ALProgressView", targets: ["ALProgressView"]), ], targets: [ - .target(name: "ALProgressRing"), + .target(name: "ALProgressView"), ] ) diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 8146a19..daf6919 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# ALProgressRing +# ALProgressView - + ### About -**ALProgressRing** - is a library for displaying a circular progress ring. +**ALProgressView** - is a library for displaying a progress view with 2 styles: ring and bar. -It's easy to customize. You can adjust the gradient for the ring, line width, shadow, and more. +It's easy to customize. You can adjust the gradient, line width, shadow, and more. Also for this library, I added about 20 functions for animation, more details in the [Animation](#Animation) section @@ -32,10 +32,12 @@ If you liked this library, please do not forget to put a `★ star`, it will hel - [Usage](#usage) - [Quick Start](#Quick-Start) - [Customization](#Customization) - - [Colors](#colors) - - [Layout](#Layout) - - [Animation](#Animation) -- [License](https://github.com/SnapKit/SnapKit#license) + - [General](#General) + - [Colors](#colors) + - [Animation](#Animation) + - [ALProgressRing](#ALProgressRing) + - [ALProgressBar](#ALProgressBar) +- [License](#License) ## @@ -52,23 +54,23 @@ If you liked this library, please do not forget to put a `★ star`, it will hel The [Swift Package Manager](https://swift.org/package-manager/) is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies. -To integrate **ALProgressRing** click `File -> Swift Package -> Add Package Dependency` and insert: +To integrate **ALProgressView** click `File -> Swift Package -> Add Package Dependency` and insert: ```ogdl -https://github.com/alxrguz/ALProgressRing +https://github.com/alxrguz/ALProgressView ``` #### CocoaPods -**ALProgressRing** is available through [CocoaPods](https://cocoapods.org/pods/ALProgressRing). To install it, simply add the following line to your Podfile: +**ALProgressView** is available through [CocoaPods](https://cocoapods.org/pods/ALProgressView). To install it, simply add the following line to your Podfile: ```ruby -pod 'ALProgressRing' +pod 'ALProgressView' ``` #### Manually -If you prefer not to use either of the aforementioned dependency managers, you can integrate ALProgressRing into your project manually. Put `Source/ALProgressRing` folder in your Xcode project. +If you prefer not to use either of the aforementioned dependency managers, you can integrate ALProgressView into your project manually. Put `Source/ALProgressView` folder in your Xcode project. @@ -77,53 +79,91 @@ If you prefer not to use either of the aforementioned dependency managers, you c #### Quick Start ```swift -import ALProgressRing +import ALProgressView class MyViewController: UIViewController { private lazy var progressRing = ALProgressRing() + private lazy var progressBar = ALProgressBar() override func viewDidLoad() { super.viewDidLoad() view.addSubview(progressRing) - // Setup layout + view.addSubview(progressRing) + + // MARK: ALProgressRing + + // Setup layout progressRing.translatesAutoresizingMaskIntoConstraints = false progressRing.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true progressRing.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true // Make sure to set the view size progressRing.widthAnchor.constraint(equalToConstant: 180).isActive = true progressRing.heightAnchor.constraint(equalToConstant: 180).isActive = true - + + + // MARK: ALProgressBar + + // Setup layout + progressBar.translatesAutoresizingMaskIntoConstraints = false + progressBar.topAnchor.constraint(equalTo: progressRing.bottomAnchor, constant: 20).isActive = true + progressBar.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + progressBar.widthAnchor.constraint(equalTo: titleLabel.widthAnchor).isActive = true + // Make sure to set the view height + progressBar.heightAnchor.constraint(equalToConstant: 10).isActive = true + + + // Setting progress progressRing.setProgress(0.8, animated: true) + progressBar.setProgress(0.6, animated: true) } } ``` +You can also run ExampleApp and play with the parameters there + #### Customization -#### Colors +##### General + +###### Colors You can customize the buttons, headers and indicators colors depending on their state. ```swift /// Set track color /// If you don't need a gradient, just set the same values for `startColor` and `endColor` -progressRing.startColor = .systemPink -progressRing.endColor = .systemRed +progressView.startColor = .systemPink +progressView.endColor = .systemRed /// Set groove color -progressRing.endColor = .systemRed +progressView.grooveColor = .systemRed ``` +###### Animation +```swift +progressView.duration = 2 // Duration of the ring's fill animation. +progressView.timingFunction = .easeOutExpo // Timing function of the ring's fill animation. -#### Layout +/// The following use of setProgress (_ value: Int, animated: Bool) +/// will take into account the new parameters +progressView.setProgress(0.8, animated: true) +``` + +Let's take a look at the `timingFunction` parameter, it is of type `ALTimingFunction`, which contains the following types of animations: + + + +There is a good cheat sheet available [here](http://easings.net/). + +##### AlProgressRing ```swift -progressRing.startAngle = -.pi / 2 // The start angle of the ring to begin drawing. +progressBar.startAngle = -.pi / 2 // The start angle of the ring to begin drawing. progressRing.endAngle = 1.5 * .pi // The end angle of the ring to end drawing. progressRing.startGradientPoint = .init(x: 0.5, y: 0) // The starting poin of the gradient progressRing.endGradientPoint = .init(x: 0.5, y: 1) // The ending position of the gradient. @@ -137,24 +177,15 @@ progressRing.grooveWidth = 8 -#### Animation +##### AlProgressBar ```swift -progressRing.duration = 2 // Duration of the ring's fill animation. -progressRing.timingFunction = .easeOutExpo // Timing function of the ring's fill animation. - -/// The following use of setProgress (_ value: Int, animated: Bool) -/// will take into account the new parameters -progressRing.setProgress(0.8, animated: true) +progressBar.barEdgeInset = 1.5 // Distance between groove and progress bar. ``` -Let's take a look at the `timingFunction` parameter, it is of type `ALTimingFunction`, which contains the following types of animations: - - -There is a good cheat sheet available [here](http://easings.net/). ## License -**ALProgressRing** is under MIT license. See the [LICENSE](https://github.com/alxrguz/ALProgressRing/blob/main/LICENSE) file for more info. +**ALProgressView** is under MIT license. See the [LICENSE](https://github.com/alxrguz/ALProgressView/blob/main/LICENSE) file for more info. diff --git a/Sources/ALProgressRing/Model/ALTimingFunction.swift b/Sources/ALProgressView/Model/ALTimingFunction.swift old mode 100644 new mode 100755 similarity index 100% rename from Sources/ALProgressRing/Model/ALTimingFunction.swift rename to Sources/ALProgressView/Model/ALTimingFunction.swift diff --git a/Sources/ALProgressView/Views/ALProgressBar.swift b/Sources/ALProgressView/Views/ALProgressBar.swift new file mode 100644 index 0000000..8ad1398 --- /dev/null +++ b/Sources/ALProgressView/Views/ALProgressBar.swift @@ -0,0 +1,191 @@ +// The MIT License (MIT) +// +// Copyright (c) 2020 Alexandr Guzenko (alxrguz@icloud.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +/// A fillable progress ring drawing. +open class ALProgressBar: UIView { + + // MARK: Properties + + /// Distance between groove and progress bar. Default is 0 + public var barEdgeInset: CGFloat = 0 { + didSet { configureBar(); styleBarLayer() } + } + + /// The first gradient color of the track. + public var startColor: UIColor = .systemPink { + didSet { gradientLayer.colors = [startColor.cgColor, endColor.cgColor] } + } + + /// The second gradient color of the track. + public var endColor: UIColor = .systemRed { + didSet { gradientLayer.colors = [startColor.cgColor, endColor.cgColor] } + } + + /// The groove color in which the fillable ring resides. + public var grooveColor: UIColor = UIColor.systemGray.withAlphaComponent(0.2) { + didSet { barLayer.strokeColor = grooveColor.cgColor } + } + + /// The starting poin of the gradient. Default is (x: 0, y: 0.5) + public var startGradientPoint: CGPoint = .init(x: 0, y: 0.5) { + didSet { gradientLayer.startPoint = startGradientPoint } + } + + /// The ending position of the gradient. Default is (x: 1, y: 0.5) + public var endGradientPoint: CGPoint = .init(x: 1, y: 0.5) { + didSet { gradientLayer.endPoint = endGradientPoint } + } + + /// Duration of the ring's fill animation. Default is 2.0 + public var duration: TimeInterval = 2.0 + + /// Timing function of the ring's fill animation. Default is `.easeOutExpo` + public var timingFunction: ALTimingFunction = .easeOutExpo + + /// The progress of the ring between 0 and 1. The ring will fill based on the value. + public private(set) var progress: CGFloat = 0 + + private let ringLayer: CAShapeLayer = { + let layer = CAShapeLayer() + layer.lineCap = .round + layer.fillColor = nil + layer.strokeStart = 0 + layer.strokeEnd = 1 + return layer + }() + + private let barLayer: CAShapeLayer = { + let layer = CAShapeLayer() + layer.lineCap = .round + layer.fillColor = nil + layer.strokeStart = 0 + layer.strokeEnd = 1 + return layer + }() + + private let gradientLayer = CAGradientLayer() + + // MARK: Life Cycle + public init() { + super.init(frame: .zero) + setup() + } + + override public init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + setup() + } + + public override func layoutSubviews() { + super.layoutSubviews() + configureBar() + styleBarLayer() + } + + public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + styleBarLayer() + } + + // MARK: Methods + + /// Set the progress value of the ring. The ring will fill based on the value. + /// + /// - Parameters: + /// - value: Progress value between 0 and 1. + /// - animated: Flag for the fill ring's animation. + /// - completion: Closure called after animation ends + public func setProgress(_ value: Float, animated: Bool, completion: (() -> Void)? = nil) { + layoutIfNeeded() + let value = CGFloat(min(value, 1.0)) + let oldValue = ringLayer.presentation()?.strokeEnd ?? progress + progress = value + ringLayer.strokeEnd = progress + guard animated else { + layer.removeAllAnimations() + ringLayer.removeAllAnimations() + gradientLayer.removeAllAnimations() + completion?() + return + } + + CATransaction.begin() + let path = #keyPath(CAShapeLayer.strokeEnd) + let fill = CABasicAnimation(keyPath: path) + fill.fromValue = oldValue + fill.toValue = value + fill.duration = duration + fill.timingFunction = timingFunction.function + CATransaction.setCompletionBlock(completion) + ringLayer.add(fill, forKey: "fill") + CATransaction.commit() + } + + + private func setup() { + preservesSuperviewLayoutMargins = true + layer.addSublayer(barLayer) + layer.addSublayer(gradientLayer) + styleBarLayer() + setProgress(Float(progress), animated: false) + } + + private func styleBarLayer() { + barLayer.strokeColor = grooveColor.cgColor + barLayer.lineWidth = frame.height + + ringLayer.lineWidth = frame.height - (barEdgeInset * 2) + ringLayer.strokeColor = startColor.cgColor + ringLayer.strokeEnd = min(progress, 1.0) + + gradientLayer.colors = [startColor.cgColor, endColor.cgColor] + gradientLayer.startPoint = startGradientPoint + gradientLayer.endPoint = endGradientPoint + } + + private func configureBar() { + let inset = frame.height / 2 + let barInset = barEdgeInset / 2 + + let grooveLinePath = UIBezierPath() + grooveLinePath.move(to: CGPoint(x: inset, y: bounds.midY)) + grooveLinePath.addLine(to: CGPoint(x: bounds.width - inset, y: bounds.midY)) + barLayer.path = grooveLinePath.cgPath + + + let barLinePath = UIBezierPath() + barLinePath.move(to: CGPoint(x: inset + barInset, y: bounds.midY)) + barLinePath.addLine(to: CGPoint(x: bounds.width - (inset + barInset), y: bounds.midY)) + ringLayer.path = barLinePath.cgPath + + [barLayer, ringLayer, gradientLayer].forEach { $0.frame = bounds } + gradientLayer.mask = ringLayer + } +} + diff --git a/Sources/ALProgressRing/Views/ALProgressRing.swift b/Sources/ALProgressView/Views/ALProgressRing.swift old mode 100644 new mode 100755 similarity index 99% rename from Sources/ALProgressRing/Views/ALProgressRing.swift rename to Sources/ALProgressView/Views/ALProgressRing.swift index e679045..4a3441b --- a/Sources/ALProgressRing/Views/ALProgressRing.swift +++ b/Sources/ALProgressView/Views/ALProgressRing.swift @@ -150,6 +150,7 @@ open class ALProgressRing: UIView { public override func layoutSubviews() { super.layoutSubviews() configureRing() + styleRingLayer() } public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { @@ -211,8 +212,6 @@ open class ALProgressRing: UIView { gradientLayer.startPoint = CGPoint(x: 0.0, y: 0) gradientLayer.endPoint = CGPoint(x: 0.0, y: 1) - gradientLayer.shadowOpacity = 0.4 - gradientLayer.shadowRadius = 5 gradientLayer.shadowColor = startColor.cgColor gradientLayer.shadowOffset = .zero }