Showing preview only (204K chars total). Download the full file or copy to clipboard to get everything.
Repository: keygx/GradientCircularProgress
Branch: master
Commit: 9e2dc60d335e
Files: 60
Total size: 185.9 KB
Directory structure:
gitextract_v1j42pdv/
├── .gitignore
├── GCProgressSample/
│ ├── GCProgressSample/
│ │ ├── AlertHelperKit.swift
│ │ ├── AppDelegate.swift
│ │ ├── AsyncUtil.swift
│ │ ├── BackgroundTransparentStyle.swift
│ │ ├── Base.lproj/
│ │ │ ├── LaunchScreen.xib
│ │ │ └── Main.storyboard
│ │ ├── Images.xcassets/
│ │ │ └── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ ├── MyButton.swift
│ │ ├── MyStyle.swift
│ │ └── ViewController.swift
│ ├── GCProgressSample.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── GradientCircularProgress.xcscheme
│ ├── GCProgressSampleTests/
│ │ ├── GCProgressSampleTests.swift
│ │ └── Info.plist
│ └── GradientCircularProgress/
│ ├── GradientCircularProgress.h
│ ├── GradientCircularProgress.swift
│ ├── Info.plist
│ ├── Progress/
│ │ ├── Core/
│ │ │ ├── CircularProgressView.swift
│ │ │ └── ProgressAtRatioView.swift
│ │ ├── Elements/
│ │ │ ├── ArcView.swift
│ │ │ ├── Background.swift
│ │ │ ├── GradientArcView.swift
│ │ │ ├── GradientArcWithClearColorView.swift
│ │ │ └── WindowBuilder.swift
│ │ ├── ProgressView.swift
│ │ ├── ProgressViewController.swift
│ │ └── Property.swift
│ ├── Styles/
│ │ ├── BlueDarkStyle.swift
│ │ ├── BlueIndicatorStyle.swift
│ │ ├── GreenLightStyle.swift
│ │ ├── OrangeClearStyle.swift
│ │ └── Style.swift
│ └── Utils/
│ └── ColorUtil.swift
├── GradientCircularProgress.podspec
├── LICENSE
├── README.md
├── Sample/
│ ├── BackgroundTransparentStyle.swift
│ └── MyStyle.swift
└── source/
├── GradientCircularProgress.h
├── GradientCircularProgress.swift
├── Progress/
│ ├── Core/
│ │ ├── CircularProgressView.swift
│ │ └── ProgressAtRatioView.swift
│ ├── Elements/
│ │ ├── ArcView.swift
│ │ ├── Background.swift
│ │ ├── GradientArcView.swift
│ │ ├── GradientArcWithClearColorView.swift
│ │ └── WindowBuilder.swift
│ ├── ProgressView.swift
│ ├── ProgressViewController.swift
│ └── Property.swift
├── Styles/
│ ├── BlueDarkStyle.swift
│ ├── BlueIndicatorStyle.swift
│ ├── GreenLightStyle.swift
│ ├── OrangeClearStyle.swift
│ └── Style.swift
└── Utils/
└── ColorUtil.swift
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Created by https://www.gitignore.io
### Swift ###
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
#
Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
Carthage/Checkouts
Carthage/Build
================================================
FILE: GCProgressSample/GCProgressSample/AlertHelperKit.swift
================================================
//
// AlertHelperKit.swift
//
// Created by keygx on 2015/07/21.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public enum ActionSheetPopoverStyle: Int {
case normal = 0
case barButton
}
public struct Parameters {
var title: String?
var message: String?
var cancelButton: String?
var destructiveButtons: [String]?
var otherButtons: [String]?
var disabledButtons: [String]?
var inputFields: [InputField]?
var sender: AnyObject?
var arrowDirection: UIPopoverArrowDirection?
var popoverStyle: ActionSheetPopoverStyle = .normal
public init(
title: String? = nil,
message: String? = nil,
cancelButton: String? = nil,
destructiveButtons: [String]? = nil,
otherButtons: [String]? = nil,
disabledButtons: [String]? = nil,
inputFields: [InputField]? = nil,
sender: AnyObject? = nil,
arrowDirection: UIPopoverArrowDirection? = nil,
popoverStyle: ActionSheetPopoverStyle = .normal
) {
self.title = title
self.message = message
self.cancelButton = cancelButton
self.destructiveButtons = destructiveButtons
self.otherButtons = otherButtons
self.disabledButtons = disabledButtons
self.inputFields = inputFields
self.sender = sender
self.arrowDirection = arrowDirection
self.popoverStyle = popoverStyle
}
}
public struct InputField {
var placeholder: String
var secure: Bool?
public init(placeholder: String, secure: Bool?) {
self.placeholder = placeholder
self.secure = secure
}
}
public class AlertHelperKit {
public var animated: Bool = true
public var completionHandler: (() -> Void)?
public var textFields: [AnyObject]?
public init() {
initialize()
}
private func initialize() {
animated = true
completionHandler = nil
textFields = nil
}
// Alert
public func showAlert(_ parent: UIViewController, title: String?, message: String?, button: String) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
// cancel
let cancelAction = UIAlertAction(title: button, style: .cancel, handler: nil)
alertController.addAction(cancelAction)
show(parent, ac: alertController)
}
// Alert with Callback Handler
public func showAlertWithHandler(_ parent: UIViewController, parameters: Parameters, handler: @escaping (Int) -> ()) {
let alertController: UIAlertController = buildAlertController(.alert, params: parameters) { buttonIndex in
handler(buttonIndex)
}
buttonDisabled(alertController, params: parameters)
show(parent, ac: alertController)
}
// ActionSheet
public func showActionSheet(_ parent: UIViewController, parameters: Parameters, handler: @escaping (Int) -> ()) {
let alertController: UIAlertController = buildAlertController(.actionSheet, params: parameters) { buttonIndex in
handler(buttonIndex)
}
buttonDisabled(alertController, params: parameters)
if let popover = alertController.popoverPresentationController, let sender: AnyObject = parameters.sender, let arrowDirection = parameters.arrowDirection {
popover.sourceView = parent.view
switch parameters.popoverStyle {
case .barButton:
guard let barButton = sender as? UIBarButtonItem else { return }
popover.barButtonItem = barButton
default:
guard let button = sender as? UIButton else { return }
popover.sourceRect = button.frame
}
popover.permittedArrowDirections = arrowDirection
}
show(parent, ac: alertController)
}
// Build AlertController
private func buildAlertController(_ style: UIAlertController.Style, params: Parameters, handler: @escaping (Int) -> ()) -> UIAlertController {
let alertController = UIAlertController(title: params.title, message: params.message, preferredStyle: style)
let destructivOffset = 1
var othersOffset = destructivOffset
// cancel
if let cancel = params.cancelButton {
let cancelAction = UIAlertAction(title: cancel, style: .cancel) { _ in
handler(0)
}
alertController.addAction(cancelAction)
}
// destructive
if let destructive = params.destructiveButtons {
for i in 0..<destructive.count {
let destructiveAction = UIAlertAction(title: destructive[i], style: .destructive) { _ in
handler(i + destructivOffset)
}
alertController.addAction(destructiveAction)
othersOffset += 1
}
}
// others
if let others = params.otherButtons {
for i in 0..<others.count {
let otherAction = UIAlertAction(title: others[i], style: .default) { _ in
handler(i + othersOffset)
}
alertController.addAction(otherAction)
}
}
// textFields
if style != .actionSheet {
if let inputFields = params.inputFields {
for i in 0..<inputFields.count {
alertController.addTextField(configurationHandler: { textField in
// placeholder
textField.placeholder = inputFields[i].placeholder
// secure
if let secure = inputFields[i].secure {
textField.isSecureTextEntry = secure
}
})
}
}
}
return alertController
}
// Button Disabled
private func buttonDisabled(_ alertController: UIAlertController, params: Parameters) {
guard let buttons = params.disabledButtons else {
return
}
for alertAction in alertController.actions {
let action: UIAlertAction = alertAction
for title in buttons {
if action.title == title {
action.isEnabled = false
}
}
}
}
// Appear Alert
private func show(_ vc: UIViewController, ac: UIAlertController) {
textFields = ac.textFields
vc.present(ac, animated: animated, completion: completionHandler)
}
}
================================================
FILE: GCProgressSample/GCProgressSample/AppDelegate.swift
================================================
//
// AppDelegate.swift
// GCProgressSample
//
// Created by keygx on 2015/06/21.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
private func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
================================================
FILE: GCProgressSample/GCProgressSample/AsyncUtil.swift
================================================
//
// AsyncUtil.swift
// GCProgressSample
//
// Created by keygx on 2016/02/20.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import Foundation
class AsyncUtil {
func dispatchOnMainThread(_ block: @escaping () -> (), delay: Double) {
if delay == 0 {
DispatchQueue.main.async {
block()
}
return
}
let d = DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: d) {
block()
}
}
}
================================================
FILE: GCProgressSample/GCProgressSample/BackgroundTransparentStyle.swift
================================================
//
// BackgroundTransparentStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2016/12/03.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import GradientCircularProgress
public struct BackgroundTransparentStyle: StyleProperty {
/*** style properties **********************************************************************************/
// Progress Size
public var progressSize: CGFloat = 200
// Gradient Circular
public var arcLineWidth: CGFloat = 4.0
public var startArcColor: UIColor = ColorUtil.toUIColor(r: 0.0, g: 122.0, b: 255.0, a: 1.0)
public var endArcColor: UIColor = UIColor.cyan
// Base Circular
public var baseLineWidth: CGFloat? = 6.0
public var baseArcColor: UIColor? = UIColor(red:0.0, green: 0.0, blue: 0.0, alpha: 0.2)
// Ratio
public var ratioLabelFont: UIFont? = UIFont.systemFont(ofSize: 16.0)
public var ratioLabelFontColor: UIColor? = UIColor.black
// Message
public var messageLabelFont: UIFont? = UIFont.systemFont(ofSize: 16.0)
public var messageLabelFontColor: UIColor? = UIColor.black
// Background
public var backgroundStyle: BackgroundStyles = .transparent
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
/*** style properties **********************************************************************************/
public init() {}
}
================================================
FILE: GCProgressSample/GCProgressSample/Base.lproj/LaunchScreen.xib
================================================
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_0" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="GCProgressSample" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="139.5" width="440" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
</document>
================================================
FILE: GCProgressSample/GCProgressSample/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="GCProgressSample" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="14u-O2-CKF">
<rect key="frame" x="0.0" y="80" width="375" height="40"/>
<color key="backgroundColor" red="0.84705882352941175" green="0.84705882352941175" blue="0.84705882352941175" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="X4i-OC-iK1"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7rc-3Q-ddQ">
<rect key="frame" x="117" y="124" width="140" height="28"/>
<constraints>
<constraint firstAttribute="height" constant="28" id="P3A-Qv-Bhn"/>
<constraint firstAttribute="width" constant="140" id="l71-eE-CY3"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" title="Choose Style"/>
<connections>
<action selector="btnChooseStyleAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="Mv0-jr-lpc"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iZP-hJ-h5b" customClass="MyButton" customModule="GCProgressSample" customModuleProvider="target">
<rect key="frame" x="20" y="607" width="335" height="40"/>
<constraints>
<constraint firstAttribute="width" constant="560" id="UEd-zK-JjE"/>
<constraint firstAttribute="height" constant="40" id="tKM-G9-JlM"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" title="Update Message"/>
<variation key="default">
<mask key="constraints">
<exclude reference="UEd-zK-JjE"/>
</mask>
</variation>
<connections>
<action selector="btnUpdateMessageAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="9aR-L7-2tw"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IZo-36-T7V" customClass="MyButton" customModule="GCProgressSample" customModuleProvider="target">
<rect key="frame" x="20" y="557" width="335" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="7O2-P4-a6D"/>
<constraint firstAttribute="width" constant="560" id="MKp-AB-eGC"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" title="Basic"/>
<variation key="default">
<mask key="constraints">
<exclude reference="MKp-AB-eGC"/>
</mask>
</variation>
<connections>
<action selector="btnBasicAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="a8V-va-ahk"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Hvr-2X-bR2" customClass="MyButton" customModule="GCProgressSample" customModuleProvider="target">
<rect key="frame" x="20" y="507" width="335" height="40"/>
<constraints>
<constraint firstAttribute="width" constant="560" id="0XB-wQ-jLr"/>
<constraint firstAttribute="height" constant="40" id="qk4-VJ-x8C"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<state key="normal" title="at Ratio"/>
<variation key="default">
<mask key="constraints">
<exclude reference="0XB-wQ-jLr"/>
</mask>
</variation>
<connections>
<action selector="btnAtRatioAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="T2m-vo-6Ue"/>
</connections>
</button>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="p5D-XQ-8cA">
<rect key="frame" x="20" y="36" width="335" height="29"/>
<segments>
<segment title="UIWindow"/>
<segment title="addSubView"/>
</segments>
<connections>
<action selector="segmentedControlAction:" destination="BYZ-38-t0r" eventType="valueChanged" id="mrb-th-vDk"/>
</connections>
</segmentedControl>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="iZP-hJ-h5b" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" constant="20" id="0bi-ow-fhy"/>
<constraint firstItem="p5D-XQ-8cA" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="16" id="2VA-BK-BQR"/>
<constraint firstAttribute="trailing" secondItem="iZP-hJ-h5b" secondAttribute="trailing" constant="20" id="2iH-8F-Atp"/>
<constraint firstItem="IZo-36-T7V" firstAttribute="top" secondItem="Hvr-2X-bR2" secondAttribute="bottom" constant="10" id="6rB-Rs-Y4T"/>
<constraint firstItem="7rc-3Q-ddQ" firstAttribute="top" secondItem="14u-O2-CKF" secondAttribute="bottom" constant="4" id="8Wy-kA-hAo"/>
<constraint firstItem="14u-O2-CKF" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="IKq-Ow-nBT"/>
<constraint firstItem="14u-O2-CKF" firstAttribute="top" secondItem="p5D-XQ-8cA" secondAttribute="bottom" constant="16" id="Nva-VJ-B6j"/>
<constraint firstItem="IZo-36-T7V" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" constant="20" id="T4X-bj-hx6"/>
<constraint firstAttribute="trailing" secondItem="IZo-36-T7V" secondAttribute="trailing" constant="20" id="Tc9-n1-lxi"/>
<constraint firstItem="7rc-3Q-ddQ" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="WDH-iy-XO8"/>
<constraint firstItem="Hvr-2X-bR2" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" constant="20" id="bIg-OL-gUs"/>
<constraint firstItem="p5D-XQ-8cA" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" constant="20" id="bQn-AN-jxl"/>
<constraint firstItem="iZP-hJ-h5b" firstAttribute="top" secondItem="IZo-36-T7V" secondAttribute="bottom" constant="10" id="hMh-oS-JVW"/>
<constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="iZP-hJ-h5b" secondAttribute="bottom" constant="20" id="jxc-o1-hcQ"/>
<constraint firstAttribute="trailing" secondItem="Hvr-2X-bR2" secondAttribute="trailing" constant="20" id="k80-m2-GXu"/>
<constraint firstAttribute="trailing" secondItem="14u-O2-CKF" secondAttribute="trailing" id="kLu-DU-4eP"/>
<constraint firstAttribute="trailing" secondItem="p5D-XQ-8cA" secondAttribute="trailing" constant="20" id="yXU-o4-JcL"/>
</constraints>
</view>
<connections>
<outlet property="btnAtRatio" destination="Hvr-2X-bR2" id="2by-N2-74j"/>
<outlet property="btnBasic" destination="IZo-36-T7V" id="Jzp-Ix-5Ds"/>
<outlet property="btnUpdateMessage" destination="iZP-hJ-h5b" id="PsA-c4-vTc"/>
<outlet property="segmentedControl" destination="p5D-XQ-8cA" id="R87-xN-24E"/>
<outlet property="styleLabel" destination="14u-O2-CKF" id="XF2-lH-n9P"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="348.5" y="248.5"/>
</scene>
</scenes>
</document>
================================================
FILE: GCProgressSample/GCProgressSample/Images.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: GCProgressSample/GCProgressSample/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
================================================
FILE: GCProgressSample/GCProgressSample/MyButton.swift
================================================
//
// MyButton.swift
// GCProgressSample
//
// Created by keygx on 2016/03/12.
// Copyright © 2016年 keygx. All rights reserved.
//
import UIKit
class MyButton: UIButton {
enum ButtonStatus {
case normal
case highlighted
case selected
case disabled
}
var status: ButtonStatus = .normal {
didSet {
switch status {
case .disabled:
isEnabled = false
default:
isEnabled = true
}
apply()
}
}
private let defaultColor: UIColor = UIColor(red: 0.0/255.0, green: 122.0/255.0, blue: 255.0/255.0, alpha: 1.0)
private let disabledColor: UIColor = UIColor.lightGray
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
private func initialize() {
status = .normal
layer.cornerRadius = 4.0
layer.borderWidth = 1.0
}
func apply() {
switch status {
case .disabled:
setTitleColor(disabledColor, for: .disabled)
layer.borderColor = disabledColor.cgColor
default:
setTitleColor(defaultColor, for: UIControl.State())
layer.borderColor = defaultColor.cgColor
}
}
}
================================================
FILE: GCProgressSample/GCProgressSample/MyStyle.swift
================================================
//
// MyStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/11/25.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import GradientCircularProgress
public struct MyStyle: StyleProperty {
/*** style properties **********************************************************************************/
// Progress Size
public var progressSize: CGFloat = 200
// Gradient Circular
public var arcLineWidth: CGFloat = 18.0
public var startArcColor: UIColor = UIColor.clear
public var endArcColor: UIColor = UIColor.orange
// Base Circular
public var baseLineWidth: CGFloat? = 19.0
public var baseArcColor: UIColor? = UIColor.darkGray
// Ratio
public var ratioLabelFont: UIFont? = UIFont(name: "Verdana-Bold", size: 16.0)
public var ratioLabelFontColor: UIColor? = UIColor.white
// Message
public var messageLabelFont: UIFont? = UIFont.systemFont(ofSize: 16.0)
public var messageLabelFontColor: UIColor? = UIColor.white
// Background
public var backgroundStyle: BackgroundStyles = .dark
// Dismiss
public var dismissTimeInterval: Double? = 0.0 // 'nil' for default setting.
/*** style properties **********************************************************************************/
public init() {}
}
================================================
FILE: GCProgressSample/GCProgressSample/ViewController.swift
================================================
//
// ViewController.swift
// GCProgressSample
//
// Created by keygx on 2016/03/12.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
import GradientCircularProgress
class ViewController: UIViewController {
// UI
enum UsageType {
case window
case subView
}
let styleList: [(String, StyleProperty)] = [
("Style.swift", Style()),
("BlueDarkStyle.swift", BlueDarkStyle()),
("OrangeClearStyle.swift", OrangeClearStyle()),
("GreenLightStyle.swift", GreenLightStyle()),
("BlueIndicatorStyle.swift", BlueIndicatorStyle()),
("MyStyle.swift", MyStyle()),
("BackgroundTransparentStyle", BackgroundTransparentStyle()),
]
var usageType: UsageType = .window
var seletedStyleIndex: Int = 0 {
willSet {
styleLabel.text = styleList[newValue].0
}
}
@IBOutlet weak var segmentedControl: UISegmentedControl!
@IBOutlet weak var styleLabel: UILabel!
@IBOutlet weak var btnAtRatio: MyButton!
@IBOutlet weak var btnBasic: MyButton!
@IBOutlet weak var btnUpdateMessage: MyButton!
// Progress
let progress = GradientCircularProgress()
var progressView: UIView?
// Demo
var timer: Timer?
var v: Double = 0.0
override func viewDidLoad() {
super.viewDidLoad()
usageType = .window
seletedStyleIndex = 0
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func segmentedControlAction(_ sender: AnyObject) {
switch sender.selectedSegmentIndex {
case 0:
usageType = .window
case 1:
usageType = .subView
default:
break
}
}
@IBAction func btnChooseStyleAction(_ sender: AnyObject) {
let styleTitleList: [String] = styleList.map {$0.0}
let params = Parameters(
title: nil,
message: nil,
cancelButton: "Cancel",
otherButtons: styleTitleList
)
AlertHelperKit().showAlertWithHandler(self, parameters: params) { buttonIndex in
switch buttonIndex {
case 1:
self.seletedStyleIndex = buttonIndex - 1
self.btnUpdateMessage.status = .normal
case 2:
self.seletedStyleIndex = buttonIndex - 1
self.btnUpdateMessage.status = .normal
case 3:
self.seletedStyleIndex = buttonIndex - 1
self.btnUpdateMessage.status = .disabled
case 4:
self.seletedStyleIndex = buttonIndex - 1
self.btnUpdateMessage.status = .normal
case 5:
self.seletedStyleIndex = buttonIndex - 1
self.btnUpdateMessage.status = .disabled
case 6:
self.seletedStyleIndex = buttonIndex - 1
self.btnUpdateMessage.status = .normal
case 7:
self.seletedStyleIndex = buttonIndex - 1
self.btnUpdateMessage.status = .normal
default: break
// Cancel
}
}
}
@IBAction func btnAtRatioAction(_ sender: AnyObject) {
if progress.isAvailable {
return
}
if usageType == .window {
showAtRatio()
} else {
showAtRatioTypeSubView()
}
}
@IBAction func btnBasicAction(_ sender: AnyObject) {
if progress.isAvailable {
return
}
if usageType == .window {
showBasic()
} else {
showBasicTypeSubView()
}
}
@IBAction func btnUpdateMessageAction(_ sender: AnyObject) {
if progress.isAvailable {
return
}
if usageType == .window {
showUpdateMessage()
} else {
showUpdateMessageTypeSubView()
}
}
}
// UIWindow
extension ViewController {
func showAtRatio() {
var displayFlag: Bool
switch seletedStyleIndex {
case 4:
displayFlag = false
default:
displayFlag = true
}
progress.showAtRatio(display: displayFlag, style: styleList[seletedStyleIndex].1)
startProgressAtRatio()
}
func showBasic() {
progress.show(message: "Loading...", style: styleList[seletedStyleIndex].1)
delayCloseProgress()
}
func showUpdateMessage() {
progress.show(message: "Download\n0 / 4", style: styleList[seletedStyleIndex].1)
startProgressBasic()
}
}
// SubView
extension ViewController {
func showAtRatioTypeSubView() {
var displayFlag: Bool
switch seletedStyleIndex {
case 4:
displayFlag = false
default:
displayFlag = true
}
progressView = progress.showAtRatio(frame: getRect(), display: displayFlag, style: styleList[seletedStyleIndex].1)
progressView?.layer.cornerRadius = 12.0
view.addSubview(progressView!)
startProgressAtRatio()
}
func showBasicTypeSubView() {
progressView = progress.show(frame: getRect(), message: "Loading...", style: styleList[seletedStyleIndex].1)
progressView?.layer.cornerRadius = 12.0
view.addSubview(progressView!)
delayCloseProgress()
}
func showUpdateMessageTypeSubView() {
progressView = progress.show(frame: getRect(), message: "Download\n0 / 4", style: styleList[seletedStyleIndex].1)
progressView?.layer.cornerRadius = 12.0
view.addSubview(progressView!)
startProgressBasic()
}
}
// for demo
extension ViewController {
func delayCloseProgress() {
AsyncUtil().dispatchOnMainThread({
switch self.usageType {
case .window:
self.progress.dismiss()
case .subView:
self.progress.dismiss(progress: self.progressView!)
}
},
delay: 2.0)
}
func startProgressBasic() {
v = 0.0
timer = Timer.scheduledTimer(
timeInterval: 0.01,
target: self,
selector: #selector(updateMessage),
userInfo: nil,
repeats: true
)
RunLoop.main.add(timer!, forMode: RunLoop.Mode.common)
}
@objc func updateMessage() {
v += 0.002
if v > 1.00 {
progress.updateMessage(message: "Download\n4 / 4")
timer!.invalidate()
AsyncUtil().dispatchOnMainThread({
self.progress.updateMessage(message: "Completed!")
switch self.usageType {
case .window:
self.progress.dismiss()
case .subView:
self.progress.dismiss(progress: self.progressView!)
}
}, delay: 0.8)
return
} else if v > 0.75 {
progress.updateMessage(message: "Download\n3 / 4")
} else if v > 0.5 {
progress.updateMessage(message: "Download\n2 / 4")
} else if v > 0.25 {
progress.updateMessage(message: "Download\n1 / 4")
}
}
func startProgressAtRatio() {
v = 0.0
timer = Timer.scheduledTimer(
timeInterval: 0.01,
target: self,
selector: #selector(updateProgressAtRatio),
userInfo: nil,
repeats: true
)
RunLoop.main.add(timer!, forMode: RunLoop.Mode.common)
}
@objc func updateProgressAtRatio() {
v += 0.01
progress.updateRatio(CGFloat(v))
if v > 1.00 {
timer!.invalidate()
switch usageType {
case .window:
progress.dismiss()
case .subView:
progress.dismiss(progress: progressView!)
}
return
}
}
func getRect() -> CGRect {
return CGRect(
x: view.frame.origin.x + 15,
y: (view.frame.size.height - view.frame.size.width) / 2,
width: view.frame.size.width - 30,
height: view.frame.size.width - 30)
}
}
================================================
FILE: GCProgressSample/GCProgressSample.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
360F44AB1DF27B2800835EA0 /* BackgroundTransparentStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 360F44AA1DF27B2800835EA0 /* BackgroundTransparentStyle.swift */; };
362C51F91C9AB926008C1C81 /* AlertHelperKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 362C51F81C9AB926008C1C81 /* AlertHelperKit.swift */; };
3632ED251C7833CD006484E5 /* AsyncUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3632ED241C7833CD006484E5 /* AsyncUtil.swift */; };
366555DE1C9D900F00767B90 /* MyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366555DD1C9D900F00767B90 /* MyButton.swift */; };
3667E0ED23392FEC002CCD9C /* WindowBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3667E0EC23392FEC002CCD9C /* WindowBuilder.swift */; };
368F0E4E1C35319E008B1AC4 /* MyStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 368F0E4D1C35319E008B1AC4 /* MyStyle.swift */; };
36CC1C821B37083E009DE1F8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CC1C811B37083E009DE1F8 /* AppDelegate.swift */; };
36CC1C841B37083E009DE1F8 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CC1C831B37083E009DE1F8 /* ViewController.swift */; };
36CC1C871B37083E009DE1F8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 36CC1C851B37083E009DE1F8 /* Main.storyboard */; };
36CC1C891B37083E009DE1F8 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 36CC1C881B37083E009DE1F8 /* Images.xcassets */; };
36CC1C8C1B37083E009DE1F8 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 36CC1C8A1B37083E009DE1F8 /* LaunchScreen.xib */; };
36CC1C981B37083E009DE1F8 /* GCProgressSampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CC1C971B37083E009DE1F8 /* GCProgressSampleTests.swift */; };
36CE2B5D1C93EA740084CE64 /* GradientCircularProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B471C93EA740084CE64 /* GradientCircularProgress.swift */; };
36CE2B5E1C93EA740084CE64 /* CircularProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B4A1C93EA740084CE64 /* CircularProgressView.swift */; };
36CE2B5F1C93EA740084CE64 /* ProgressAtRatioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B4B1C93EA740084CE64 /* ProgressAtRatioView.swift */; };
36CE2B601C93EA740084CE64 /* ArcView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B4D1C93EA740084CE64 /* ArcView.swift */; };
36CE2B611C93EA740084CE64 /* Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B4E1C93EA740084CE64 /* Background.swift */; };
36CE2B631C93EA740084CE64 /* GradientArcView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B501C93EA740084CE64 /* GradientArcView.swift */; };
36CE2B641C93EA740084CE64 /* GradientArcWithClearColorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B511C93EA740084CE64 /* GradientArcWithClearColorView.swift */; };
36CE2B651C93EA740084CE64 /* ProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B521C93EA740084CE64 /* ProgressView.swift */; };
36CE2B661C93EA740084CE64 /* ProgressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B531C93EA740084CE64 /* ProgressViewController.swift */; };
36CE2B671C93EA740084CE64 /* Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B541C93EA740084CE64 /* Property.swift */; };
36CE2B681C93EA740084CE64 /* BlueDarkStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B561C93EA740084CE64 /* BlueDarkStyle.swift */; };
36CE2B691C93EA740084CE64 /* BlueIndicatorStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B571C93EA740084CE64 /* BlueIndicatorStyle.swift */; };
36CE2B6A1C93EA740084CE64 /* GreenLightStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B581C93EA740084CE64 /* GreenLightStyle.swift */; };
36CE2B6B1C93EA740084CE64 /* OrangeClearStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B591C93EA740084CE64 /* OrangeClearStyle.swift */; };
36CE2B6C1C93EA740084CE64 /* Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B5A1C93EA740084CE64 /* Style.swift */; };
36CE2B6D1C93EA740084CE64 /* ColorUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36CE2B5C1C93EA740084CE64 /* ColorUtil.swift */; };
36F742C01B3A7016003D799C /* GradientCircularProgress.h in Headers */ = {isa = PBXBuildFile; fileRef = 36F742BF1B3A7016003D799C /* GradientCircularProgress.h */; settings = {ATTRIBUTES = (Public, ); }; };
36F742D21B3A7016003D799C /* GradientCircularProgress.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36F742BB1B3A7016003D799C /* GradientCircularProgress.framework */; };
36F742D31B3A7016003D799C /* GradientCircularProgress.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 36F742BB1B3A7016003D799C /* GradientCircularProgress.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
36CC1C921B37083E009DE1F8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 36CC1C741B37083E009DE1F8 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 36CC1C7B1B37083E009DE1F8;
remoteInfo = GCProgressSample;
};
36F742D01B3A7016003D799C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 36CC1C741B37083E009DE1F8 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 36F742BA1B3A7016003D799C;
remoteInfo = GradientCircularProgress;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
36F742D91B3A7016003D799C /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
36F742D31B3A7016003D799C /* GradientCircularProgress.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
360F44AA1DF27B2800835EA0 /* BackgroundTransparentStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundTransparentStyle.swift; sourceTree = "<group>"; };
362C51F81C9AB926008C1C81 /* AlertHelperKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertHelperKit.swift; sourceTree = "<group>"; };
3632ED241C7833CD006484E5 /* AsyncUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncUtil.swift; sourceTree = "<group>"; };
366555DD1C9D900F00767B90 /* MyButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyButton.swift; sourceTree = "<group>"; };
3667E0EC23392FEC002CCD9C /* WindowBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowBuilder.swift; sourceTree = "<group>"; };
368F0E4D1C35319E008B1AC4 /* MyStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyStyle.swift; sourceTree = "<group>"; };
36CC1C7C1B37083E009DE1F8 /* GCProgressSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GCProgressSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
36CC1C801B37083E009DE1F8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
36CC1C811B37083E009DE1F8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
36CC1C831B37083E009DE1F8 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
36CC1C861B37083E009DE1F8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
36CC1C881B37083E009DE1F8 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
36CC1C8B1B37083E009DE1F8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
36CC1C911B37083E009DE1F8 /* GCProgressSampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GCProgressSampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
36CC1C961B37083E009DE1F8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
36CC1C971B37083E009DE1F8 /* GCProgressSampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GCProgressSampleTests.swift; sourceTree = "<group>"; };
36CE2B471C93EA740084CE64 /* GradientCircularProgress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientCircularProgress.swift; sourceTree = "<group>"; };
36CE2B4A1C93EA740084CE64 /* CircularProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircularProgressView.swift; sourceTree = "<group>"; };
36CE2B4B1C93EA740084CE64 /* ProgressAtRatioView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressAtRatioView.swift; sourceTree = "<group>"; };
36CE2B4D1C93EA740084CE64 /* ArcView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArcView.swift; sourceTree = "<group>"; };
36CE2B4E1C93EA740084CE64 /* Background.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Background.swift; sourceTree = "<group>"; };
36CE2B501C93EA740084CE64 /* GradientArcView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientArcView.swift; sourceTree = "<group>"; };
36CE2B511C93EA740084CE64 /* GradientArcWithClearColorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientArcWithClearColorView.swift; sourceTree = "<group>"; };
36CE2B521C93EA740084CE64 /* ProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressView.swift; sourceTree = "<group>"; };
36CE2B531C93EA740084CE64 /* ProgressViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressViewController.swift; sourceTree = "<group>"; };
36CE2B541C93EA740084CE64 /* Property.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Property.swift; sourceTree = "<group>"; };
36CE2B561C93EA740084CE64 /* BlueDarkStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlueDarkStyle.swift; sourceTree = "<group>"; };
36CE2B571C93EA740084CE64 /* BlueIndicatorStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlueIndicatorStyle.swift; sourceTree = "<group>"; };
36CE2B581C93EA740084CE64 /* GreenLightStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GreenLightStyle.swift; sourceTree = "<group>"; };
36CE2B591C93EA740084CE64 /* OrangeClearStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrangeClearStyle.swift; sourceTree = "<group>"; };
36CE2B5A1C93EA740084CE64 /* Style.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Style.swift; sourceTree = "<group>"; };
36CE2B5C1C93EA740084CE64 /* ColorUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorUtil.swift; sourceTree = "<group>"; };
36F742BB1B3A7016003D799C /* GradientCircularProgress.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GradientCircularProgress.framework; sourceTree = BUILT_PRODUCTS_DIR; };
36F742BE1B3A7016003D799C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
36F742BF1B3A7016003D799C /* GradientCircularProgress.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GradientCircularProgress.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
36CC1C791B37083E009DE1F8 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
36F742D21B3A7016003D799C /* GradientCircularProgress.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
36CC1C8E1B37083E009DE1F8 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
36F742B71B3A7016003D799C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
366555DA1C9D8BB600767B90 /* libs */ = {
isa = PBXGroup;
children = (
362C51F81C9AB926008C1C81 /* AlertHelperKit.swift */,
3632ED241C7833CD006484E5 /* AsyncUtil.swift */,
366555DD1C9D900F00767B90 /* MyButton.swift */,
);
name = libs;
sourceTree = "<group>";
};
36CC1C731B37083E009DE1F8 = {
isa = PBXGroup;
children = (
36CC1C7E1B37083E009DE1F8 /* GCProgressSample */,
36CC1C941B37083E009DE1F8 /* GCProgressSampleTests */,
36F742BC1B3A7016003D799C /* GradientCircularProgress */,
36CC1C7D1B37083E009DE1F8 /* Products */,
);
sourceTree = "<group>";
};
36CC1C7D1B37083E009DE1F8 /* Products */ = {
isa = PBXGroup;
children = (
36CC1C7C1B37083E009DE1F8 /* GCProgressSample.app */,
36CC1C911B37083E009DE1F8 /* GCProgressSampleTests.xctest */,
36F742BB1B3A7016003D799C /* GradientCircularProgress.framework */,
);
name = Products;
sourceTree = "<group>";
};
36CC1C7E1B37083E009DE1F8 /* GCProgressSample */ = {
isa = PBXGroup;
children = (
366555DA1C9D8BB600767B90 /* libs */,
36CC1C811B37083E009DE1F8 /* AppDelegate.swift */,
36CC1C831B37083E009DE1F8 /* ViewController.swift */,
368F0E4D1C35319E008B1AC4 /* MyStyle.swift */,
360F44AA1DF27B2800835EA0 /* BackgroundTransparentStyle.swift */,
36CC1C851B37083E009DE1F8 /* Main.storyboard */,
36CC1C881B37083E009DE1F8 /* Images.xcassets */,
36CC1C8A1B37083E009DE1F8 /* LaunchScreen.xib */,
36CC1C7F1B37083E009DE1F8 /* Supporting Files */,
);
path = GCProgressSample;
sourceTree = "<group>";
};
36CC1C7F1B37083E009DE1F8 /* Supporting Files */ = {
isa = PBXGroup;
children = (
36CC1C801B37083E009DE1F8 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
36CC1C941B37083E009DE1F8 /* GCProgressSampleTests */ = {
isa = PBXGroup;
children = (
36CC1C971B37083E009DE1F8 /* GCProgressSampleTests.swift */,
36CC1C951B37083E009DE1F8 /* Supporting Files */,
);
path = GCProgressSampleTests;
sourceTree = "<group>";
};
36CC1C951B37083E009DE1F8 /* Supporting Files */ = {
isa = PBXGroup;
children = (
36CC1C961B37083E009DE1F8 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
36CE2B481C93EA740084CE64 /* Progress */ = {
isa = PBXGroup;
children = (
36CE2B491C93EA740084CE64 /* Core */,
36CE2B4C1C93EA740084CE64 /* Elements */,
36CE2B521C93EA740084CE64 /* ProgressView.swift */,
36CE2B531C93EA740084CE64 /* ProgressViewController.swift */,
36CE2B541C93EA740084CE64 /* Property.swift */,
);
path = Progress;
sourceTree = "<group>";
};
36CE2B491C93EA740084CE64 /* Core */ = {
isa = PBXGroup;
children = (
36CE2B4A1C93EA740084CE64 /* CircularProgressView.swift */,
36CE2B4B1C93EA740084CE64 /* ProgressAtRatioView.swift */,
);
path = Core;
sourceTree = "<group>";
};
36CE2B4C1C93EA740084CE64 /* Elements */ = {
isa = PBXGroup;
children = (
36CE2B4D1C93EA740084CE64 /* ArcView.swift */,
36CE2B4E1C93EA740084CE64 /* Background.swift */,
3667E0EC23392FEC002CCD9C /* WindowBuilder.swift */,
36CE2B501C93EA740084CE64 /* GradientArcView.swift */,
36CE2B511C93EA740084CE64 /* GradientArcWithClearColorView.swift */,
);
path = Elements;
sourceTree = "<group>";
};
36CE2B551C93EA740084CE64 /* Styles */ = {
isa = PBXGroup;
children = (
36CE2B561C93EA740084CE64 /* BlueDarkStyle.swift */,
36CE2B571C93EA740084CE64 /* BlueIndicatorStyle.swift */,
36CE2B581C93EA740084CE64 /* GreenLightStyle.swift */,
36CE2B591C93EA740084CE64 /* OrangeClearStyle.swift */,
36CE2B5A1C93EA740084CE64 /* Style.swift */,
);
path = Styles;
sourceTree = "<group>";
};
36CE2B5B1C93EA740084CE64 /* Utils */ = {
isa = PBXGroup;
children = (
36CE2B5C1C93EA740084CE64 /* ColorUtil.swift */,
);
path = Utils;
sourceTree = "<group>";
};
36F742BC1B3A7016003D799C /* GradientCircularProgress */ = {
isa = PBXGroup;
children = (
36CE2B471C93EA740084CE64 /* GradientCircularProgress.swift */,
36CE2B481C93EA740084CE64 /* Progress */,
36CE2B551C93EA740084CE64 /* Styles */,
36CE2B5B1C93EA740084CE64 /* Utils */,
36F742BF1B3A7016003D799C /* GradientCircularProgress.h */,
36F742BD1B3A7016003D799C /* Supporting Files */,
);
path = GradientCircularProgress;
sourceTree = "<group>";
};
36F742BD1B3A7016003D799C /* Supporting Files */ = {
isa = PBXGroup;
children = (
36F742BE1B3A7016003D799C /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
36F742B81B3A7016003D799C /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
36F742C01B3A7016003D799C /* GradientCircularProgress.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
36CC1C7B1B37083E009DE1F8 /* GCProgressSample */ = {
isa = PBXNativeTarget;
buildConfigurationList = 36CC1C9B1B37083E009DE1F8 /* Build configuration list for PBXNativeTarget "GCProgressSample" */;
buildPhases = (
36CC1C781B37083E009DE1F8 /* Sources */,
36CC1C791B37083E009DE1F8 /* Frameworks */,
36CC1C7A1B37083E009DE1F8 /* Resources */,
36F742D91B3A7016003D799C /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
36F742D11B3A7016003D799C /* PBXTargetDependency */,
);
name = GCProgressSample;
productName = GCProgressSample;
productReference = 36CC1C7C1B37083E009DE1F8 /* GCProgressSample.app */;
productType = "com.apple.product-type.application";
};
36CC1C901B37083E009DE1F8 /* GCProgressSampleTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 36CC1C9E1B37083E009DE1F8 /* Build configuration list for PBXNativeTarget "GCProgressSampleTests" */;
buildPhases = (
36CC1C8D1B37083E009DE1F8 /* Sources */,
36CC1C8E1B37083E009DE1F8 /* Frameworks */,
36CC1C8F1B37083E009DE1F8 /* Resources */,
);
buildRules = (
);
dependencies = (
36CC1C931B37083E009DE1F8 /* PBXTargetDependency */,
);
name = GCProgressSampleTests;
productName = GCProgressSampleTests;
productReference = 36CC1C911B37083E009DE1F8 /* GCProgressSampleTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
36F742BA1B3A7016003D799C /* GradientCircularProgress */ = {
isa = PBXNativeTarget;
buildConfigurationList = 36F742D81B3A7016003D799C /* Build configuration list for PBXNativeTarget "GradientCircularProgress" */;
buildPhases = (
36F742B61B3A7016003D799C /* Sources */,
36F742B71B3A7016003D799C /* Frameworks */,
36F742B81B3A7016003D799C /* Headers */,
36F742B91B3A7016003D799C /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = GradientCircularProgress;
productName = GradientCircularProgress;
productReference = 36F742BB1B3A7016003D799C /* GradientCircularProgress.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
36CC1C741B37083E009DE1F8 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftMigration = 0700;
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 1100;
ORGANIZATIONNAME = keygx;
TargetAttributes = {
36CC1C7B1B37083E009DE1F8 = {
CreatedOnToolsVersion = 6.3.2;
DevelopmentTeam = 3CCNMX7TC9;
DevelopmentTeamName = "Yukihiko Kagiyama";
LastSwiftMigration = 1020;
ProvisioningStyle = Automatic;
};
36CC1C901B37083E009DE1F8 = {
CreatedOnToolsVersion = 6.3.2;
LastSwiftMigration = 0800;
TestTargetID = 36CC1C7B1B37083E009DE1F8;
};
36F742BA1B3A7016003D799C = {
CreatedOnToolsVersion = 6.3.2;
DevelopmentTeamName = "Yukihiko Kagiyama";
LastSwiftMigration = 1020;
};
};
};
buildConfigurationList = 36CC1C771B37083E009DE1F8 /* Build configuration list for PBXProject "GCProgressSample" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 36CC1C731B37083E009DE1F8;
productRefGroup = 36CC1C7D1B37083E009DE1F8 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
36CC1C7B1B37083E009DE1F8 /* GCProgressSample */,
36CC1C901B37083E009DE1F8 /* GCProgressSampleTests */,
36F742BA1B3A7016003D799C /* GradientCircularProgress */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
36CC1C7A1B37083E009DE1F8 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
36CC1C871B37083E009DE1F8 /* Main.storyboard in Resources */,
36CC1C8C1B37083E009DE1F8 /* LaunchScreen.xib in Resources */,
36CC1C891B37083E009DE1F8 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
36CC1C8F1B37083E009DE1F8 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
36F742B91B3A7016003D799C /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
36CC1C781B37083E009DE1F8 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
36CC1C841B37083E009DE1F8 /* ViewController.swift in Sources */,
362C51F91C9AB926008C1C81 /* AlertHelperKit.swift in Sources */,
360F44AB1DF27B2800835EA0 /* BackgroundTransparentStyle.swift in Sources */,
36CC1C821B37083E009DE1F8 /* AppDelegate.swift in Sources */,
3632ED251C7833CD006484E5 /* AsyncUtil.swift in Sources */,
368F0E4E1C35319E008B1AC4 /* MyStyle.swift in Sources */,
366555DE1C9D900F00767B90 /* MyButton.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
36CC1C8D1B37083E009DE1F8 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
36CC1C981B37083E009DE1F8 /* GCProgressSampleTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
36F742B61B3A7016003D799C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
36CE2B5F1C93EA740084CE64 /* ProgressAtRatioView.swift in Sources */,
3667E0ED23392FEC002CCD9C /* WindowBuilder.swift in Sources */,
36CE2B681C93EA740084CE64 /* BlueDarkStyle.swift in Sources */,
36CE2B601C93EA740084CE64 /* ArcView.swift in Sources */,
36CE2B671C93EA740084CE64 /* Property.swift in Sources */,
36CE2B5E1C93EA740084CE64 /* CircularProgressView.swift in Sources */,
36CE2B5D1C93EA740084CE64 /* GradientCircularProgress.swift in Sources */,
36CE2B631C93EA740084CE64 /* GradientArcView.swift in Sources */,
36CE2B6C1C93EA740084CE64 /* Style.swift in Sources */,
36CE2B661C93EA740084CE64 /* ProgressViewController.swift in Sources */,
36CE2B611C93EA740084CE64 /* Background.swift in Sources */,
36CE2B641C93EA740084CE64 /* GradientArcWithClearColorView.swift in Sources */,
36CE2B6B1C93EA740084CE64 /* OrangeClearStyle.swift in Sources */,
36CE2B651C93EA740084CE64 /* ProgressView.swift in Sources */,
36CE2B6A1C93EA740084CE64 /* GreenLightStyle.swift in Sources */,
36CE2B691C93EA740084CE64 /* BlueIndicatorStyle.swift in Sources */,
36CE2B6D1C93EA740084CE64 /* ColorUtil.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
36CC1C931B37083E009DE1F8 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 36CC1C7B1B37083E009DE1F8 /* GCProgressSample */;
targetProxy = 36CC1C921B37083E009DE1F8 /* PBXContainerItemProxy */;
};
36F742D11B3A7016003D799C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 36F742BA1B3A7016003D799C /* GradientCircularProgress */;
targetProxy = 36F742D01B3A7016003D799C /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
36CC1C851B37083E009DE1F8 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
36CC1C861B37083E009DE1F8 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
36CC1C8A1B37083E009DE1F8 /* LaunchScreen.xib */ = {
isa = PBXVariantGroup;
children = (
36CC1C8B1B37083E009DE1F8 /* Base */,
);
name = LaunchScreen.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
36CC1C991B37083E009DE1F8 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
BITCODE_GENERATION_MODE = marker;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = 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_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_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
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 = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = "";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
36CC1C9A1B37083E009DE1F8 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
BITCODE_GENERATION_MODE = bitcode;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = 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_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_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
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 = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_VERSION = "";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
36CC1C9C1B37083E009DE1F8 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 3.13.0;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/GCProgressSample",
);
INFOPLIST_FILE = GCProgressSample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 3.13.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.keygraphix.ios.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
36CC1C9D1B37083E009DE1F8 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CURRENT_PROJECT_VERSION = 3.13.0;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/GCProgressSample",
);
INFOPLIST_FILE = GCProgressSample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 3.13.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.keygraphix.ios.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
};
name = Release;
};
36CC1C9F1B37083E009DE1F8 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = GCProgressSampleTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.keygraphix.ios.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GCProgressSample.app/GCProgressSample";
};
name = Debug;
};
36CC1CA01B37083E009DE1F8 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = GCProgressSampleTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.keygraphix.ios.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GCProgressSample.app/GCProgressSample";
};
name = Release;
};
36F742D41B3A7016003D799C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
CURRENT_PROJECT_VERSION = 3.13.0;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = GradientCircularProgress/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 3.13.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.keygraphix.ios.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
36F742D51B3A7016003D799C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
CURRENT_PROJECT_VERSION = 3.13.0;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = GradientCircularProgress/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 3.13.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.keygraphix.ios.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
36CC1C771B37083E009DE1F8 /* Build configuration list for PBXProject "GCProgressSample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
36CC1C991B37083E009DE1F8 /* Debug */,
36CC1C9A1B37083E009DE1F8 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
36CC1C9B1B37083E009DE1F8 /* Build configuration list for PBXNativeTarget "GCProgressSample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
36CC1C9C1B37083E009DE1F8 /* Debug */,
36CC1C9D1B37083E009DE1F8 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
36CC1C9E1B37083E009DE1F8 /* Build configuration list for PBXNativeTarget "GCProgressSampleTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
36CC1C9F1B37083E009DE1F8 /* Debug */,
36CC1CA01B37083E009DE1F8 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
36F742D81B3A7016003D799C /* Build configuration list for PBXNativeTarget "GradientCircularProgress" */ = {
isa = XCConfigurationList;
buildConfigurations = (
36F742D41B3A7016003D799C /* Debug */,
36F742D51B3A7016003D799C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 36CC1C741B37083E009DE1F8 /* Project object */;
}
================================================
FILE: GCProgressSample/GCProgressSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:GCProgressSample.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: GCProgressSample/GCProgressSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: GCProgressSample/GCProgressSample.xcodeproj/xcshareddata/xcschemes/GradientCircularProgress.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1100"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "36F742BA1B3A7016003D799C"
BuildableName = "GradientCircularProgress.framework"
BlueprintName = "GradientCircularProgress"
ReferencedContainer = "container:GCProgressSample.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "36F742BA1B3A7016003D799C"
BuildableName = "GradientCircularProgress.framework"
BlueprintName = "GradientCircularProgress"
ReferencedContainer = "container:GCProgressSample.xcodeproj">
</BuildableReference>
</MacroExpansion>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "36F742BA1B3A7016003D799C"
BuildableName = "GradientCircularProgress.framework"
BlueprintName = "GradientCircularProgress"
ReferencedContainer = "container:GCProgressSample.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: GCProgressSample/GCProgressSampleTests/GCProgressSampleTests.swift
================================================
//
// GCProgressSampleTests.swift
// GCProgressSampleTests
//
// Created by keygx on 2015/06/21.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
import XCTest
class GCProgressSampleTests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
XCTAssert(true, "Pass")
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure() {
// Put the code you want to measure the time of here.
}
}
}
================================================
FILE: GCProgressSample/GCProgressSampleTests/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
================================================
FILE: GCProgressSample/GradientCircularProgress/GradientCircularProgress.h
================================================
//
// GradientCircularProgress.h
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for GradientCircularProgress.
FOUNDATION_EXPORT double GradientCircularProgressVersionNumber;
//! Project version string for GradientCircularProgress.
FOUNDATION_EXPORT const unsigned char GradientCircularProgressVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <GradientCircularProgress/PublicHeader.h>
================================================
FILE: GCProgressSample/GradientCircularProgress/GradientCircularProgress.swift
================================================
//
// GradientCircularProgress.swift
// GradientCircularProgress
//
// Created by keygx on 2015/07/29.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public class GradientCircularProgress {
private var baseWindow: UIWindow?
private var progressViewController: ProgressViewController?
private var progressView: ProgressView?
private var property: Property?
public var isAvailable: Bool = false
public init() {}
}
// MARK: Common
extension GradientCircularProgress {
public func updateMessage(message: String) {
if !isAvailable {
return
}
// Use addSubView
if let v = progressView {
v.updateMessage(message)
}
// Use UIWindow
if let vc = progressViewController {
vc.updateMessage(message: message)
}
}
public func updateRatio(_ ratio: CGFloat) {
if !isAvailable {
return
}
// Use addSubView
if let v = progressView {
v.ratio = ratio
}
// Use UIWindow
if let vc = progressViewController {
vc.ratio = ratio
}
}
}
// MARK: Use UIWindow
extension GradientCircularProgress {
public func showAtRatio(display: Bool = true, style: StyleProperty = Style()) {
if isAvailable {
return
}
isAvailable = true
property = Property(style: style)
getProgressAtRatio(display: display, style: style)
}
private func getProgressAtRatio(display: Bool, style: StyleProperty) {
baseWindow = WindowBuilder.build()
progressViewController = ProgressViewController()
guard let win = baseWindow, let vc = progressViewController else {
return
}
win.rootViewController = vc
win.backgroundColor = UIColor.clear
vc.arc(display: display, style: style, baseWindow: baseWindow)
}
public func show(style: StyleProperty = Style()) {
if isAvailable {
return
}
isAvailable = true
property = Property(style: style)
getProgress(message: nil, style: style)
}
public func show(message: String, style: StyleProperty = Style()) {
if isAvailable {
return
}
isAvailable = true
property = Property(style: style)
getProgress(message: message, style: style)
}
private func getProgress(message: String?, style: StyleProperty) {
baseWindow = WindowBuilder.build()
progressViewController = ProgressViewController()
guard let win = baseWindow, let vc = progressViewController else {
return
}
win.rootViewController = vc
win.backgroundColor = UIColor.clear
vc.circle(message: message, style: style, baseWindow: baseWindow)
}
public func dismiss() {
if !isAvailable {
return
}
guard let prop = property else {
return
}
if let vc = progressViewController {
vc.dismiss(prop.dismissTimeInterval!)
}
cleanup(prop.dismissTimeInterval!, completionHandler: nil)
}
public func dismiss(_ completionHandler: @escaping () -> Void) -> () {
if !isAvailable {
return
}
guard let prop = property else {
return
}
if let vc = progressViewController {
vc.dismiss(prop.dismissTimeInterval!)
}
cleanup(prop.dismissTimeInterval!) {
completionHandler()
}
}
private func cleanup(_ t: Double, completionHandler: (() -> Void)?) {
let delay = t * Double(NSEC_PER_SEC)
let time = DispatchTime.now() + Double(Int64(delay)) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: time) { [weak self] in
guard let win = self?.baseWindow else {
return
}
UIView.animate(
withDuration: 0.3,
animations: {
win.alpha = 0
},
completion: { finished in
self?.progressViewController = nil
win.isHidden = true
win.rootViewController = nil
self?.baseWindow = nil
self?.property = nil
self?.isAvailable = false
guard let completionHandler = completionHandler else {
return
}
completionHandler()
}
)
}
}
}
// MARK: Use addSubView
extension GradientCircularProgress {
public func showAtRatio(frame: CGRect, display: Bool = true, style: StyleProperty = Style()) -> UIView? {
if isAvailable {
return nil
}
isAvailable = true
property = Property(style: style)
progressView = ProgressView(frame: frame)
guard let v = progressView else {
return nil
}
v.arc(display, style: style)
return v
}
public func show(frame: CGRect, style: StyleProperty = Style()) -> UIView? {
if isAvailable {
return nil
}
isAvailable = true
property = Property(style: style)
return getProgress(frame: frame, message: nil, style: style)
}
public func show(frame: CGRect, message: String, style: StyleProperty = Style()) -> UIView? {
if isAvailable {
return nil
}
isAvailable = true
property = Property(style: style)
return getProgress(frame: frame, message: message, style: style)
}
private func getProgress(frame: CGRect, message: String?, style: StyleProperty) -> UIView? {
progressView = ProgressView(frame: frame)
guard let v = progressView else {
return nil
}
v.circle(message, style: style)
return v
}
public func dismiss(progress view: UIView) {
if !isAvailable {
return
}
guard let prop = property else {
return
}
cleanup(prop.dismissTimeInterval!, view: view, completionHandler: nil)
}
public func dismiss(progress view: UIView, completionHandler: @escaping () -> Void) -> () {
if !isAvailable {
return
}
guard let prop = property else {
return
}
cleanup(prop.dismissTimeInterval!, view: view) {
completionHandler()
}
}
private func cleanup(_ t: Double, view: UIView, completionHandler: (() -> Void)?) {
let delay = t * Double(NSEC_PER_SEC)
let time = DispatchTime.now() + Double(Int64(delay)) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: time) {
UIView.animate(
withDuration: 0.3,
animations: {
view.alpha = 0
},
completion: { [weak self] finished in
view.removeFromSuperview()
self?.property = nil
self?.isAvailable = false
guard let completionHandler = completionHandler else {
return
}
completionHandler()
}
)
}
}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
================================================
FILE: GCProgressSample/GradientCircularProgress/Progress/Core/CircularProgressView.swift
================================================
//
// CircularProgressView.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class CircularProgressView: UIView {
var prop: Property?
var messageLabel = UILabel()
var centerPoint: CGPoint?
var message: String? {
willSet {
messageLabel.frame = frame
messageLabel.text = newValue
guard let message = messageLabel.text else {
return
}
// Attribute
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineHeightMultiple = 1.2
paragraphStyle.alignment = NSTextAlignment.center
let attr = [NSAttributedString.Key.paragraphStyle: paragraphStyle]
let attributedString = NSMutableAttributedString(string: message, attributes: attr)
messageLabel.attributedText = attributedString
messageLabel.sizeToFit()
if centerPoint == nil {
centerPoint = center
}
if let center = centerPoint {
messageLabel.center = center
}
}
}
var gradientLayer = CALayer()
private struct Animation {
var rotationZ: CABasicAnimation {
let animation: CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.duration = 0.8
animation.repeatCount = HUGE
animation.fromValue = NSNumber(value: 0.0)
animation.toValue = NSNumber(value: 2 * Float.pi)
return animation
}
init() {}
func start(_ layer: CALayer) {
layer.add(rotationZ, forKey: "rotate")
}
func stop(_ layer: CALayer) {
layer.removeAllAnimations()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.clear
layer.masksToBounds = true
NotificationCenter.default.addObserver(self,
selector: #selector(viewDidEnterBackground(_:)),
name: UIApplication.didEnterBackgroundNotification,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(viewWillEnterForeground(_:)),
name: UIApplication.willEnterForegroundNotification,
object: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
NotificationCenter.default.removeObserver(self)
}
override func didMoveToWindow() {
super.didMoveToWindow()
if window != nil {
Animation().start(gradientLayer)
} else {
Animation().stop(gradientLayer)
}
}
@objc private func viewDidEnterBackground(_ notification: Notification?) {
Animation().stop(gradientLayer)
}
@objc private func viewWillEnterForeground(_ notification: Notification?) {
Animation().start(gradientLayer)
}
internal func initialize(frame: CGRect) {
guard let prop = prop else {
return
}
let rect: CGRect = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
// Base Circular
if let baseLineWidth = prop.baseLineWidth, let baseArcColor = prop.baseArcColor {
let circular: ArcView = ArcView(frame: rect, lineWidth: baseLineWidth)
circular.color = baseArcColor
circular.prop = prop
addSubview(circular)
}
// Gradient Circular
if ColorUtil.toRGBA(color: prop.startArcColor).a < 1.0 || ColorUtil.toRGBA(color: prop.endArcColor).a < 1.0 {
// Clear Color
let gradient: UIView = GradientArcWithClearColorView().draw(rect: rect, prop: prop)
addSubview(gradient)
gradientLayer = gradient.layer
Animation().start(gradientLayer)
} else {
// Opaque Color
let gradient: GradientArcView = GradientArcView(frame: rect)
gradient.prop = prop
addSubview(gradient)
gradientLayer = gradient.layer
Animation().start(gradientLayer)
}
}
internal func showMessage(_ message: String) {
guard let prop = prop else {
return
}
// Message
messageLabel.font = prop.messageLabelFont
messageLabel.textAlignment = NSTextAlignment.center
messageLabel.textColor = prop.messageLabelFontColor
messageLabel.numberOfLines = 0
addSubview(messageLabel)
self.message = message
}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Progress/Core/ProgressAtRatioView.swift
================================================
//
// ProgressAtRatioView.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class ProgressAtRatioView: UIView {
internal var arcView: ArcView?
internal var prop: Property?
internal var ratioLabel: UILabel = UILabel()
internal var ratio: CGFloat = 0.0 {
didSet {
ratioLabel.text = String(format:"%.0f", ratio * 100) + "%"
}
}
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.clear
layer.masksToBounds = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
internal func initialize(frame: CGRect) {
guard let prop = prop else {
return
}
let rect: CGRect = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
// Base Circular
if let baseLineWidth = prop.baseLineWidth, let baseArcColor = prop.baseArcColor {
let circular: ArcView = ArcView(frame: rect, lineWidth: baseLineWidth)
circular.prop = prop
circular.ratio = 1.0
circular.color = baseArcColor
circular.lineWidth = baseLineWidth
addSubview(circular)
}
// Gradient Circular
if ColorUtil.toRGBA(color: prop.startArcColor).a < 1.0 || ColorUtil.toRGBA(color: prop.endArcColor).a < 1.0 {
// Clear Color
let gradient: UIView = GradientArcWithClearColorView().draw(rect: rect, prop: prop)
addSubview(gradient)
masking(rect: rect, prop: prop, gradient: gradient)
} else {
// Opaque Color
let gradient: GradientArcView = GradientArcView(frame: rect)
gradient.prop = prop
addSubview(gradient)
masking(rect: rect, prop: prop, gradient: gradient)
}
}
private func masking(rect: CGRect, prop: Property, gradient: UIView) {
// Mask
arcView = ArcView(frame: rect, lineWidth: prop.arcLineWidth)
guard let mask = arcView else {
return
}
mask.prop = prop
gradient.layer.mask = mask.layer
}
override func draw(_ rect: CGRect) {
guard let mask = arcView else {
return
}
if ratio > 1.0 {
mask.ratio = 1.0
} else {
mask.ratio = ratio
}
mask.setNeedsDisplay()
}
func showRatio() {
guard let prop = prop else {
return
}
// Progress Ratio
ratioLabel.text = " "
ratioLabel.font = prop.ratioLabelFont
ratioLabel.textAlignment = NSTextAlignment.right
ratioLabel.textColor = prop.ratioLabelFontColor
ratioLabel.sizeToFit()
ratioLabel.center = center
addSubview(ratioLabel)
}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Progress/Elements/ArcView.swift
================================================
//
// Arc.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class ArcView: UIView {
var prop: Property?
var ratio: CGFloat = 1.0
var color: UIColor = UIColor.black
var lineWidth: CGFloat = 0.0
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
init(frame: CGRect, lineWidth: CGFloat) {
super.init(frame: frame)
backgroundColor = UIColor.clear
layer.masksToBounds = true
self.lineWidth = lineWidth
}
override func draw(_ rect: CGRect) {
drawArc(rect: rect)
}
private func drawArc(rect: CGRect) {
guard let prop = prop else {
return
}
let circularRect: CGRect = prop.progressRect
let arcPoint: CGPoint = CGPoint(x: rect.width/2, y: rect.height/2)
let arcRadius: CGFloat = circularRect.width/2 + prop.arcLineWidth/2
let arcStartAngle: CGFloat = -CGFloat.pi/2
let arcEndAngle: CGFloat = ratio * 2.0 * CGFloat.pi - CGFloat.pi/2
let arc: UIBezierPath = UIBezierPath(arcCenter: arcPoint,
radius: arcRadius,
startAngle: arcStartAngle,
endAngle: arcEndAngle,
clockwise: true)
color.setStroke()
arc.lineWidth = lineWidth
arc.lineCapStyle = prop.arcLineCapStyle
arc.stroke()
}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Progress/Elements/Background.swift
================================================
//
// Background.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
struct Background {
internal func blurEffectView(fromBlurStyle style: BackgroundStyles, frame: CGRect) -> UIVisualEffectView? {
var blurView: UIVisualEffectView?
// return (blurEffectStyle: UIBlurEffectStyle?, isUserInteraction: Bool)
let backgroundStyle = getStyle(style)
if let blur = backgroundStyle.blurEffectStyle {
// UIBlurEffectStyle (.extraLight, .light, .dark)
let effect = UIBlurEffect(style: blur)
blurView = UIVisualEffectView(effect: effect)
} else {
if !backgroundStyle.isUserInteraction {
// .transparent
blurView = UIVisualEffectView(effect: nil)
}
}
blurView?.frame = frame
return blurView
}
private func getStyle(_ style: BackgroundStyles) -> (blurEffectStyle: UIBlurEffect.Style?, isUserInteraction: Bool) {
switch style {
case .extraLight:
return (.extraLight, false)
case .light:
return (.light, false)
case .dark:
return (.dark, false)
case .transparent:
return (nil, false)
default:
// .none
return (nil, true)
}
}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Progress/Elements/GradientArcView.swift
================================================
//
// GradientArcView.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class GradientArcView: UIView {
internal var prop: Property?
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.clear
layer.masksToBounds = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func getGradientPointColor(ratio: CGFloat, startColor: UIColor, endColor: UIColor) -> UIColor {
let sColor = ColorUtil.toRGBA(color: startColor)
let eColor = ColorUtil.toRGBA(color: endColor)
let r = (eColor.r - sColor.r) * ratio + sColor.r
let g = (eColor.g - sColor.g) * ratio + sColor.g
let b = (eColor.b - sColor.b) * ratio + sColor.b
let a = (eColor.a - sColor.a) * ratio + sColor.a
return UIColor(red: r, green: g, blue: b, alpha: a)
}
override func draw(_ rect: CGRect) {
guard let prop = prop else {
return
}
let circularRect: CGRect = prop.progressRect
var currentAngle: CGFloat = 0.0
for i in stride(from:CGFloat(0.0), through: CGFloat(1.0), by: CGFloat(0.005)) {
let arcPoint: CGPoint = CGPoint(x: rect.width/2, y: rect.height/2)
let arcRadius: CGFloat = circularRect.width/2 + prop.arcLineWidth/2
let arcStartAngle: CGFloat = -CGFloat.pi/2
let arcEndAngle: CGFloat = i * 2.0 * CGFloat.pi - CGFloat.pi/2
if currentAngle == 0.0 {
currentAngle = arcStartAngle
} else {
currentAngle = arcEndAngle - 0.05
}
let arc: UIBezierPath = UIBezierPath(arcCenter: arcPoint,
radius: arcRadius,
startAngle: currentAngle,
endAngle: arcEndAngle,
clockwise: true)
let strokeColor: UIColor = getGradientPointColor(ratio: i, startColor: prop.startArcColor, endColor: prop.endArcColor)
strokeColor.setStroke()
arc.lineWidth = prop.arcLineWidth
arc.lineCapStyle = prop.arcLineCapStyle
arc.stroke()
}
}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Progress/Elements/GradientArcWithClearColorView.swift
================================================
//
// GradientArcWithClearColorView.swift
// GradientCircularProgress
//
// Created by keygx on 2015/11/20.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class GradientArcWithClearColorView: UIView {
internal func draw(rect: CGRect, prop: Property) -> UIImageView {
// Gradient Clear Circular
/* Prop */
var startArcColorProp = prop
var endArcColorProp = prop
var startGradientMaskProp = prop
var endGradientMaskProp = prop
var solidMaskProp = prop
// StartArc
startArcColorProp.endArcColor = ColorUtil.toNotOpacityColor(color: startArcColorProp.startArcColor)
// EndArc
endArcColorProp.startArcColor = ColorUtil.toNotOpacityColor(color: endArcColorProp.endArcColor)
// StartGradientMask
startGradientMaskProp.startArcColor = UIColor.black
startGradientMaskProp.endArcColor = UIColor.white
startGradientMaskProp.progressSize += 10.0
startGradientMaskProp.arcLineWidth += 20.0
// EndGradientMask
endGradientMaskProp.startArcColor = UIColor.white
endGradientMaskProp.endArcColor = UIColor.black
endGradientMaskProp.progressSize += 10.0
endGradientMaskProp.arcLineWidth += 20.0
// SolidMask
solidMaskProp.startArcColor = UIColor.black
solidMaskProp.endArcColor = UIColor.black
/* Mask Image */
// StartArcColorImage
let startArcColorView = ArcView(frame: rect, lineWidth: startArcColorProp.arcLineWidth)
startArcColorView.color = startArcColorProp.startArcColor
startArcColorView.prop = startArcColorProp
let startArcColorImage = viewToUIImage(view: startArcColorView)!
// StartGradientMaskImage
let startGradientMaskView = GradientArcView(frame: rect)
startGradientMaskView.prop = startGradientMaskProp
let startGradientMaskImage = viewToUIImage(view: startGradientMaskView)!
// EndArcColorImage
let endArcColorView = ArcView(frame: rect, lineWidth: endArcColorProp.arcLineWidth)
endArcColorView.color = endArcColorProp.startArcColor
endArcColorView.prop = endArcColorProp
let endArcColorImage = viewToUIImage(view: endArcColorView)!
// EndGradientMaskImage
let endGradientMaskView = GradientArcView(frame: rect)
endGradientMaskView.prop = endGradientMaskProp
let endGradientMaskImage = viewToUIImage(view: endGradientMaskView)!
// SolidMaskImage
let solidMaskView = ArcView(frame: rect, lineWidth: solidMaskProp.arcLineWidth)
solidMaskView.prop = solidMaskProp
let solidMaskImage = viewToUIImage(view: solidMaskView)!
/* Masking */
var startArcImage = mask(image: startGradientMaskImage, maskImage: solidMaskImage)
startArcImage = mask(image: startArcColorImage, maskImage: startArcImage)
var endArcImage = mask(image: endGradientMaskImage, maskImage: solidMaskImage)
endArcImage = mask(image: endArcColorImage, maskImage: endArcImage)
/* Composite */
let image: UIImage = composite(image1: startArcImage, image2: endArcImage, prop: prop)
/* UIImageView */
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
return imageView
}
internal func mask(image: UIImage, maskImage: UIImage) -> UIImage {
let maskRef: CGImage = maskImage.cgImage!
let mask: CGImage = CGImage(
maskWidth: maskRef.width,
height: maskRef.height,
bitsPerComponent: maskRef.bitsPerComponent,
bitsPerPixel: maskRef.bitsPerPixel,
bytesPerRow: maskRef.bytesPerRow,
provider: maskRef.dataProvider!,
decode: nil,
shouldInterpolate: false)!
let maskedImageRef: CGImage = image.cgImage!.masking(mask)!
let scale = UIScreen.main.scale
let maskedImage: UIImage = UIImage(cgImage: maskedImageRef, scale: scale, orientation: .up)
return maskedImage
}
internal func viewToUIImage(view: UIView) -> UIImage? {
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(view.frame.size, false, scale)
view.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
internal func composite(image1: UIImage, image2: UIImage, prop: Property) -> UIImage {
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(image1.size, false, scale)
image1.draw(
in: CGRect(x: 0, y: 0, width: image1.size.width, height: image1.size.height),
blendMode: .overlay,
alpha: ColorUtil.toRGBA(color: prop.startArcColor).a)
image2.draw(
in: CGRect(x: 0, y: 0, width: image2.size.width, height: image2.size.height),
blendMode: .overlay,
alpha: ColorUtil.toRGBA(color: prop.endArcColor).a)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Progress/Elements/WindowBuilder.swift
================================================
//
// WindowBuilder.swift
// GradientCircularProgress
//
// Created by keygx on 2019/09/24.
// Copyright © 2019 keygx. All rights reserved.
//
import UIKit
class WindowBuilder {
static func build() -> UIWindow? {
var baseWindow: UIWindow?
if #available(iOS 13.0, *) {
let windowScene = UIApplication.shared.connectedScenes
.filter { $0.activationState == .foregroundActive }.first
if let windowScene = windowScene as? UIWindowScene {
baseWindow = UIWindow(windowScene: windowScene)
} else {
baseWindow = UIWindow()
}
} else {
baseWindow = UIWindow()
}
baseWindow?.bounds = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
baseWindow?.backgroundColor = UIColor.clear
baseWindow?.windowLevel = UIWindow.Level.alert + 1
baseWindow?.makeKeyAndVisible()
return baseWindow
}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Progress/ProgressView.swift
================================================
//
// ProgressView.swift
// GradientCircularProgress
//
// Created by keygx on 2016/03/07.
// Copyright (c) 2016年 keygx. All rights reserved.
//
import UIKit
class ProgressView: UIView {
private var viewRect: CGRect?
private var blurView: UIVisualEffectView?
private var progressAtRatioView: ProgressAtRatioView?
private var circularProgressView: CircularProgressView?
internal var prop: Property?
internal var ratio: CGFloat = 0.0 {
didSet {
progressAtRatioView?.ratio = ratio
progressAtRatioView?.setNeedsDisplay()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
initialize(frame: frame)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
private func initialize(frame: CGRect) {
viewRect = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
clipsToBounds = true
}
internal func arc(_ display: Bool, style: StyleProperty) {
prop = Property(style: style)
guard let prop = prop else {
return
}
isUserInteractionEnabled = !(prop.backgroundStyle.rawValue == 0) ? true : false
getBlurView()
progressAtRatioView = ProgressAtRatioView(frame: CGRect(x: 0, y: 0, width: prop.progressSize, height: prop.progressSize))
guard let progressAtRatioView = progressAtRatioView else {
return
}
progressAtRatioView.prop = prop
progressAtRatioView.initialize(frame: progressAtRatioView.frame)
if display {
progressAtRatioView.showRatio()
}
progressAtRatioView.frame = CGRect(
x: (frame.size.width - progressAtRatioView.frame.size.width) / 2,
y: (frame.size.height - progressAtRatioView.frame.size.height) / 2,
width: progressAtRatioView.frame.size.width,
height: progressAtRatioView.frame.size.height)
addSubview(progressAtRatioView)
}
internal func circle(_ message: String?, style: StyleProperty) {
prop = Property(style: style)
guard let prop = prop else {
return
}
isUserInteractionEnabled = !(prop.backgroundStyle.rawValue == 0) ? true : false
getBlurView()
circularProgressView = CircularProgressView(frame: CGRect(x: 0, y: 0, width: prop.progressSize, height: prop.progressSize))
guard let circularProgressView = circularProgressView else {
return
}
circularProgressView.prop = prop
circularProgressView.initialize(frame: circularProgressView.frame)
if let message = message {
circularProgressView.showMessage(message)
}
circularProgressView.frame = CGRect(
x: (frame.size.width - circularProgressView.frame.size.width) / 2,
y: (frame.size.height - circularProgressView.frame.size.height) / 2,
width: circularProgressView.frame.size.width,
height: circularProgressView.frame.size.height)
addSubview(circularProgressView)
}
internal func updateMessage(_ message: String) {
guard let circularProgressView = circularProgressView else {
return
}
circularProgressView.message = message
}
private func getBlurView() {
guard let rect = viewRect, let prop = prop else {
return
}
blurView = Background().blurEffectView(fromBlurStyle: prop.backgroundStyle, frame: rect)
guard let blurView = blurView else {
return
}
backgroundColor = UIColor.clear
addSubview(blurView)
}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Progress/ProgressViewController.swift
================================================
//
// ProgressViewController.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class ProgressViewController: UIViewController {
private var viewRect: CGRect?
private var blurView: UIVisualEffectView?
private var progressAtRatioView: ProgressAtRatioView?
private var circularProgressView: CircularProgressView?
internal var prop: Property?
internal var ratio: CGFloat = 0.0 {
didSet {
progressAtRatioView?.ratio = ratio
progressAtRatioView?.setNeedsDisplay()
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.clear
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override var shouldAutorotate: Bool {
return false
}
override var prefersStatusBarHidden: Bool {
let orientation: UIInterfaceOrientation
if #available(iOS 13.0, *) {
orientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation ?? .portrait
} else {
orientation = UIApplication.shared.statusBarOrientation
}
switch orientation {
case .landscapeLeft, .landscapeRight:
// LandscapeLeft | LandscapeRight
return true
default:
// Unknown | Portrait | PortraitUpsideDown
return false
}
}
private func getViewRect() {
let window = UIWindow(frame: UIScreen.main.bounds)
viewRect = window.frame
}
private func getBlurView() {
guard let rect = viewRect, let prop = prop else {
return
}
blurView = Background().blurEffectView(fromBlurStyle: prop.backgroundStyle, frame: rect)
guard let blurView = blurView else {
return
}
view.backgroundColor = UIColor.clear
view.addSubview(blurView)
}
internal func arc(display: Bool, style: StyleProperty, baseWindow: UIWindow?) {
prop = Property(style: style)
guard let win = baseWindow, let prop = prop else {
return
}
win.isUserInteractionEnabled = !(prop.backgroundStyle.rawValue == 0) ? true : false // 0 == .None
getViewRect()
getBlurView()
progressAtRatioView = ProgressAtRatioView(frame: CGRect(x: 0, y: 0, width: prop.progressSize, height: prop.progressSize))
guard let progressAtRatioView = progressAtRatioView else {
return
}
progressAtRatioView.prop = prop
progressAtRatioView.initialize(frame: progressAtRatioView.frame)
if display {
progressAtRatioView.showRatio()
}
progressAtRatioView.center = view.center
view.addSubview(progressAtRatioView)
}
internal func circle(message: String?, style: StyleProperty, baseWindow: UIWindow?) {
prop = Property(style: style)
guard let win = baseWindow, let prop = prop else {
return
}
win.isUserInteractionEnabled = !(prop.backgroundStyle.rawValue == 0) ? true : false // 0 == .None
getViewRect()
getBlurView()
circularProgressView = CircularProgressView(frame: CGRect(x: 0, y: 0, width: prop.progressSize, height: prop.progressSize))
guard let circularProgressView = circularProgressView else {
return
}
circularProgressView.prop = prop
circularProgressView.initialize(frame: circularProgressView.frame)
if message != nil {
circularProgressView.showMessage(message!)
}
circularProgressView.center = view.center
view.addSubview(circularProgressView)
}
internal func updateMessage(message: String) {
guard let circularProgressView = circularProgressView else {
return
}
circularProgressView.message = message
}
internal func dismiss(_ t: Double) {
let delay = t * Double(NSEC_PER_SEC)
let time = DispatchTime.now() + Double(Int64(delay)) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: time) {
guard let blurView = self.blurView, let progressAtRatioView = self.progressAtRatioView, let circularProgressView = self.circularProgressView else {
return
}
UIView.animate(
withDuration: 0.3,
animations: {
progressAtRatioView.alpha = 0.0
circularProgressView.alpha = 0.0
},
completion: { finished in
progressAtRatioView.removeFromSuperview()
circularProgressView.removeFromSuperview()
blurView.removeFromSuperview()
}
)
}
}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Progress/Property.swift
================================================
//
// Property.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
public protocol StyleProperty {
// Progress Size
var progressSize: CGFloat { get set }
// Gradient Circular
var arcLineWidth: CGFloat { get set }
var startArcColor: UIColor { get set }
var endArcColor: UIColor { get set }
// Base Circular
var baseLineWidth: CGFloat? { get set }
var baseArcColor: UIColor? { get set }
// Ratio
var ratioLabelFont: UIFont? { get set }
var ratioLabelFontColor: UIColor? { get set }
// Message
var messageLabelFont: UIFont? { get set }
var messageLabelFontColor: UIColor? { get set }
// Background
var backgroundStyle: BackgroundStyles { get set }
// Dismiss
var dismissTimeInterval: Double? { get set }
// Initialize
init()
}
public enum BackgroundStyles: Int {
case none = 0
case extraLight
case light
case dark
case transparent
}
internal struct Property {
let margin: CGFloat = 5.0
let arcLineCapStyle: CGLineCap = CGLineCap.butt
// Progress Size
var progressSize: CGFloat
// Gradient Circular
var arcLineWidth: CGFloat
var startArcColor: UIColor
var endArcColor: UIColor
// Base Circular
var baseLineWidth: CGFloat?
var baseArcColor: UIColor?
// Ratio
let ratioLabelFont: UIFont?
let ratioLabelFontColor: UIColor?
// Message
let messageLabelFont: UIFont?
let messageLabelFontColor: UIColor?
// Background
let backgroundStyle: BackgroundStyles
// Dismiss
let dismissTimeInterval: Double?
// Progress Rect
var progressRect: CGRect {
let lineWidth: CGFloat = (arcLineWidth > baseLineWidth!) ? arcLineWidth : baseLineWidth!
return CGRect(x: 0, y: 0, width: progressSize - lineWidth * 2, height: progressSize - lineWidth * 2)
}
init(style: StyleProperty) {
let styles: StyleProperty = style
progressSize = styles.progressSize
arcLineWidth = styles.arcLineWidth
startArcColor = styles.startArcColor
endArcColor = styles.endArcColor
baseLineWidth = styles.baseLineWidth ?? 0.0
baseArcColor = styles.baseArcColor ?? UIColor.clear
ratioLabelFont = styles.ratioLabelFont ?? UIFont.systemFont(ofSize: 16.0)
ratioLabelFontColor = styles.ratioLabelFontColor ?? UIColor.clear
messageLabelFont = styles.messageLabelFont ?? UIFont.systemFont(ofSize: 16.0)
messageLabelFontColor = styles.messageLabelFontColor ?? UIColor.clear
backgroundStyle = styles.backgroundStyle
dismissTimeInterval = styles.dismissTimeInterval ?? 0.8
}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Styles/BlueDarkStyle.swift
================================================
//
// BlueDarkStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/08/31.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public struct BlueDarkStyle: StyleProperty {
// Progress Size
public var progressSize: CGFloat = 260
// Gradient Circular
public var arcLineWidth: CGFloat = 4.0
public var startArcColor: UIColor = ColorUtil.toUIColor(r: 0.0, g: 122.0, b: 255.0, a: 1.0)
public var endArcColor: UIColor = UIColor.cyan
// Base Circular
public var baseLineWidth: CGFloat? = 5.0
public var baseArcColor: UIColor? = UIColor(red:0.0, green: 0.0, blue: 0.0, alpha: 0.2)
// Ratio
public var ratioLabelFont: UIFont? = UIFont(name: "Verdana-Bold", size: 16.0)
public var ratioLabelFontColor: UIColor? = UIColor.white
// Message
public var messageLabelFont: UIFont? = UIFont.systemFont(ofSize: 16.0)
public var messageLabelFontColor: UIColor? = UIColor.white
// Background
public var backgroundStyle: BackgroundStyles = .dark
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
public init() {}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Styles/BlueIndicatorStyle.swift
================================================
//
// BlueIndicatorStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/08/31.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public struct BlueIndicatorStyle: StyleProperty {
// Progress Size
public var progressSize: CGFloat = 44
// Gradient Circular
public var arcLineWidth: CGFloat = 4.0
public var startArcColor: UIColor = ColorUtil.toUIColor(r: 235.0, g: 245.0, b: 255.0, a: 1.0)
public var endArcColor: UIColor = ColorUtil.toUIColor(r: 0.0, g: 122.0, b: 255.0, a: 1.0)
// Base Circular
public var baseLineWidth: CGFloat? = 4.0
public var baseArcColor: UIColor? = ColorUtil.toUIColor(r: 215.0, g: 215.0, b: 215.0, a: 0.4)
// Ratio
public var ratioLabelFont: UIFont? = nil
public var ratioLabelFontColor: UIColor? = nil
// Message
public var messageLabelFont: UIFont? = nil
public var messageLabelFontColor: UIColor? = nil
// Background
public var backgroundStyle: BackgroundStyles = .none
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
public init() {}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Styles/GreenLightStyle.swift
================================================
//
// GreenLightStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/11/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public struct GreenLightStyle: StyleProperty {
// Progress Size
public var progressSize: CGFloat = 200
// Gradient Circular
public var arcLineWidth: CGFloat = 32.0
public var startArcColor: UIColor = ColorUtil.toUIColor(r: 40.0, g: 110.0, b: 60.0, a: 1.0)
public var endArcColor: UIColor = UIColor.green
// Base Circular
public var baseLineWidth: CGFloat? = 1.0
public var baseArcColor: UIColor? = UIColor(red:0.0, green: 0.0, blue: 0.0, alpha: 0.1)
// Ratio
public var ratioLabelFont: UIFont? = UIFont(name: "Verdana-Bold", size: 18.0)
public var ratioLabelFontColor: UIColor? = UIColor.darkGray
// Message
public var messageLabelFont: UIFont? = UIFont(name: "Verdana", size: 18.0)
public var messageLabelFontColor: UIColor? = UIColor.darkGray
// Background
public var backgroundStyle: BackgroundStyles = .light
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
public init() {}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Styles/OrangeClearStyle.swift
================================================
//
// OrangeClearStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/11/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public struct OrangeClearStyle: StyleProperty {
// Progress Size
public var progressSize: CGFloat = 80
// Gradient Circular
public var arcLineWidth: CGFloat = 6.0
public var startArcColor: UIColor = UIColor.clear
public var endArcColor: UIColor = UIColor.orange
// Base Circular
public var baseLineWidth: CGFloat? = nil
public var baseArcColor: UIColor? = nil
// Ratio
public var ratioLabelFont: UIFont? = UIFont.systemFont(ofSize: 13.0)
public var ratioLabelFontColor: UIColor? = UIColor.black
// Message
public var messageLabelFont: UIFont? = nil
public var messageLabelFontColor: UIColor? = nil
// Background
public var backgroundStyle: BackgroundStyles = .none
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
public init() {}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Styles/Style.swift
================================================
//
// DefaultStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/08/31.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public struct Style: StyleProperty {
// Progress Size
public var progressSize: CGFloat = 220
// Gradient Circular
public var arcLineWidth: CGFloat = 16.0
public var startArcColor: UIColor = ColorUtil.toUIColor(r: 230.0, g: 230.0, b: 230.0, a: 0.6)
public var endArcColor: UIColor = ColorUtil.toUIColor(r: 90.0, g: 90.0, b: 90.0, a: 1.0)
// Base Circular
public var baseLineWidth: CGFloat? = 16.0
public var baseArcColor: UIColor? = UIColor(red:1.0, green: 1.0, blue: 1.0, alpha: 0.8)
// Ratio
public var ratioLabelFont: UIFont? = UIFont.systemFont(ofSize: 18.0)
public var ratioLabelFontColor: UIColor? = UIColor.black
// Message
public var messageLabelFont: UIFont? = UIFont.systemFont(ofSize: 18.0)
public var messageLabelFontColor: UIColor? = UIColor.black
// Background
public var backgroundStyle: BackgroundStyles = .extraLight
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
public init() {}
}
================================================
FILE: GCProgressSample/GradientCircularProgress/Utils/ColorUtil.swift
================================================
//
// ColorUtil.swift
// GradientCircularProgress
//
// Created by keygx on 2015/11/23.
// Copyright © 2015年 keygx. All rights reserved.
//
import UIKit
public class ColorUtil {
public class func toUIColor(r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) -> UIColor {
return UIColor(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: a)
}
internal class func toRGBA(color: UIColor) -> (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) {
var r: CGFloat = 0.0
var g: CGFloat = 0.0
var b: CGFloat = 0.0
var a: CGFloat = 0.0
color.getRed(&r, green: &g, blue: &b, alpha: &a)
return (r, g, b, a)
}
internal class func toNotOpacityColor(color: UIColor) -> UIColor {
if color == UIColor.clear {
return UIColor.white
} else {
return UIColor(
red: ColorUtil.toRGBA(color: color).r,
green: ColorUtil.toRGBA(color: color).g,
blue: ColorUtil.toRGBA(color: color).b,
alpha: 1.0)
}
}
}
================================================
FILE: GradientCircularProgress.podspec
================================================
Pod::Spec.new do |s|
s.name = "GradientCircularProgress"
s.version = "3.13.0"
s.summary = "Customizable progress indicator library in Swift"
s.homepage = "https://github.com/keygx/GradientCircularProgress"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "keygx" => "y.kagiyama@gmail.com" }
s.social_media_url = "http://twitter.com/keygx"
s.platform = :ios
s.ios.deployment_target = '8.0'
s.source = { :git => "https://github.com/keygx/GradientCircularProgress.git", :tag => "#{s.version}" }
s.source_files = "source/**/*"
s.requires_arc = true
end
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2015 Yukihiko Kagiyama
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.
================================================
FILE: README.md
================================================
# Gradient Circular Progress
Customizable progress indicator library in Swift
## Requirements
- Swift 5.1
- iOS 8.0 or later
## Screen Shots
- Preset style: [BlueDarkStyle.swift](https://github.com/keygx/GradientCircularProgress/blob/master/Source/BlueDarkStyle.swift)
 
- All preset styles


- Example Use AddSubView
 
## Installation
### Carthage
```Cartfile
github "keygx/GradientCircularProgress"
```
### CocoaPods
```PodFile
pod 'GradientCircularProgress', :git => 'https://github.com/keygx/GradientCircularProgress'
```
### Swift versions support
- Swift 5.1, tag "swift5.1"
- Swift 5, tag "swift5"
- Swift 4.2, tag "swift4.2"
- Swift 4.1, tag "swift4.1"
- Swift 4.0, tag "swift4.0"
## Style Settings
Please make your original styles

- Define custom style structs that implements the StyleProperty Protocol
[MyStyle.swift](https://github.com/keygx/GradientCircularProgress/blob/master/Sample/MyStyle.swift)
```swift
import GradientCircularProgress
public struct MyStyle : StyleProperty {
/*** style properties **********************************************************************************/
// Progress Size
public var progressSize: CGFloat = 200
// Gradient Circular
public var arcLineWidth: CGFloat = 18.0
public var startArcColor: UIColor = UIColor.clear()
public var endArcColor: UIColor = UIColor.orange()
// Base Circular
public var baseLineWidth: CGFloat? = 19.0
public var baseArcColor: UIColor? = UIColor.darkGray()
// Ratio
public var ratioLabelFont: UIFont? = UIFont(name: "Verdana-Bold", size: 16.0)
public var ratioLabelFontColor: UIColor? = UIColor.white()
// Message
public var messageLabelFont: UIFont? = UIFont.systemFont(ofSize: 16.0)
public var messageLabelFontColor: UIColor? = UIColor.white()
// Background
public var backgroundStyle: BackgroundStyles = .dark
// Dismiss
public var dismissTimeInterval: Double? = 0.0 // 'nil' for default setting.
/*** style properties **********************************************************************************/
public init() {}
}
```

## Usage
```swift
import GradientCircularProgress
```
### Basic
#### UIWindow
```swift
let progress = GradientCircularProgress()
progress.show(message: "Loading...", MyStyle())
progress.dismiss()
```
#### addSubView
```swift
let progress = GradientCircularProgress()
let progressView = progress.show(frame: rect, message: "Loading...", style: MyStyle())
view.addSubview(progressView!)
progress.dismiss(progress: progressView!)
```
### at Rtio
#### UIWindow
```swift
let progress = GradientCircularProgress()
let ratio: CGFloat = CGFloat(totalBytesWritten) / CGFloat(totalBytesExpectedToWrite)
progress.showAtRatio(style: MyStyle())
progress.updateRatio(ratio)
progress.dismiss()
```
#### addSubView
```swift
let progress = GradientCircularProgress()
let progressView = progress.showAtRatio(frame: rect, display: true, style: MyStyle())
view.addSubview(progressView!)
progress.updateRatio(ratio)
progress.dismiss(progress: progressView!)
```
### Update Message
#### UIWindow
```swift
let progress = GradientCircularProgress()
progress.show(message: "Download\n0 / 4", MyStyle())
progress.updateMessage(message: "Download\n1 / 4")
progress.updateMessage(message: "Download\n2 / 4")
progress.updateMessage(message: "Download\n3 / 4")
progress.updateMessage(message: "Download\n4 / 4")
progress.updateMessage(message: "Completed!")
progress.dismiss()
```
#### addSubView
```swift
let progress = GradientCircularProgress()
let progressView = progress.show(frame: rect, message: "Download\n0 / 4", style: MyStyle())
view.addSubview(progressView!)
progress.updateMessage(message: "Download\n1 / 4")
progress.updateMessage(message: "Download\n2 / 4")
progress.updateMessage(message: "Download\n3 / 4")
progress.updateMessage(message: "Download\n4 / 4")
progress.updateMessage(message: "Completed!")
progress.dismiss(progress: progressView!)
```
## API
### Use UIWindow
```swift
public func showAtRatio(display: Bool = true, style: StyleProperty = Style())
public func show(style: StyleProperty = Style())
public func show(message: String, style: StyleProperty = Style())
public func dismiss()
public func dismiss(_ completionHandler: () -> Void) -> ()
```
### Use addSubView
```swift
public func showAtRatio(frame: CGRect, display: Bool = true, style: StyleProperty = Style()) -> UIView?
public func show(frame: CGRect, style: StyleProperty = Style()) -> UIView?
public func show(frame: CGRect, message: String, style: StyleProperty = Style()) -> UIView?
public func dismiss(progress view: UIView)
public func dismiss(progress view: UIView, completionHandler: () -> Void) -> ()
```
### Common
```swift
public func updateMessage(message message: String)
public func updateRatio(_ ratio: CGFloat)
```
## License
Gradient Circular Progress is released under the MIT license. See LICENSE for details.
## Author
Yukihiko Kagiyama (keygx) <https://twitter.com/keygx>
================================================
FILE: Sample/BackgroundTransparentStyle.swift
================================================
//
// BackgroundTransparentStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2016/12/03.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
import GradientCircularProgress
public struct BackgroundTransparentStyle: StyleProperty {
/*** style properties **********************************************************************************/
// Progress Size
public var progressSize: CGFloat = 200
// Gradient Circular
public var arcLineWidth: CGFloat = 4.0
public var startArcColor: UIColor = ColorUtil.toUIColor(r: 0.0, g: 122.0, b: 255.0, a: 1.0)
public var endArcColor: UIColor = UIColor.cyan
// Base Circular
public var baseLineWidth: CGFloat? = 6.0
public var baseArcColor: UIColor? = UIColor(red:0.0, green: 0.0, blue: 0.0, alpha: 0.2)
// Ratio
public var ratioLabelFont: UIFont? = UIFont.systemFont(ofSize: 16.0)
public var ratioLabelFontColor: UIColor? = UIColor.black
// Message
public var messageLabelFont: UIFont? = UIFont.systemFont(ofSize: 16.0)
public var messageLabelFontColor: UIColor? = UIColor.black
// Background
public var backgroundStyle: BackgroundStyles = .transparent
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
/*** style properties **********************************************************************************/
public init() {}
}
================================================
FILE: Sample/MyStyle.swift
================================================
//
// MyStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/11/25.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
import GradientCircularProgress
public struct MyStyle: StyleProperty {
/*** style properties **********************************************************************************/
// Progress Size
public var progressSize: CGFloat = 200
// Gradient Circular
public var arcLineWidth: CGFloat = 18.0
public var startArcColor: UIColor = UIColor.clear
public var endArcColor: UIColor = UIColor.orange
// Base Circular
public var baseLineWidth: CGFloat? = 19.0
public var baseArcColor: UIColor? = UIColor.darkGray
// Ratio
public var ratioLabelFont: UIFont? = UIFont(name: "Verdana-Bold", size: 16.0)
public var ratioLabelFontColor: UIColor? = UIColor.white
// Message
public var messageLabelFont: UIFont? = UIFont.systemFont(ofSize: 16.0)
public var messageLabelFontColor: UIColor? = UIColor.white
// Background
public var backgroundStyle: BackgroundStyles = .dark
// Dismiss
public var dismissTimeInterval: Double? = 0.0 // 'nil' for default setting.
/*** style properties **********************************************************************************/
public init() {}
}
================================================
FILE: source/GradientCircularProgress.h
================================================
//
// GradientCircularProgress.h
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for GradientCircularProgress.
FOUNDATION_EXPORT double GradientCircularProgressVersionNumber;
//! Project version string for GradientCircularProgress.
FOUNDATION_EXPORT const unsigned char GradientCircularProgressVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <GradientCircularProgress/PublicHeader.h>
================================================
FILE: source/GradientCircularProgress.swift
================================================
//
// GradientCircularProgress.swift
// GradientCircularProgress
//
// Created by keygx on 2015/07/29.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public class GradientCircularProgress {
private var baseWindow: UIWindow?
private var progressViewController: ProgressViewController?
private var progressView: ProgressView?
private var property: Property?
public var isAvailable: Bool = false
public init() {}
}
// MARK: Common
extension GradientCircularProgress {
public func updateMessage(message: String) {
if !isAvailable {
return
}
// Use addSubView
if let v = progressView {
v.updateMessage(message)
}
// Use UIWindow
if let vc = progressViewController {
vc.updateMessage(message: message)
}
}
public func updateRatio(_ ratio: CGFloat) {
if !isAvailable {
return
}
// Use addSubView
if let v = progressView {
v.ratio = ratio
}
// Use UIWindow
if let vc = progressViewController {
vc.ratio = ratio
}
}
}
// MARK: Use UIWindow
extension GradientCircularProgress {
public func showAtRatio(display: Bool = true, style: StyleProperty = Style()) {
if isAvailable {
return
}
isAvailable = true
property = Property(style: style)
getProgressAtRatio(display: display, style: style)
}
private func getProgressAtRatio(display: Bool, style: StyleProperty) {
baseWindow = WindowBuilder.build()
progressViewController = ProgressViewController()
guard let win = baseWindow, let vc = progressViewController else {
return
}
win.rootViewController = vc
win.backgroundColor = UIColor.clear
vc.arc(display: display, style: style, baseWindow: baseWindow)
}
public func show(style: StyleProperty = Style()) {
if isAvailable {
return
}
isAvailable = true
property = Property(style: style)
getProgress(message: nil, style: style)
}
public func show(message: String, style: StyleProperty = Style()) {
if isAvailable {
return
}
isAvailable = true
property = Property(style: style)
getProgress(message: message, style: style)
}
private func getProgress(message: String?, style: StyleProperty) {
baseWindow = WindowBuilder.build()
progressViewController = ProgressViewController()
guard let win = baseWindow, let vc = progressViewController else {
return
}
win.rootViewController = vc
win.backgroundColor = UIColor.clear
vc.circle(message: message, style: style, baseWindow: baseWindow)
}
public func dismiss() {
if !isAvailable {
return
}
guard let prop = property else {
return
}
if let vc = progressViewController {
vc.dismiss(prop.dismissTimeInterval!)
}
cleanup(prop.dismissTimeInterval!, completionHandler: nil)
}
public func dismiss(_ completionHandler: @escaping () -> Void) -> () {
if !isAvailable {
return
}
guard let prop = property else {
return
}
if let vc = progressViewController {
vc.dismiss(prop.dismissTimeInterval!)
}
cleanup(prop.dismissTimeInterval!) {
completionHandler()
}
}
private func cleanup(_ t: Double, completionHandler: (() -> Void)?) {
let delay = t * Double(NSEC_PER_SEC)
let time = DispatchTime.now() + Double(Int64(delay)) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: time) { [weak self] in
guard let win = self?.baseWindow else {
return
}
UIView.animate(
withDuration: 0.3,
animations: {
win.alpha = 0
},
completion: { finished in
self?.progressViewController = nil
win.isHidden = true
win.rootViewController = nil
self?.baseWindow = nil
self?.property = nil
self?.isAvailable = false
guard let completionHandler = completionHandler else {
return
}
completionHandler()
}
)
}
}
}
// MARK: Use addSubView
extension GradientCircularProgress {
public func showAtRatio(frame: CGRect, display: Bool = true, style: StyleProperty = Style()) -> UIView? {
if isAvailable {
return nil
}
isAvailable = true
property = Property(style: style)
progressView = ProgressView(frame: frame)
guard let v = progressView else {
return nil
}
v.arc(display, style: style)
return v
}
public func show(frame: CGRect, style: StyleProperty = Style()) -> UIView? {
if isAvailable {
return nil
}
isAvailable = true
property = Property(style: style)
return getProgress(frame: frame, message: nil, style: style)
}
public func show(frame: CGRect, message: String, style: StyleProperty = Style()) -> UIView? {
if isAvailable {
return nil
}
isAvailable = true
property = Property(style: style)
return getProgress(frame: frame, message: message, style: style)
}
private func getProgress(frame: CGRect, message: String?, style: StyleProperty) -> UIView? {
progressView = ProgressView(frame: frame)
guard let v = progressView else {
return nil
}
v.circle(message, style: style)
return v
}
public func dismiss(progress view: UIView) {
if !isAvailable {
return
}
guard let prop = property else {
return
}
cleanup(prop.dismissTimeInterval!, view: view, completionHandler: nil)
}
public func dismiss(progress view: UIView, completionHandler: @escaping () -> Void) -> () {
if !isAvailable {
return
}
guard let prop = property else {
return
}
cleanup(prop.dismissTimeInterval!, view: view) {
completionHandler()
}
}
private func cleanup(_ t: Double, view: UIView, completionHandler: (() -> Void)?) {
let delay = t * Double(NSEC_PER_SEC)
let time = DispatchTime.now() + Double(Int64(delay)) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: time) {
UIView.animate(
withDuration: 0.3,
animations: {
view.alpha = 0
},
completion: { [weak self] finished in
view.removeFromSuperview()
self?.property = nil
self?.isAvailable = false
guard let completionHandler = completionHandler else {
return
}
completionHandler()
}
)
}
}
}
================================================
FILE: source/Progress/Core/CircularProgressView.swift
================================================
//
// CircularProgressView.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class CircularProgressView: UIView {
var prop: Property?
var messageLabel = UILabel()
var centerPoint: CGPoint?
var message: String? {
willSet {
messageLabel.frame = frame
messageLabel.text = newValue
guard let message = messageLabel.text else {
return
}
// Attribute
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineHeightMultiple = 1.2
paragraphStyle.alignment = NSTextAlignment.center
let attr = [NSAttributedString.Key.paragraphStyle: paragraphStyle]
let attributedString = NSMutableAttributedString(string: message, attributes: attr)
messageLabel.attributedText = attributedString
messageLabel.sizeToFit()
if centerPoint == nil {
centerPoint = center
}
if let center = centerPoint {
messageLabel.center = center
}
}
}
var gradientLayer = CALayer()
private struct Animation {
var rotationZ: CABasicAnimation {
let animation: CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.duration = 0.8
animation.repeatCount = HUGE
animation.fromValue = NSNumber(value: 0.0)
animation.toValue = NSNumber(value: 2 * Float.pi)
return animation
}
init() {}
func start(_ layer: CALayer) {
layer.add(rotationZ, forKey: "rotate")
}
func stop(_ layer: CALayer) {
layer.removeAllAnimations()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.clear
layer.masksToBounds = true
NotificationCenter.default.addObserver(self,
selector: #selector(viewDidEnterBackground(_:)),
name: UIApplication.didEnterBackgroundNotification,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(viewWillEnterForeground(_:)),
name: UIApplication.willEnterForegroundNotification,
object: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
NotificationCenter.default.removeObserver(self)
}
override func didMoveToWindow() {
super.didMoveToWindow()
if window != nil {
Animation().start(gradientLayer)
} else {
Animation().stop(gradientLayer)
}
}
@objc private func viewDidEnterBackground(_ notification: Notification?) {
Animation().stop(gradientLayer)
}
@objc private func viewWillEnterForeground(_ notification: Notification?) {
Animation().start(gradientLayer)
}
internal func initialize(frame: CGRect) {
guard let prop = prop else {
return
}
let rect: CGRect = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
// Base Circular
if let baseLineWidth = prop.baseLineWidth, let baseArcColor = prop.baseArcColor {
let circular: ArcView = ArcView(frame: rect, lineWidth: baseLineWidth)
circular.color = baseArcColor
circular.prop = prop
addSubview(circular)
}
// Gradient Circular
if ColorUtil.toRGBA(color: prop.startArcColor).a < 1.0 || ColorUtil.toRGBA(color: prop.endArcColor).a < 1.0 {
// Clear Color
let gradient: UIView = GradientArcWithClearColorView().draw(rect: rect, prop: prop)
addSubview(gradient)
gradientLayer = gradient.layer
Animation().start(gradientLayer)
} else {
// Opaque Color
let gradient: GradientArcView = GradientArcView(frame: rect)
gradient.prop = prop
addSubview(gradient)
gradientLayer = gradient.layer
Animation().start(gradientLayer)
}
}
internal func showMessage(_ message: String) {
guard let prop = prop else {
return
}
// Message
messageLabel.font = prop.messageLabelFont
messageLabel.textAlignment = NSTextAlignment.center
messageLabel.textColor = prop.messageLabelFontColor
messageLabel.numberOfLines = 0
addSubview(messageLabel)
self.message = message
}
}
================================================
FILE: source/Progress/Core/ProgressAtRatioView.swift
================================================
//
// ProgressAtRatioView.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class ProgressAtRatioView: UIView {
internal var arcView: ArcView?
internal var prop: Property?
internal var ratioLabel: UILabel = UILabel()
internal var ratio: CGFloat = 0.0 {
didSet {
ratioLabel.text = String(format:"%.0f", ratio * 100) + "%"
}
}
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.clear
layer.masksToBounds = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
internal func initialize(frame: CGRect) {
guard let prop = prop else {
return
}
let rect: CGRect = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
// Base Circular
if let baseLineWidth = prop.baseLineWidth, let baseArcColor = prop.baseArcColor {
let circular: ArcView = ArcView(frame: rect, lineWidth: baseLineWidth)
circular.prop = prop
circular.ratio = 1.0
circular.color = baseArcColor
circular.lineWidth = baseLineWidth
addSubview(circular)
}
// Gradient Circular
if ColorUtil.toRGBA(color: prop.startArcColor).a < 1.0 || ColorUtil.toRGBA(color: prop.endArcColor).a < 1.0 {
// Clear Color
let gradient: UIView = GradientArcWithClearColorView().draw(rect: rect, prop: prop)
addSubview(gradient)
masking(rect: rect, prop: prop, gradient: gradient)
} else {
// Opaque Color
let gradient: GradientArcView = GradientArcView(frame: rect)
gradient.prop = prop
addSubview(gradient)
masking(rect: rect, prop: prop, gradient: gradient)
}
}
private func masking(rect: CGRect, prop: Property, gradient: UIView) {
// Mask
arcView = ArcView(frame: rect, lineWidth: prop.arcLineWidth)
guard let mask = arcView else {
return
}
mask.prop = prop
gradient.layer.mask = mask.layer
}
override func draw(_ rect: CGRect) {
guard let mask = arcView else {
return
}
if ratio > 1.0 {
mask.ratio = 1.0
} else {
mask.ratio = ratio
}
mask.setNeedsDisplay()
}
func showRatio() {
guard let prop = prop else {
return
}
// Progress Ratio
ratioLabel.text = " "
ratioLabel.font = prop.ratioLabelFont
ratioLabel.textAlignment = NSTextAlignment.right
ratioLabel.textColor = prop.ratioLabelFontColor
ratioLabel.sizeToFit()
ratioLabel.center = center
addSubview(ratioLabel)
}
}
================================================
FILE: source/Progress/Elements/ArcView.swift
================================================
//
// Arc.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class ArcView: UIView {
var prop: Property?
var ratio: CGFloat = 1.0
var color: UIColor = UIColor.black
var lineWidth: CGFloat = 0.0
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
init(frame: CGRect, lineWidth: CGFloat) {
super.init(frame: frame)
backgroundColor = UIColor.clear
layer.masksToBounds = true
self.lineWidth = lineWidth
}
override func draw(_ rect: CGRect) {
drawArc(rect: rect)
}
private func drawArc(rect: CGRect) {
guard let prop = prop else {
return
}
let circularRect: CGRect = prop.progressRect
let arcPoint: CGPoint = CGPoint(x: rect.width/2, y: rect.height/2)
let arcRadius: CGFloat = circularRect.width/2 + prop.arcLineWidth/2
let arcStartAngle: CGFloat = -CGFloat.pi/2
let arcEndAngle: CGFloat = ratio * 2.0 * CGFloat.pi - CGFloat.pi/2
let arc: UIBezierPath = UIBezierPath(arcCenter: arcPoint,
radius: arcRadius,
startAngle: arcStartAngle,
endAngle: arcEndAngle,
clockwise: true)
color.setStroke()
arc.lineWidth = lineWidth
arc.lineCapStyle = prop.arcLineCapStyle
arc.stroke()
}
}
================================================
FILE: source/Progress/Elements/Background.swift
================================================
//
// Background.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
struct Background {
internal func blurEffectView(fromBlurStyle style: BackgroundStyles, frame: CGRect) -> UIVisualEffectView? {
var blurView: UIVisualEffectView?
// return (blurEffectStyle: UIBlurEffectStyle?, isUserInteraction: Bool)
let backgroundStyle = getStyle(style)
if let blur = backgroundStyle.blurEffectStyle {
// UIBlurEffectStyle (.extraLight, .light, .dark)
let effect = UIBlurEffect(style: blur)
blurView = UIVisualEffectView(effect: effect)
} else {
if !backgroundStyle.isUserInteraction {
// .transparent
blurView = UIVisualEffectView(effect: nil)
}
}
blurView?.frame = frame
return blurView
}
private func getStyle(_ style: BackgroundStyles) -> (blurEffectStyle: UIBlurEffect.Style?, isUserInteraction: Bool) {
switch style {
case .extraLight:
return (.extraLight, false)
case .light:
return (.light, false)
case .dark:
return (.dark, false)
case .transparent:
return (nil, false)
default:
// .none
return (nil, true)
}
}
}
================================================
FILE: source/Progress/Elements/GradientArcView.swift
================================================
//
// GradientArcView.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class GradientArcView: UIView {
internal var prop: Property?
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.clear
layer.masksToBounds = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func getGradientPointColor(ratio: CGFloat, startColor: UIColor, endColor: UIColor) -> UIColor {
let sColor = ColorUtil.toRGBA(color: startColor)
let eColor = ColorUtil.toRGBA(color: endColor)
let r = (eColor.r - sColor.r) * ratio + sColor.r
let g = (eColor.g - sColor.g) * ratio + sColor.g
let b = (eColor.b - sColor.b) * ratio + sColor.b
let a = (eColor.a - sColor.a) * ratio + sColor.a
return UIColor(red: r, green: g, blue: b, alpha: a)
}
override func draw(_ rect: CGRect) {
guard let prop = prop else {
return
}
let circularRect: CGRect = prop.progressRect
var currentAngle: CGFloat = 0.0
for i in stride(from:CGFloat(0.0), through: CGFloat(1.0), by: CGFloat(0.005)) {
let arcPoint: CGPoint = CGPoint(x: rect.width/2, y: rect.height/2)
let arcRadius: CGFloat = circularRect.width/2 + prop.arcLineWidth/2
let arcStartAngle: CGFloat = -CGFloat.pi/2
let arcEndAngle: CGFloat = i * 2.0 * CGFloat.pi - CGFloat.pi/2
if currentAngle == 0.0 {
currentAngle = arcStartAngle
} else {
currentAngle = arcEndAngle - 0.05
}
let arc: UIBezierPath = UIBezierPath(arcCenter: arcPoint,
radius: arcRadius,
startAngle: currentAngle,
endAngle: arcEndAngle,
clockwise: true)
let strokeColor: UIColor = getGradientPointColor(ratio: i, startColor: prop.startArcColor, endColor: prop.endArcColor)
strokeColor.setStroke()
arc.lineWidth = prop.arcLineWidth
arc.lineCapStyle = prop.arcLineCapStyle
arc.stroke()
}
}
}
================================================
FILE: source/Progress/Elements/GradientArcWithClearColorView.swift
================================================
//
// GradientArcWithClearColorView.swift
// GradientCircularProgress
//
// Created by keygx on 2015/11/20.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class GradientArcWithClearColorView: UIView {
internal func draw(rect: CGRect, prop: Property) -> UIImageView {
// Gradient Clear Circular
/* Prop */
var startArcColorProp = prop
var endArcColorProp = prop
var startGradientMaskProp = prop
var endGradientMaskProp = prop
var solidMaskProp = prop
// StartArc
startArcColorProp.endArcColor = ColorUtil.toNotOpacityColor(color: startArcColorProp.startArcColor)
// EndArc
endArcColorProp.startArcColor = ColorUtil.toNotOpacityColor(color: endArcColorProp.endArcColor)
// StartGradientMask
startGradientMaskProp.startArcColor = UIColor.black
startGradientMaskProp.endArcColor = UIColor.white
startGradientMaskProp.progressSize += 10.0
startGradientMaskProp.arcLineWidth += 20.0
// EndGradientMask
endGradientMaskProp.startArcColor = UIColor.white
endGradientMaskProp.endArcColor = UIColor.black
endGradientMaskProp.progressSize += 10.0
endGradientMaskProp.arcLineWidth += 20.0
// SolidMask
solidMaskProp.startArcColor = UIColor.black
solidMaskProp.endArcColor = UIColor.black
/* Mask Image */
// StartArcColorImage
let startArcColorView = ArcView(frame: rect, lineWidth: startArcColorProp.arcLineWidth)
startArcColorView.color = startArcColorProp.startArcColor
startArcColorView.prop = startArcColorProp
let startArcColorImage = viewToUIImage(view: startArcColorView)!
// StartGradientMaskImage
let startGradientMaskView = GradientArcView(frame: rect)
startGradientMaskView.prop = startGradientMaskProp
let startGradientMaskImage = viewToUIImage(view: startGradientMaskView)!
// EndArcColorImage
let endArcColorView = ArcView(frame: rect, lineWidth: endArcColorProp.arcLineWidth)
endArcColorView.color = endArcColorProp.startArcColor
endArcColorView.prop = endArcColorProp
let endArcColorImage = viewToUIImage(view: endArcColorView)!
// EndGradientMaskImage
let endGradientMaskView = GradientArcView(frame: rect)
endGradientMaskView.prop = endGradientMaskProp
let endGradientMaskImage = viewToUIImage(view: endGradientMaskView)!
// SolidMaskImage
let solidMaskView = ArcView(frame: rect, lineWidth: solidMaskProp.arcLineWidth)
solidMaskView.prop = solidMaskProp
let solidMaskImage = viewToUIImage(view: solidMaskView)!
/* Masking */
var startArcImage = mask(image: startGradientMaskImage, maskImage: solidMaskImage)
startArcImage = mask(image: startArcColorImage, maskImage: startArcImage)
var endArcImage = mask(image: endGradientMaskImage, maskImage: solidMaskImage)
endArcImage = mask(image: endArcColorImage, maskImage: endArcImage)
/* Composite */
let image: UIImage = composite(image1: startArcImage, image2: endArcImage, prop: prop)
/* UIImageView */
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
return imageView
}
internal func mask(image: UIImage, maskImage: UIImage) -> UIImage {
let maskRef: CGImage = maskImage.cgImage!
let mask: CGImage = CGImage(
maskWidth: maskRef.width,
height: maskRef.height,
bitsPerComponent: maskRef.bitsPerComponent,
bitsPerPixel: maskRef.bitsPerPixel,
bytesPerRow: maskRef.bytesPerRow,
provider: maskRef.dataProvider!,
decode: nil,
shouldInterpolate: false)!
let maskedImageRef: CGImage = image.cgImage!.masking(mask)!
let scale = UIScreen.main.scale
let maskedImage: UIImage = UIImage(cgImage: maskedImageRef, scale: scale, orientation: .up)
return maskedImage
}
internal func viewToUIImage(view: UIView) -> UIImage? {
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(view.frame.size, false, scale)
view.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
internal func composite(image1: UIImage, image2: UIImage, prop: Property) -> UIImage {
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(image1.size, false, scale)
image1.draw(
in: CGRect(x: 0, y: 0, width: image1.size.width, height: image1.size.height),
blendMode: .overlay,
alpha: ColorUtil.toRGBA(color: prop.startArcColor).a)
image2.draw(
in: CGRect(x: 0, y: 0, width: image2.size.width, height: image2.size.height),
blendMode: .overlay,
alpha: ColorUtil.toRGBA(color: prop.endArcColor).a)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
================================================
FILE: source/Progress/Elements/WindowBuilder.swift
================================================
//
// WindowBuilder.swift
// GradientCircularProgress
//
// Created by keygx on 2019/09/24.
// Copyright © 2019 keygx. All rights reserved.
//
import UIKit
class WindowBuilder {
static func build() -> UIWindow? {
var baseWindow: UIWindow?
if #available(iOS 13.0, *) {
let windowScene = UIApplication.shared.connectedScenes
.filter { $0.activationState == .foregroundActive }.first
if let windowScene = windowScene as? UIWindowScene {
baseWindow = UIWindow(windowScene: windowScene)
} else {
baseWindow = UIWindow()
}
} else {
baseWindow = UIWindow()
}
baseWindow?.bounds = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
baseWindow?.backgroundColor = UIColor.clear
baseWindow?.windowLevel = UIWindow.Level.alert + 1
baseWindow?.makeKeyAndVisible()
return baseWindow
}
}
================================================
FILE: source/Progress/ProgressView.swift
================================================
//
// ProgressView.swift
// GradientCircularProgress
//
// Created by keygx on 2016/03/07.
// Copyright (c) 2016年 keygx. All rights reserved.
//
import UIKit
class ProgressView: UIView {
private var viewRect: CGRect?
private var blurView: UIVisualEffectView?
private var progressAtRatioView: ProgressAtRatioView?
private var circularProgressView: CircularProgressView?
internal var prop: Property?
internal var ratio: CGFloat = 0.0 {
didSet {
progressAtRatioView?.ratio = ratio
progressAtRatioView?.setNeedsDisplay()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
initialize(frame: frame)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
private func initialize(frame: CGRect) {
viewRect = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
clipsToBounds = true
}
internal func arc(_ display: Bool, style: StyleProperty) {
prop = Property(style: style)
guard let prop = prop else {
return
}
isUserInteractionEnabled = !(prop.backgroundStyle.rawValue == 0) ? true : false
getBlurView()
progressAtRatioView = ProgressAtRatioView(frame: CGRect(x: 0, y: 0, width: prop.progressSize, height: prop.progressSize))
guard let progressAtRatioView = progressAtRatioView else {
return
}
progressAtRatioView.prop = prop
progressAtRatioView.initialize(frame: progressAtRatioView.frame)
if display {
progressAtRatioView.showRatio()
}
progressAtRatioView.frame = CGRect(
x: (frame.size.width - progressAtRatioView.frame.size.width) / 2,
y: (frame.size.height - progressAtRatioView.frame.size.height) / 2,
width: progressAtRatioView.frame.size.width,
height: progressAtRatioView.frame.size.height)
addSubview(progressAtRatioView)
}
internal func circle(_ message: String?, style: StyleProperty) {
prop = Property(style: style)
guard let prop = prop else {
return
}
isUserInteractionEnabled = !(prop.backgroundStyle.rawValue == 0) ? true : false
getBlurView()
circularProgressView = CircularProgressView(frame: CGRect(x: 0, y: 0, width: prop.progressSize, height: prop.progressSize))
guard let circularProgressView = circularProgressView else {
return
}
circularProgressView.prop = prop
circularProgressView.initialize(frame: circularProgressView.frame)
if let message = message {
circularProgressView.showMessage(message)
}
circularProgressView.frame = CGRect(
x: (frame.size.width - circularProgressView.frame.size.width) / 2,
y: (frame.size.height - circularProgressView.frame.size.height) / 2,
width: circularProgressView.frame.size.width,
height: circularProgressView.frame.size.height)
addSubview(circularProgressView)
}
internal func updateMessage(_ message: String) {
guard let circularProgressView = circularProgressView else {
return
}
circularProgressView.message = message
}
private func getBlurView() {
guard let rect = viewRect, let prop = prop else {
return
}
blurView = Background().blurEffectView(fromBlurStyle: prop.backgroundStyle, frame: rect)
guard let blurView = blurView else {
return
}
backgroundColor = UIColor.clear
addSubview(blurView)
}
}
================================================
FILE: source/Progress/ProgressViewController.swift
================================================
//
// ProgressViewController.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
class ProgressViewController: UIViewController {
private var viewRect: CGRect?
private var blurView: UIVisualEffectView?
private var progressAtRatioView: ProgressAtRatioView?
private var circularProgressView: CircularProgressView?
internal var prop: Property?
internal var ratio: CGFloat = 0.0 {
didSet {
progressAtRatioView?.ratio = ratio
progressAtRatioView?.setNeedsDisplay()
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.clear
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override var shouldAutorotate: Bool {
return false
}
override var prefersStatusBarHidden: Bool {
let orientation: UIInterfaceOrientation
if #available(iOS 13.0, *) {
orientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation ?? .portrait
} else {
orientation = UIApplication.shared.statusBarOrientation
}
switch orientation {
case .landscapeLeft, .landscapeRight:
// LandscapeLeft | LandscapeRight
return true
default:
// Unknown | Portrait | PortraitUpsideDown
return false
}
}
private func getViewRect() {
let window = UIWindow(frame: UIScreen.main.bounds)
viewRect = window.frame
}
private func getBlurView() {
guard let rect = viewRect, let prop = prop else {
return
}
blurView = Background().blurEffectView(fromBlurStyle: prop.backgroundStyle, frame: rect)
guard let blurView = blurView else {
return
}
view.backgroundColor = UIColor.clear
view.addSubview(blurView)
}
internal func arc(display: Bool, style: StyleProperty, baseWindow: UIWindow?) {
prop = Property(style: style)
guard let win = baseWindow, let prop = prop else {
return
}
win.isUserInteractionEnabled = !(prop.backgroundStyle.rawValue == 0) ? true : false // 0 == .None
getViewRect()
getBlurView()
progressAtRatioView = ProgressAtRatioView(frame: CGRect(x: 0, y: 0, width: prop.progressSize, height: prop.progressSize))
guard let progressAtRatioView = progressAtRatioView else {
return
}
progressAtRatioView.prop = prop
progressAtRatioView.initialize(frame: progressAtRatioView.frame)
if display {
progressAtRatioView.showRatio()
}
progressAtRatioView.center = view.center
view.addSubview(progressAtRatioView)
}
internal func circle(message: String?, style: StyleProperty, baseWindow: UIWindow?) {
prop = Property(style: style)
guard let win = baseWindow, let prop = prop else {
return
}
win.isUserInteractionEnabled = !(prop.backgroundStyle.rawValue == 0) ? true : false // 0 == .None
getViewRect()
getBlurView()
circularProgressView = CircularProgressView(frame: CGRect(x: 0, y: 0, width: prop.progressSize, height: prop.progressSize))
guard let circularProgressView = circularProgressView else {
return
}
circularProgressView.prop = prop
circularProgressView.initialize(frame: circularProgressView.frame)
if message != nil {
circularProgressView.showMessage(message!)
}
circularProgressView.center = view.center
view.addSubview(circularProgressView)
}
internal func updateMessage(message: String) {
guard let circularProgressView = circularProgressView else {
return
}
circularProgressView.message = message
}
internal func dismiss(_ t: Double) {
let delay = t * Double(NSEC_PER_SEC)
let time = DispatchTime.now() + Double(Int64(delay)) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: time) {
guard let blurView = self.blurView, let progressAtRatioView = self.progressAtRatioView, let circularProgressView = self.circularProgressView else {
return
}
UIView.animate(
withDuration: 0.3,
animations: {
progressAtRatioView.alpha = 0.0
circularProgressView.alpha = 0.0
},
completion: { finished in
progressAtRatioView.removeFromSuperview()
circularProgressView.removeFromSuperview()
blurView.removeFromSuperview()
}
)
}
}
}
================================================
FILE: source/Progress/Property.swift
================================================
//
// Property.swift
// GradientCircularProgress
//
// Created by keygx on 2015/06/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
public protocol StyleProperty {
// Progress Size
var progressSize: CGFloat { get set }
// Gradient Circular
var arcLineWidth: CGFloat { get set }
var startArcColor: UIColor { get set }
var endArcColor: UIColor { get set }
// Base Circular
var baseLineWidth: CGFloat? { get set }
var baseArcColor: UIColor? { get set }
// Ratio
var ratioLabelFont: UIFont? { get set }
var ratioLabelFontColor: UIColor? { get set }
// Message
var messageLabelFont: UIFont? { get set }
var messageLabelFontColor: UIColor? { get set }
// Background
var backgroundStyle: BackgroundStyles { get set }
// Dismiss
var dismissTimeInterval: Double? { get set }
// Initialize
init()
}
public enum BackgroundStyles: Int {
case none = 0
case extraLight
case light
case dark
case transparent
}
internal struct Property {
let margin: CGFloat = 5.0
let arcLineCapStyle: CGLineCap = CGLineCap.butt
// Progress Size
var progressSize: CGFloat
// Gradient Circular
var arcLineWidth: CGFloat
var startArcColor: UIColor
var endArcColor: UIColor
// Base Circular
var baseLineWidth: CGFloat?
var baseArcColor: UIColor?
// Ratio
let ratioLabelFont: UIFont?
let ratioLabelFontColor: UIColor?
// Message
let messageLabelFont: UIFont?
let messageLabelFontColor: UIColor?
// Background
let backgroundStyle: BackgroundStyles
// Dismiss
let dismissTimeInterval: Double?
// Progress Rect
var progressRect: CGRect {
let lineWidth: CGFloat = (arcLineWidth > baseLineWidth!) ? arcLineWidth : baseLineWidth!
return CGRect(x: 0, y: 0, width: progressSize - lineWidth * 2, height: progressSize - lineWidth * 2)
}
init(style: StyleProperty) {
let styles: StyleProperty = style
progressSize = styles.progressSize
arcLineWidth = styles.arcLineWidth
startArcColor = styles.startArcColor
endArcColor = styles.endArcColor
baseLineWidth = styles.baseLineWidth ?? 0.0
baseArcColor = styles.baseArcColor ?? UIColor.clear
ratioLabelFont = styles.ratioLabelFont ?? UIFont.systemFont(ofSize: 16.0)
ratioLabelFontColor = styles.ratioLabelFontColor ?? UIColor.clear
messageLabelFont = styles.messageLabelFont ?? UIFont.systemFont(ofSize: 16.0)
messageLabelFontColor = styles.messageLabelFontColor ?? UIColor.clear
backgroundStyle = styles.backgroundStyle
dismissTimeInterval = styles.dismissTimeInterval ?? 0.8
}
}
================================================
FILE: source/Styles/BlueDarkStyle.swift
================================================
//
// BlueDarkStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/08/31.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public struct BlueDarkStyle: StyleProperty {
// Progress Size
public var progressSize: CGFloat = 260
// Gradient Circular
public var arcLineWidth: CGFloat = 4.0
public var startArcColor: UIColor = ColorUtil.toUIColor(r: 0.0, g: 122.0, b: 255.0, a: 1.0)
public var endArcColor: UIColor = UIColor.cyan
// Base Circular
public var baseLineWidth: CGFloat? = 5.0
public var baseArcColor: UIColor? = UIColor(red:0.0, green: 0.0, blue: 0.0, alpha: 0.2)
// Ratio
public var ratioLabelFont: UIFont? = UIFont(name: "Verdana-Bold", size: 16.0)
public var ratioLabelFontColor: UIColor? = UIColor.white
// Message
public var messageLabelFont: UIFont? = UIFont.systemFont(ofSize: 16.0)
public var messageLabelFontColor: UIColor? = UIColor.white
// Background
public var backgroundStyle: BackgroundStyles = .dark
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
public init() {}
}
================================================
FILE: source/Styles/BlueIndicatorStyle.swift
================================================
//
// BlueIndicatorStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/08/31.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public struct BlueIndicatorStyle: StyleProperty {
// Progress Size
public var progressSize: CGFloat = 44
// Gradient Circular
public var arcLineWidth: CGFloat = 4.0
public var startArcColor: UIColor = ColorUtil.toUIColor(r: 235.0, g: 245.0, b: 255.0, a: 1.0)
public var endArcColor: UIColor = ColorUtil.toUIColor(r: 0.0, g: 122.0, b: 255.0, a: 1.0)
// Base Circular
public var baseLineWidth: CGFloat? = 4.0
public var baseArcColor: UIColor? = ColorUtil.toUIColor(r: 215.0, g: 215.0, b: 215.0, a: 0.4)
// Ratio
public var ratioLabelFont: UIFont? = nil
public var ratioLabelFontColor: UIColor? = nil
// Message
public var messageLabelFont: UIFont? = nil
public var messageLabelFontColor: UIColor? = nil
// Background
public var backgroundStyle: BackgroundStyles = .none
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
public init() {}
}
================================================
FILE: source/Styles/GreenLightStyle.swift
================================================
//
// GreenLightStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/11/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public struct GreenLightStyle: StyleProperty {
// Progress Size
public var progressSize: CGFloat = 200
// Gradient Circular
public var arcLineWidth: CGFloat = 32.0
public var startArcColor: UIColor = ColorUtil.toUIColor(r: 40.0, g: 110.0, b: 60.0, a: 1.0)
public var endArcColor: UIColor = UIColor.green
// Base Circular
public var baseLineWidth: CGFloat? = 1.0
public var baseArcColor: UIColor? = UIColor(red:0.0, green: 0.0, blue: 0.0, alpha: 0.1)
// Ratio
public var ratioLabelFont: UIFont? = UIFont(name: "Verdana-Bold", size: 18.0)
public var ratioLabelFontColor: UIColor? = UIColor.darkGray
// Message
public var messageLabelFont: UIFont? = UIFont(name: "Verdana", size: 18.0)
public var messageLabelFontColor: UIColor? = UIColor.darkGray
// Background
public var backgroundStyle: BackgroundStyles = .light
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
public init() {}
}
================================================
FILE: source/Styles/OrangeClearStyle.swift
================================================
//
// OrangeClearStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/11/24.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public struct OrangeClearStyle: StyleProperty {
// Progress Size
public var progressSize: CGFloat = 80
// Gradient Circular
public var arcLineWidth: CGFloat = 6.0
public var startArcColor: UIColor = UIColor.clear
public var endArcColor: UIColor = UIColor.orange
// Base Circular
public var baseLineWidth: CGFloat? = nil
public var baseArcColor: UIColor? = nil
// Ratio
public var ratioLabelFont: UIFont? = UIFont.systemFont(ofSize: 13.0)
public var ratioLabelFontColor: UIColor? = UIColor.black
// Message
public var messageLabelFont: UIFont? = nil
public var messageLabelFontColor: UIColor? = nil
// Background
public var backgroundStyle: BackgroundStyles = .none
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
public init() {}
}
================================================
FILE: source/Styles/Style.swift
================================================
//
// DefaultStyle.swift
// GradientCircularProgress
//
// Created by keygx on 2015/08/31.
// Copyright (c) 2015年 keygx. All rights reserved.
//
import UIKit
public struct Style: StyleProperty {
// Progress Size
public var progressSize: CGFloat = 220
// Gradient Circular
public var arcLineWidth: CGFloat = 16.0
public var startArcColor: UIColor = ColorUtil.toUIColor(r: 230.0, g: 230.0, b: 230.0, a: 0.6)
public var endArcColor: UIColor = ColorUtil.toUIColor(r: 90.0, g: 90.0, b: 90.0, a: 1.0)
// Base Circular
public var baseLineWidth: CGFloat? = 16.0
public var baseArcColor: UIColor? = UIColor(red:1.0, green: 1.0, blue: 1.0, alpha: 0.8)
// Ratio
public var ratioLabelFont: UIFont? = UIFont.systemFont(ofSize: 18.0)
public var ratioLabelFontColor: UIColor? = UIColor.black
// Message
public var messageLabelFont: UIFont? = UIFont.systemFont(ofSize: 18.0)
public var messageLabelFontColor: UIColor? = UIColor.black
// Background
public var backgroundStyle: BackgroundStyles = .extraLight
// Dismiss
public var dismissTimeInterval: Double? = nil // 'nil' for default setting.
public init() {}
}
================================================
FILE: source/Utils/ColorUtil.swift
================================================
//
// ColorUtil.swift
// GradientCircularProgress
//
// Created by keygx on 2015/11/23.
// Copyright © 2015年 keygx. All rights reserved.
//
import UIKit
public class ColorUtil {
public class func toUIColor(r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) -> UIColor {
return UIColor(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: a)
}
internal class func toRGBA(color: UIColor) -> (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) {
var r: CGFloat = 0.0
var g: CGFloat = 0.0
var b: CGFloat = 0.0
var a: CGFloat = 0.0
color.getRed(&r, green: &g, blue: &b, alpha: &a)
return (r, g, b, a)
}
internal class func toNotOpacityColor(color: UIColor) -> UIColor {
if color == UIColor.clear {
return UIColor.white
} else {
return UIColor(
red: ColorUtil.toRGBA(color: color).r,
green: ColorUtil.toRGBA(color: color).g,
blue: ColorUt
gitextract_v1j42pdv/
├── .gitignore
├── GCProgressSample/
│ ├── GCProgressSample/
│ │ ├── AlertHelperKit.swift
│ │ ├── AppDelegate.swift
│ │ ├── AsyncUtil.swift
│ │ ├── BackgroundTransparentStyle.swift
│ │ ├── Base.lproj/
│ │ │ ├── LaunchScreen.xib
│ │ │ └── Main.storyboard
│ │ ├── Images.xcassets/
│ │ │ └── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ ├── MyButton.swift
│ │ ├── MyStyle.swift
│ │ └── ViewController.swift
│ ├── GCProgressSample.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── GradientCircularProgress.xcscheme
│ ├── GCProgressSampleTests/
│ │ ├── GCProgressSampleTests.swift
│ │ └── Info.plist
│ └── GradientCircularProgress/
│ ├── GradientCircularProgress.h
│ ├── GradientCircularProgress.swift
│ ├── Info.plist
│ ├── Progress/
│ │ ├── Core/
│ │ │ ├── CircularProgressView.swift
│ │ │ └── ProgressAtRatioView.swift
│ │ ├── Elements/
│ │ │ ├── ArcView.swift
│ │ │ ├── Background.swift
│ │ │ ├── GradientArcView.swift
│ │ │ ├── GradientArcWithClearColorView.swift
│ │ │ └── WindowBuilder.swift
│ │ ├── ProgressView.swift
│ │ ├── ProgressViewController.swift
│ │ └── Property.swift
│ ├── Styles/
│ │ ├── BlueDarkStyle.swift
│ │ ├── BlueIndicatorStyle.swift
│ │ ├── GreenLightStyle.swift
│ │ ├── OrangeClearStyle.swift
│ │ └── Style.swift
│ └── Utils/
│ └── ColorUtil.swift
├── GradientCircularProgress.podspec
├── LICENSE
├── README.md
├── Sample/
│ ├── BackgroundTransparentStyle.swift
│ └── MyStyle.swift
└── source/
├── GradientCircularProgress.h
├── GradientCircularProgress.swift
├── Progress/
│ ├── Core/
│ │ ├── CircularProgressView.swift
│ │ └── ProgressAtRatioView.swift
│ ├── Elements/
│ │ ├── ArcView.swift
│ │ ├── Background.swift
│ │ ├── GradientArcView.swift
│ │ ├── GradientArcWithClearColorView.swift
│ │ └── WindowBuilder.swift
│ ├── ProgressView.swift
│ ├── ProgressViewController.swift
│ └── Property.swift
├── Styles/
│ ├── BlueDarkStyle.swift
│ ├── BlueIndicatorStyle.swift
│ ├── GreenLightStyle.swift
│ ├── OrangeClearStyle.swift
│ └── Style.swift
└── Utils/
└── ColorUtil.swift
Condensed preview — 60 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (205K chars).
[
{
"path": ".gitignore",
"chars": 683,
"preview": "# Created by https://www.gitignore.io\n\n### Swift ###\n# Xcode\n#\nbuild/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode"
},
{
"path": "GCProgressSample/GCProgressSample/AlertHelperKit.swift",
"chars": 6811,
"preview": "//\n// AlertHelperKit.swift\n//\n// Created by keygx on 2015/07/21.\n// Copyright (c) 2015年 keygx. All rights reserved.\n/"
},
{
"path": "GCProgressSample/GCProgressSample/AppDelegate.swift",
"chars": 2164,
"preview": "//\n// AppDelegate.swift\n// GCProgressSample\n//\n// Created by keygx on 2015/06/21.\n// Copyright (c) 2015年 keygx. All "
},
{
"path": "GCProgressSample/GCProgressSample/AsyncUtil.swift",
"chars": 591,
"preview": "//\n// AsyncUtil.swift\n// GCProgressSample\n//\n// Created by keygx on 2016/02/20.\n// Copyright (c) 2015年 keygx. All ri"
},
{
"path": "GCProgressSample/GCProgressSample/BackgroundTransparentStyle.swift",
"chars": 1457,
"preview": "//\n// BackgroundTransparentStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2016/12/03.\n// Copyrigh"
},
{
"path": "GCProgressSample/GCProgressSample/Base.lproj/LaunchScreen.xib",
"chars": 2696,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVe"
},
{
"path": "GCProgressSample/GCProgressSample/Base.lproj/Main.storyboard",
"chars": 12847,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
},
{
"path": "GCProgressSample/GCProgressSample/Images.xcassets/AppIcon.appiconset/Contents.json",
"chars": 1495,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"iphone\",\n \"size\" : \"20x20\",\n \"scale\" : \"2x\"\n },\n {\n \"idiom\""
},
{
"path": "GCProgressSample/GCProgressSample/Info.plist",
"chars": 1537,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "GCProgressSample/GCProgressSample/MyButton.swift",
"chars": 1448,
"preview": "//\n// MyButton.swift\n// GCProgressSample\n//\n// Created by keygx on 2016/03/12.\n// Copyright © 2016年 keygx. All right"
},
{
"path": "GCProgressSample/GCProgressSample/MyStyle.swift",
"chars": 1348,
"preview": "//\n// MyStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/11/25.\n// Copyright (c) 2015年 keygx. "
},
{
"path": "GCProgressSample/GCProgressSample/ViewController.swift",
"chars": 8577,
"preview": "//\n// ViewController.swift\n// GCProgressSample\n//\n// Created by keygx on 2016/03/12.\n// Copyright (c) 2015年 keygx. A"
},
{
"path": "GCProgressSample/GCProgressSample.xcodeproj/project.pbxproj",
"chars": 37052,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "GCProgressSample/GCProgressSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 161,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:GCProgressSampl"
},
{
"path": "GCProgressSample/GCProgressSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "GCProgressSample/GCProgressSample.xcodeproj/xcshareddata/xcschemes/GradientCircularProgress.xcscheme",
"chars": 2873,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1100\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "GCProgressSample/GCProgressSampleTests/GCProgressSampleTests.swift",
"chars": 914,
"preview": "//\n// GCProgressSampleTests.swift\n// GCProgressSampleTests\n//\n// Created by keygx on 2015/06/21.\n// Copyright (c) 20"
},
{
"path": "GCProgressSample/GCProgressSampleTests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "GCProgressSample/GradientCircularProgress/GradientCircularProgress.h",
"chars": 594,
"preview": "//\n// GradientCircularProgress.h\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) "
},
{
"path": "GCProgressSample/GradientCircularProgress/GradientCircularProgress.swift",
"chars": 7826,
"preview": "//\n// GradientCircularProgress.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/07/29.\n// Copyright "
},
{
"path": "GCProgressSample/GradientCircularProgress/Info.plist",
"chars": 823,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "GCProgressSample/GradientCircularProgress/Progress/Core/CircularProgressView.swift",
"chars": 5170,
"preview": "//\n// CircularProgressView.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) "
},
{
"path": "GCProgressSample/GradientCircularProgress/Progress/Core/ProgressAtRatioView.swift",
"chars": 3127,
"preview": "//\n// ProgressAtRatioView.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) 2"
},
{
"path": "GCProgressSample/GradientCircularProgress/Progress/Elements/ArcView.swift",
"chars": 1709,
"preview": "//\n// Arc.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) 2015年 keygx. All "
},
{
"path": "GCProgressSample/GradientCircularProgress/Progress/Elements/Background.swift",
"chars": 1445,
"preview": "//\n// Background.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) 2015年 keyg"
},
{
"path": "GCProgressSample/GradientCircularProgress/Progress/Elements/GradientArcView.swift",
"chars": 2572,
"preview": "//\n// GradientArcView.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) 2015年"
},
{
"path": "GCProgressSample/GradientCircularProgress/Progress/Elements/GradientArcWithClearColorView.swift",
"chars": 5470,
"preview": "//\n// GradientArcWithClearColorView.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/11/20.\n// Copyr"
},
{
"path": "GCProgressSample/GradientCircularProgress/Progress/Elements/WindowBuilder.swift",
"chars": 1050,
"preview": "//\n// WindowBuilder.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2019/09/24.\n// Copyright © 2019 keyg"
},
{
"path": "GCProgressSample/GradientCircularProgress/Progress/ProgressView.swift",
"chars": 3981,
"preview": "//\n// ProgressView.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2016/03/07.\n// Copyright (c) 2016年 ke"
},
{
"path": "GCProgressSample/GradientCircularProgress/Progress/ProgressViewController.swift",
"chars": 5259,
"preview": "//\n// ProgressViewController.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c"
},
{
"path": "GCProgressSample/GradientCircularProgress/Progress/Property.swift",
"chars": 2930,
"preview": "//\n// Property.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) 2015年 keygx."
},
{
"path": "GCProgressSample/GradientCircularProgress/Styles/BlueDarkStyle.swift",
"chars": 1183,
"preview": "//\n// BlueDarkStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/08/31.\n// Copyright (c) 2015年 k"
},
{
"path": "GCProgressSample/GradientCircularProgress/Styles/BlueIndicatorStyle.swift",
"chars": 1158,
"preview": "//\n// BlueIndicatorStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/08/31.\n// Copyright (c) 20"
},
{
"path": "GCProgressSample/GradientCircularProgress/Styles/GreenLightStyle.swift",
"chars": 1200,
"preview": "//\n// GreenLightStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/11/24.\n// Copyright (c) 2015年"
},
{
"path": "GCProgressSample/GradientCircularProgress/Styles/OrangeClearStyle.swift",
"chars": 1053,
"preview": "//\n// OrangeClearStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/11/24.\n// Copyright (c) 2015"
},
{
"path": "GCProgressSample/GradientCircularProgress/Styles/Style.swift",
"chars": 1217,
"preview": "//\n// DefaultStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/08/31.\n// Copyright (c) 2015年 ke"
},
{
"path": "GCProgressSample/GradientCircularProgress/Utils/ColorUtil.swift",
"chars": 1119,
"preview": "//\n// ColorUtil.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/11/23.\n// Copyright © 2015年 keygx. "
},
{
"path": "GradientCircularProgress.podspec",
"chars": 588,
"preview": "Pod::Spec.new do |s|\n s.name = \"GradientCircularProgress\"\n s.version = \"3.13.0\"\n s.summary = \"Customizable progress i"
},
{
"path": "LICENSE",
"chars": 1083,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Yukihiko Kagiyama\n\nPermission is hereby granted, free of charge, to any person"
},
{
"path": "README.md",
"chars": 5313,
"preview": "# Gradient Circular Progress\n\nCustomizable progress indicator library in Swift\n\n## Requirements\n- Swift 5.1\n- iOS 8.0 or"
},
{
"path": "Sample/BackgroundTransparentStyle.swift",
"chars": 1469,
"preview": "//\n// BackgroundTransparentStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2016/12/03.\n// Copyrigh"
},
{
"path": "Sample/MyStyle.swift",
"chars": 1360,
"preview": "//\n// MyStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/11/25.\n// Copyright (c) 2015年 keygx. "
},
{
"path": "source/GradientCircularProgress.h",
"chars": 594,
"preview": "//\n// GradientCircularProgress.h\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) "
},
{
"path": "source/GradientCircularProgress.swift",
"chars": 7826,
"preview": "//\n// GradientCircularProgress.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/07/29.\n// Copyright "
},
{
"path": "source/Progress/Core/CircularProgressView.swift",
"chars": 5170,
"preview": "//\n// CircularProgressView.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) "
},
{
"path": "source/Progress/Core/ProgressAtRatioView.swift",
"chars": 3127,
"preview": "//\n// ProgressAtRatioView.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) 2"
},
{
"path": "source/Progress/Elements/ArcView.swift",
"chars": 1709,
"preview": "//\n// Arc.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) 2015年 keygx. All "
},
{
"path": "source/Progress/Elements/Background.swift",
"chars": 1445,
"preview": "//\n// Background.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) 2015年 keyg"
},
{
"path": "source/Progress/Elements/GradientArcView.swift",
"chars": 2572,
"preview": "//\n// GradientArcView.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) 2015年"
},
{
"path": "source/Progress/Elements/GradientArcWithClearColorView.swift",
"chars": 5470,
"preview": "//\n// GradientArcWithClearColorView.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/11/20.\n// Copyr"
},
{
"path": "source/Progress/Elements/WindowBuilder.swift",
"chars": 1050,
"preview": "//\n// WindowBuilder.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2019/09/24.\n// Copyright © 2019 keyg"
},
{
"path": "source/Progress/ProgressView.swift",
"chars": 3981,
"preview": "//\n// ProgressView.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2016/03/07.\n// Copyright (c) 2016年 ke"
},
{
"path": "source/Progress/ProgressViewController.swift",
"chars": 5259,
"preview": "//\n// ProgressViewController.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c"
},
{
"path": "source/Progress/Property.swift",
"chars": 2930,
"preview": "//\n// Property.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/06/24.\n// Copyright (c) 2015年 keygx."
},
{
"path": "source/Styles/BlueDarkStyle.swift",
"chars": 1183,
"preview": "//\n// BlueDarkStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/08/31.\n// Copyright (c) 2015年 k"
},
{
"path": "source/Styles/BlueIndicatorStyle.swift",
"chars": 1158,
"preview": "//\n// BlueIndicatorStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/08/31.\n// Copyright (c) 20"
},
{
"path": "source/Styles/GreenLightStyle.swift",
"chars": 1200,
"preview": "//\n// GreenLightStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/11/24.\n// Copyright (c) 2015年"
},
{
"path": "source/Styles/OrangeClearStyle.swift",
"chars": 1053,
"preview": "//\n// OrangeClearStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/11/24.\n// Copyright (c) 2015"
},
{
"path": "source/Styles/Style.swift",
"chars": 1217,
"preview": "//\n// DefaultStyle.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/08/31.\n// Copyright (c) 2015年 ke"
},
{
"path": "source/Utils/ColorUtil.swift",
"chars": 1119,
"preview": "//\n// ColorUtil.swift\n// GradientCircularProgress\n//\n// Created by keygx on 2015/11/23.\n// Copyright © 2015年 keygx. "
}
]
About this extraction
This page contains the full source code of the keygx/GradientCircularProgress GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 60 files (185.9 KB), approximately 49.0k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.