├── Cartfile
├── Gemfile
├── Cartfile.resolved
├── ZVProgressHUDExample
├── smile.png
├── Assets.xcassets
│ ├── Contents.json
│ ├── smile.imageset
│ │ ├── Smile.png
│ │ └── Contents.json
│ ├── close.imageset
│ │ ├── close@2x.png
│ │ ├── close@3x.png
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── Icon-20.png
│ │ ├── Icon-29.png
│ │ ├── Icon-40.png
│ │ ├── Icon-76.png
│ │ ├── Icon-20@2x.png
│ │ ├── Icon-20@3x.png
│ │ ├── Icon-29@2x.png
│ │ ├── Icon-29@3x.png
│ │ ├── Icon-40@2x.png
│ │ ├── Icon-40@3x.png
│ │ ├── Icon-60@2x.png
│ │ ├── Icon-60@3x.png
│ │ ├── Icon-76@2x.png
│ │ ├── Icon-83_5@2x.png
│ │ ├── ios-marketing.png
│ │ └── Contents.json
│ ├── logo_crown.imageset
│ │ ├── logo_crown@2x.png
│ │ ├── logo_crown@3x.png
│ │ └── Contents.json
│ ├── loading_01.imageset
│ │ ├── dropdown_loading_01@2x.png
│ │ └── Contents.json
│ ├── loading_02.imageset
│ │ ├── dropdown_loading_02@2x.png
│ │ └── Contents.json
│ └── loading_03.imageset
│ │ ├── dropdown_loading_03@2x.png
│ │ └── Contents.json
├── Info.plist
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── AppDelegate.swift
├── ZVDownloadingView.swift
└── ViewController.swift
├── ZVProgressHUD
├── Resource.bundle
│ ├── error.png
│ ├── success.png
│ └── warning.png
├── ZVProgressHUD.h
├── Info.plist
├── ZVProgressView.swift
├── ZVIndicatorView.swift
├── ZVProgressHUDExtensions.swift
└── ZVProgressHUD.swift
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── contents.xcworkspacedata
├── ZVProgressHUD.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
├── xcshareddata
│ └── xcschemes
│ │ └── ZVProgressHUD.xcscheme
└── project.pbxproj
├── fastlane
├── Appfile
├── Fastfile
└── README.md
├── Package.resolved
├── Package.swift
├── LICENSE
├── ZVProgressHUD.podspec
├── .gitignore
├── .swiftlint.yml
├── README_CN.md
├── README.md
└── Gemfile.lock
/Cartfile:
--------------------------------------------------------------------------------
1 | github "zevwings/ZVActivityIndicatorView"
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "fastlane"
4 |
--------------------------------------------------------------------------------
/Cartfile.resolved:
--------------------------------------------------------------------------------
1 | github "zevwings/ZVActivityIndicatorView" "1.0.0"
2 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/smile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/smile.png
--------------------------------------------------------------------------------
/ZVProgressHUD/Resource.bundle/error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUD/Resource.bundle/error.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ZVProgressHUD/Resource.bundle/success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUD/Resource.bundle/success.png
--------------------------------------------------------------------------------
/ZVProgressHUD/Resource.bundle/warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUD/Resource.bundle/warning.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/smile.imageset/Smile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/smile.imageset/Smile.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/close.imageset/close@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/close.imageset/close@2x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/close.imageset/close@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/close.imageset/close@3x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-20.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-29.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-40.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-76.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-20@2x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-20@3x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-29@2x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-29@3x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-83_5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Icon-83_5@2x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/ios-marketing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/ios-marketing.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/logo_crown.imageset/logo_crown@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/logo_crown.imageset/logo_crown@2x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/logo_crown.imageset/logo_crown@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/logo_crown.imageset/logo_crown@3x.png
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/loading_01.imageset/dropdown_loading_01@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/loading_01.imageset/dropdown_loading_01@2x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/loading_02.imageset/dropdown_loading_02@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/loading_02.imageset/dropdown_loading_02@2x.png
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/loading_03.imageset/dropdown_loading_03@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zevwings/ZVProgressHUD/HEAD/ZVProgressHUDExample/Assets.xcassets/loading_03.imageset/dropdown_loading_03@2x.png
--------------------------------------------------------------------------------
/ZVProgressHUD.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | # app_identifier("[[APP_IDENTIFIER]]") # The bundle identifier of your app
2 | # apple_id("[[APPLE_ID]]") # Your Apple email address
3 |
4 |
5 | # For more information about the Appfile, see:
6 | # https://docs.fastlane.tools/advanced/#appfile
7 |
--------------------------------------------------------------------------------
/ZVProgressHUD.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "ZVActivityIndicatorView",
6 | "repositoryURL": "https://github.com/zevwings/ZVActivityIndicatorView.git",
7 | "state": {
8 | "branch": null,
9 | "revision": "cad655bc187df933f9e21017873d11f72c08c038",
10 | "version": "0.2.4"
11 | }
12 | }
13 | ]
14 | },
15 | "version": 1
16 | }
17 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/smile.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Smile.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/loading_01.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "dropdown_loading_01@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/loading_02.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "dropdown_loading_02@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/loading_03.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "dropdown_loading_03@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ZVProgressHUD.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "ZVActivityIndicatorView",
6 | "repositoryURL": "https://github.com/zevwings/ZVActivityIndicatorView.git",
7 | "state": {
8 | "branch": null,
9 | "revision": "cad655bc187df933f9e21017873d11f72c08c038",
10 | "version": "0.2.4"
11 | }
12 | }
13 | ]
14 | },
15 | "version": 1
16 | }
17 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/close.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "close@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "close@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/logo_crown.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "logo_crown@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "logo_crown@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/ZVProgressHUD/ZVProgressHUD.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZVProgressHUD.h
3 | // ZVProgressHUD
4 | //
5 | // Created by zevwings on 2017/7/11.
6 | // Copyright © 2017-2019 zevwings. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for ZVProgressHUD.
12 | FOUNDATION_EXPORT double ZVProgressHUDVersionNumber;
13 |
14 | //! Project version string for ZVProgressHUD.
15 | FOUNDATION_EXPORT const unsigned char ZVProgressHUDVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/fastlane/Fastfile:
--------------------------------------------------------------------------------
1 | # This file contains the fastlane.tools configuration
2 | # You can find the documentation at https://docs.fastlane.tools
3 | #
4 | # For a list of all available actions, check out
5 | #
6 | # https://docs.fastlane.tools/actions
7 | #
8 | # For a list of all available plugins, check out
9 | #
10 | # https://docs.fastlane.tools/plugins/available-plugins
11 | #
12 |
13 | # Uncomment the line if you want fastlane to automatically update itself
14 | # update_fastlane
15 |
16 | default_platform(:ios)
17 |
18 | platform :ios do
19 |
20 | desc "Build and upload to appetize"
21 | lane :upload_appetize do |options|
22 | git_pull
23 | build_and_upload_to_appetize(scheme: "ZVProgressHUDExample", api_token: "tok_8hajudt52c6921vcq5pzht6u4c", public_key: "39txw9h5d7mrkckm6f9vp9mn2r")
24 | end
25 |
26 | end
27 |
--------------------------------------------------------------------------------
/fastlane/README.md:
--------------------------------------------------------------------------------
1 | fastlane documentation
2 | ================
3 | # Installation
4 |
5 | Make sure you have the latest version of the Xcode command line tools installed:
6 |
7 | ```
8 | xcode-select --install
9 | ```
10 |
11 | Install _fastlane_ using
12 | ```
13 | [sudo] gem install fastlane -NV
14 | ```
15 | or alternatively using `brew install fastlane`
16 |
17 | # Available Actions
18 | ## iOS
19 | ### ios upload_appetize
20 | ```
21 | fastlane ios upload_appetize
22 | ```
23 | Build and upload to appetize
24 |
25 | ----
26 |
27 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
28 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools).
29 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
30 |
--------------------------------------------------------------------------------
/ZVProgressHUD/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.3
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "ZVProgressHUD",
8 | platforms: [.iOS(.v9)],
9 | products: [
10 | .library(
11 | name: "ZVProgressHUD",
12 | targets: ["ZVProgressHUD"]),
13 | ],
14 | dependencies: [
15 | .package(url: "https://github.com/zevwings/ZVActivityIndicatorView.git", from: "0.2.1"),
16 | ],
17 | targets: [
18 | .target(
19 | name: "ZVProgressHUD",
20 | dependencies: ["ZVActivityIndicatorView"],
21 | path: "./ZVProgressHUD",
22 | exclude: ["Info.plist"],
23 | resources: [
24 | .process("Resource.bundle")
25 | ],
26 | swiftSettings: [
27 | .define("ZVProgressHUD_SPM")
28 | ]
29 | )
30 | ],
31 | swiftLanguageVersions: [.v5]
32 | )
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ZVProgressHUD.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod spec lint ZVProgressHUD.podspec' to ensure this is a
3 | # valid spec and to remove all comments including this before submitting the spec.
4 | #
5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
7 | #
8 |
9 | Pod::Spec.new do |s|
10 |
11 | s.name = "ZVProgressHUD"
12 | s.version = "3.0.6"
13 | s.summary = "A pure-swift and wieldy HUD"
14 | s.swift_version = '5.1'
15 |
16 | s.description = <<-DESC
17 | ZVProgressHUD a pure-swift and wieldy HUD
18 | DESC
19 |
20 | s.homepage = "https://github.com/zevwings/ZVProgressHUD"
21 | s.license = "MIT"
22 | s.author = { "zevwings" => "zevwings@gmail.com" }
23 | s.platform = :ios, "9.0"
24 | s.source = { :git => "https://github.com/zevwings/ZVProgressHUD.git", :tag => "#{s.version}" }
25 | s.source_files = "ZVProgressHUD/**/*.swift", "ZVProgressHUD/ZVProgressHUD.h"
26 | s.resources = "ZVProgressHUD/Resource.bundle"
27 | s.requires_arc = true
28 |
29 | s.dependency 'ZVActivityIndicatorView'
30 |
31 | end
32 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | ## Playgrounds
32 | timeline.xctimeline
33 | playground.xcworkspace
34 |
35 | # Swift Package Manager
36 | #
37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
38 | # Packages/
39 | # Package.pins
40 | .build/
41 |
42 | # CocoaPods
43 | #
44 | # We recommend against adding the Pods directory to your .gitignore. However
45 | # you should judge for yourself, the pros and cons are mentioned at:
46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
47 | #
48 | # Pods/
49 |
50 | # Carthage
51 | #
52 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
53 | Carthage/
54 |
55 | # fastlane
56 | #
57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
58 | # screenshots whenever they are needed.
59 | # For more information about the recommended setup visit:
60 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
61 |
62 | fastlane/report.xml
63 | fastlane/Preview.html
64 | fastlane/screenshots
65 | fastlane/test_output
66 |
--------------------------------------------------------------------------------
/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | disabled_rules: # rule identifiers to exclude from running
2 | - colon
3 | # - comma
4 | - control_statement
5 | - trailing_whitespace
6 | - file_length
7 | opt_in_rules: # some rules are only opt-in
8 | - empty_count
9 | # Find all the available rules by running:
10 | # swiftlint rules
11 | included: # paths to include during linting. `--path` is ignored if present.
12 | - ZVProgressHUD
13 | excluded: # paths to ignore during linting. Takes precedence over `included`.
14 | - Carthage
15 | - Pods
16 | - Source/ExcludedFolder
17 | - Source/ExcludedFile.swift
18 | - Source/*/ExcludedFile.swift # Exclude files with a wildcard
19 | analyzer_rules: # Rules run by `swiftlint analyze` (experimental)
20 | - explicit_self
21 |
22 | # configurable rules can be customized from this configuration file
23 | # binary rules can set their severity level
24 | force_cast: warning # implicitly
25 | force_try:
26 | severity: warning # explicitly
27 | # rules that have both warning and error levels, can set just the warning level
28 | # implicitly
29 | line_length: 120
30 | # they can set both implicitly with an array
31 | type_body_length:
32 | - 300 # warning
33 | - 400 # error
34 | # or they can set both explicitly
35 | #file_length:
36 | # warning: 800
37 | # error: 1200
38 | function_body_length:
39 | warning: 60
40 | error: 80
41 |
42 | # naming rules can set warnings/errors for min_length and max_length
43 | # additionally they can set excluded names
44 | type_name:
45 | min_length: 3 # only warning
46 | max_length: # warning and error
47 | warning: 40
48 | error: 50
49 | excluded: iPhone # excluded via string
50 | identifier_name:
51 | min_length: # only min_length
52 | error: 3 # only error
53 | excluded: # excluded via string array
54 | - id
55 | - URL
56 | - GlobalAPIKey
57 | reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit, html, emoji, sonarqube, markdown)
58 |
59 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ZVProgressHUDExample
4 | //
5 | // Created by zevwings on 12/02/2018.
6 | // Copyright © 2017-2019 zevwings. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // 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.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // 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.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // 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.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "filename" : "Icon-20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "idiom" : "iphone",
11 | "size" : "20x20",
12 | "filename" : "Icon-20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-29@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-29@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-40@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-40@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-60@2x.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-60@3x.png",
49 | "scale" : "3x"
50 | },
51 | {
52 | "idiom" : "ipad",
53 | "size" : "20x20",
54 | "filename" : "Icon-20.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "idiom" : "ipad",
59 | "size" : "20x20",
60 | "filename" : "Icon-20@2x.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "29x29",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-29.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-29@2x.png",
73 | "scale" : "2x"
74 | },
75 | {
76 | "size" : "40x40",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-40.png",
79 | "scale" : "1x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-40@2x.png",
85 | "scale" : "2x"
86 | },
87 | {
88 | "size" : "76x76",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-76.png",
91 | "scale" : "1x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-76@2x.png",
97 | "scale" : "2x"
98 | },
99 | {
100 | "size" : "83.5x83.5",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-83_5@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "idiom" : "ios-marketing",
107 | "size" : "1024x1024",
108 | "filename" : "ios-marketing.png",
109 | "scale" : "1x"
110 | }
111 | ],
112 | "info" : {
113 | "version" : 1,
114 | "author" : "xcode"
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/ZVProgressHUD.xcodeproj/xcshareddata/xcschemes/ZVProgressHUD.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
42 |
48 |
49 |
50 |
51 |
52 |
62 |
63 |
69 |
70 |
71 |
72 |
78 |
79 |
85 |
86 |
87 |
88 |
90 |
91 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/ZVProgressHUD/ZVProgressView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ZVProgressView.swift
3 | // ZVProgressHUD
4 | //
5 | // Created by zevwings on 2017/7/13.
6 | // Copyright © 2017-2019 zevwings. All rights reserved.
7 | //
8 |
9 | #if !os(macOS)
10 |
11 | import UIKit
12 |
13 | class ZVProgressView: UIView {
14 |
15 | var strokeWidth: CGFloat = 3.0 {
16 | didSet {
17 | foregroundLayer.lineWidth = strokeWidth
18 | backgroundLayer.lineWidth = strokeWidth
19 | }
20 | }
21 |
22 | var progressBackgroundColor: UIColor = UIColor.black.withAlphaComponent(0.5) {
23 | didSet {
24 | backgroundLayer.strokeColor = progressBackgroundColor.cgColor
25 | }
26 | }
27 |
28 | var progressForegroundColor: UIColor = .black {
29 | didSet {
30 | foregroundLayer.strokeColor = progressForegroundColor.cgColor
31 | }
32 | }
33 |
34 | var progressLabelColor: UIColor = .black {
35 | didSet {
36 | progressLabel.textColor = progressLabelColor
37 | }
38 | }
39 |
40 | var font: UIFont = .systemFont(ofSize: 12) {
41 | didSet {
42 | progressLabel.font = font
43 | }
44 | }
45 |
46 | var isProgressLabelHidden: Bool = false {
47 | didSet {
48 | progressLabel.isHidden = isProgressLabelHidden
49 | }
50 | }
51 |
52 | var progress: Float = 0.0 {
53 | didSet {
54 | foregroundLayer.strokeEnd = CGFloat(progress)
55 | setNeedsDisplay()
56 | }
57 | }
58 |
59 | private lazy var progressLabel : UILabel = {
60 | let label = UILabel()
61 | label.textColor = progressLabelColor
62 | label.font = font
63 | label.textAlignment = .center
64 | label.frame = bounds
65 | return label
66 | }()
67 |
68 | private lazy var foregroundLayer: CAShapeLayer = {
69 |
70 | let foregroundLayer = CAShapeLayer()
71 | foregroundLayer.lineCap = .round
72 | foregroundLayer.lineWidth = strokeWidth
73 | foregroundLayer.frame = bounds
74 | foregroundLayer.fillColor = UIColor.clear.cgColor
75 | foregroundLayer.strokeStart = 0.0
76 | foregroundLayer.strokeEnd = 0.0
77 |
78 | return foregroundLayer
79 | }()
80 |
81 | private lazy var backgroundLayer: CAShapeLayer = {
82 |
83 | let backgroundLayer = CAShapeLayer()
84 | backgroundLayer.lineCap = .round
85 | backgroundLayer.lineWidth = strokeWidth
86 | backgroundLayer.frame = bounds
87 | backgroundLayer.fillColor = UIColor.clear.cgColor
88 | backgroundLayer.strokeStart = 0.0
89 | backgroundLayer.strokeEnd = 1.0
90 |
91 | return backgroundLayer
92 | }()
93 |
94 | override init(frame: CGRect) {
95 | super.init(frame: frame)
96 |
97 | addSubview(progressLabel)
98 | layer.addSublayer(backgroundLayer)
99 | layer.addSublayer(foregroundLayer)
100 | layer.masksToBounds = true
101 | }
102 |
103 | required init?(coder aDecoder: NSCoder) {
104 | fatalError("init(coder:) has not been implemented")
105 | }
106 |
107 | override func layoutSubviews() {
108 | super.layoutSubviews()
109 |
110 | backgroundColor = .clear
111 |
112 | let rect = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
113 | foregroundLayer.frame = rect
114 | backgroundLayer.frame = rect
115 | progressLabel.frame = rect
116 | prepare()
117 | }
118 |
119 | private func prepare() {
120 |
121 | let arcCenter = CGPoint(x: self.frame.width / 2.0, y: self.frame.height / 2.0)
122 | let radius = (min(self.bounds.height, self.bounds.width) - self.strokeWidth) / 2.0
123 | let startAngle = -CGFloat.pi / 2
124 | let endAngle = CGFloat.pi * 3 / 2
125 |
126 | let bezierPath = UIBezierPath(
127 | arcCenter: arcCenter,
128 | radius: radius,
129 | startAngle: startAngle,
130 | endAngle: endAngle,
131 | clockwise: true
132 | )
133 |
134 | foregroundLayer.path = bezierPath.cgPath
135 | backgroundLayer.path = bezierPath.cgPath
136 |
137 | }
138 |
139 | func updateProgress(_ progress: Float) {
140 |
141 | CATransaction.begin()
142 | CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut))
143 | CATransaction.setAnimationDuration(0.15)
144 | foregroundLayer.strokeEnd = CGFloat(progress)
145 | progressLabel.text = "\(Int(progress * 100))%"
146 | CATransaction.commit()
147 | }
148 | }
149 |
150 | #endif
151 |
--------------------------------------------------------------------------------
/README_CN.md:
--------------------------------------------------------------------------------
1 | # ZVProgressHUD
2 | [](https://github.com/Carthage/Carthage)
3 | [](https://cocoapods.org)
4 | [](http://cocoadocs.org/docsets/Alamofire)
5 |
6 |
7 | `ZVProgressHUD` 是用纯`swift`开发,简单易用的提示工具。
8 |
9 | ## 版本支持
10 |
11 | - iOS 8.0+
12 | - Swift 4.0
13 |
14 | ## 安装
15 | ### Cocoapod
16 | [CocoaPods](https://cocoapods.org) is a dependency manager for Swift and Objective-C Cocoa projects.
17 |
18 | You can install Cocoapod with the following command
19 |
20 | ```
21 | $ sudo gem install cocoapods
22 | ```
23 | To integrate `ZVProgressHUD` into your project using CocoaPods, specify it into your `Podfile`
24 |
25 | ```
26 | source 'https://github.com/CocoaPods/Specs.git'
27 | platform :ios, '8.0'
28 |
29 | target 'TargetName' do
30 | use_frameworks!
31 | pod 'ZVProgressHUD', :git => 'https://github.com/zevwings/ZVProgressHUD.git'
32 | end
33 | ```
34 |
35 | Then,install your dependencies with [CocoaPods](https://cocoapods.org).
36 |
37 | ```
38 | $ pod install
39 | ```
40 | ### Carthage
41 |
42 | [Carthage](https://github.com/Carthage/Carthage) is intended to be the simplest way to add frameworks to your application.
43 |
44 | You can install Carthage with [Homebrew](https://brew.sh) using following command:
45 |
46 | ```
47 | $ brew update
48 | $ brew install carthage
49 | ```
50 |
51 | To integrate `ZVProgressHUD` into your project using Carthage, specify it into your `Cartfile`
52 |
53 | ```
54 | github "zevwings/ZVProgressHUD" ~> 0.0.1
55 | ```
56 |
57 | Then,build the framework with Carthage
58 | using `carthage update` and drag `ZVProgressHUD.framework` into your project.
59 |
60 | #### Note:
61 | The framework is under the Carthage/Build, and you should drag it into `Target` -> `Genral` -> `Embedded Binaries`
62 |
63 | ## 使用方法
64 | 当你在需要使用`ZVProgressHUD `使用`import ZVProgressHUD`导入即可。
65 |
66 | ### 任务提示
67 | 当你需要任务提示时,使用如下代码即可
68 |
69 | ```
70 | ZVProgressHUD.show()
71 | ```
72 |
73 | 通过如下代码自定义动画类型
74 |
75 | ```
76 | /// 动画类型,默认为 .flat
77 | public enum AnimationType {
78 | //使用自定义`ZVActivityIndicator`
79 | case flat
80 | //使用系统自带`UIActivityIndicator`
81 | case native
82 | }
83 |
84 | /// 你可以通过类属性修改动画类型
85 | ZVProgressHUD.animationType = .flat
86 | ```
87 |
88 | 当你需要改变`ZVProgressHUD`的显示父视图时,只需要在调用`show`方法时,指定父视图即可
89 |
90 | ```
91 | // 你也可以延迟视图显示,通过`delay`参数
92 | ZVProgressHUD.show(with: "正在加载", in: superview, delay: 0.0)
93 | ```
94 |
95 | ### 关闭提示
96 | 当你需要关闭任务提示时,使用如下代码即可
97 |
98 | ```
99 | ZVProgressHUD.dismiss()
100 | ```
101 |
102 | ### 展示一个确认信息
103 | 当需要展示任务确认信息时,调用如下方法
104 |
105 | ```
106 | ZVProgressHUD.showError(with: "保存失败")
107 | ZVProgressHUD.showSuccess(with: "保存成功")
108 | ZVProgressHUD.showWarning(with: "存储信息有误")
109 | ```
110 |
111 | ### 展示自定义图片
112 | 当你需要展示自定义图片时,可以使用如下方法
113 |
114 | ```
115 | let image = UIImage(named: "smile")
116 | ZVProgressHUD.showImage(image!)
117 | // 或者
118 | ZVProgressHUD.showImage(image!, title: "微笑每一天")
119 | ```
120 |
121 | ### 展示自定义动画
122 | 当你需要展示自定义动画时,可以使用如下方法
123 |
124 | ```
125 | var images = [UIImage]()
126 | for index in 1 ... 3 {
127 | let image = UIImage(named: "loading_0\(index)")
128 | images.append(image!)
129 | }
130 |
131 | ZVProgressHUD.showAnimation(images)
132 | ```
133 |
134 | ### 展示任务进度
135 |
136 | ```
137 | ZVProgressHUD.showProgress(0.0, title: "任务进度")
138 | ```
139 |
140 | ### 自定义属性
141 |
142 | ```
143 | // 设置显示前景色、背景色
144 | class var displayStyle: DisplayStyle
145 |
146 | // 设置遮罩类型
147 | class var maskType: MaskType
148 |
149 | // 基础视图圆角
150 | class var cornerRadius: CGFloat
151 |
152 | // 基础视图的偏移量
153 | class var offset: UIOffset
154 |
155 | // 字体
156 | class var font: UIFont
157 |
158 | // 当动画类型为`flat`时,改变圆环宽度
159 | class var strokeWith: CGFloat
160 |
161 | // 指示视图大小
162 | class var indicatorSize: CGSize
163 |
164 | // 设置动画类型,默认为`flat`
165 | class var animationType: IndicatorView.AnimationType
166 |
167 | ```
168 |
169 | ### 自定义边距
170 |
171 | ```
172 | // 设置整体内容边距
173 | class var contentInsets: UIEdgeInsets
174 |
175 | // 设置文本边距
176 | class var titleEdgeInsets: UIEdgeInsets
177 |
178 | // 设置指示器边距
179 | class var indicatorEdgeInsets: UIEdgeInsets
180 | ```
181 |
182 | ### 通知
183 |
184 | 你可以使用对应类型的通知,自定义相关操作。
185 |
186 | ```
187 | extension NSNotification.Name {
188 |
189 | // 接受到点击时间
190 | public static let ZVProgressHUDReceivedTouchUpInsideEvent: Notification.Name
191 |
192 | // 视图将要展示
193 | public static let ZVProgressHUDWillAppear: Notification.Name
194 |
195 | // 视图完成展示
196 | public static let ZVProgressHUDDidAppear: Notification.Name
197 |
198 | // 视图将要消失
199 | public static let ZVProgressHUDWillDisappear: Notification.Name
200 |
201 | // 视图完成消失
202 | public static let ZVProgressHUDDidDisappear: Notification.Name
203 | }
204 | ```
205 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ZVProgressHUD
2 | [](https://github.com/Carthage/Carthage)
3 | [](https://cocoapods.org)
4 | [](http://cocoadocs.org/docsets/Alamofire)
5 |
6 |
7 | ZVProgressHUD is a pure-swift and wieldy HUD.
8 |
9 | [中文文档](https://github.com/zevwings/ZVProgressHUD/blob/master/README_CN.md)
10 |
11 | ## Requirements
12 |
13 | - iOS 8.0+
14 | - Swift 5.0
15 |
16 | ## Appetize
17 | You can run this demo at [Appetize](https://appetize.io/embed/39txw9h5d7mrkckm6f9vp9mn2r?device=iphone5s&scale=100&autoplay=false&orientation=portrait&deviceColor=white)
18 |
19 |
20 | ## Installation
21 | ### Cocoapod
22 | [CocoaPods](https://cocoapods.org) is a dependency manager for Swift and Objective-C Cocoa projects.
23 |
24 | You can install Cocoapod with the following command
25 |
26 | ```
27 | $ sudo gem install cocoapods
28 | ```
29 | To integrate `ZVProgressHUD` into your project using CocoaPods, specify it into your `Podfile`
30 |
31 | ```
32 | source 'https://github.com/CocoaPods/Specs.git'
33 | platform :ios, '8.0'
34 |
35 | target 'TargetName' do
36 | use_frameworks!
37 | pod 'ZVProgressHUD', '~> 2.0.0'
38 | end
39 | ```
40 |
41 | Then,install your dependencies with [CocoaPods](https://cocoapods.org).
42 |
43 | ```
44 | $ pod install
45 | ```
46 | ### Carthage
47 |
48 | [Carthage](https://github.com/Carthage/Carthage) is intended to be the simplest way to add frameworks to your application.
49 |
50 | You can install Carthage with [Homebrew](https://brew.sh) using following command:
51 |
52 | ```
53 | $ brew update
54 | $ brew install carthage
55 | ```
56 |
57 | To integrate `ZVProgressHUD` into your project using Carthage, specify it into your `Cartfile`
58 |
59 | ```
60 | github "zevwings/ZVProgressHUD" ~> 0.0.1
61 | ```
62 |
63 | Then,build the framework with Carthage
64 | using `carthage update` and drag `ZVProgressHUD.framework` into your project.
65 |
66 | #### Note:
67 | The framework is under the Carthage/Build, and you should drag it into `Target` -> `Genral` -> `Embedded Binaries`
68 |
69 | ## Usage
70 | You can use `import ProgressHUD` when you needed to use `ZVProgressHUD`.
71 |
72 | ### Showing a HUD
73 | When you start a task, You can using following code:
74 |
75 | ```
76 | // class method
77 | ProgressHUD.shared.show()
78 | // or you can use instance method
79 | let hud = ProgressHUD()
80 | hud.show()
81 | ```
82 |
83 | you can custom animation type, use following code:
84 |
85 | ```
86 | /// the animation type, default is flat
87 | public enum AnimationType {
88 | case flat
89 | case native
90 | }
91 |
92 | /// this code will modify global animation type.
93 | ProgressHUD.shared.animationType = .flat
94 | ```
95 |
96 | when you want modify the superview of `ZVProgressHUD`, use the following code:
97 |
98 | ```
99 | // the HUD will show delay 0.0
100 | ZVProgressHUD.show(with: "Loading", in: superview, delay: 0.0)
101 | ```
102 |
103 | ### Dismiss a HUD
104 | you can use a simple code to close HUD.
105 |
106 | ```
107 | // class method
108 | ProgressHUD.shared.dismiss()
109 | // or you can use instance method
110 | hud.dismiss()
111 | ```
112 |
113 | ### Showing a confirm
114 | when you want show a comfirm infomation, use the following code:
115 |
116 | ```
117 | ProgressHUD.shared.showError(with: "error")
118 | ProgressHUD.shared.showSuccess(with: "success")
119 | ProgressHUD.shared.showWarning(with: "warning")
120 | ```
121 |
122 | ### Showing a custom image
123 | you also can show a custom image, use the following code:
124 |
125 | ```
126 | let image = UIImage(named: "smile")
127 | ProgressHUD.shared.showImage(image!)
128 | // or
129 | ProgressHUD.shared.showImage(image!, title: "smile everyday!")
130 | ```
131 |
132 | ### Showing a custom animation
133 | you can use the following code to custom a animation indicator.
134 |
135 | ```
136 | var images = [UIImage]()
137 | for index in 1 ... 3 {
138 | let image = UIImage(named: "loading_0\(index)")
139 | images.append(image!)
140 | }
141 |
142 | ProgressHUD.shared.showAnimation(images)
143 | ```
144 |
145 | ### Showing a progress
146 |
147 | ```
148 | ProgressHUD.shared.showProgress(0.0, title: "Progress")
149 | ```
150 |
151 | ### Custom logo
152 |
153 | ```
154 | // set logoSize of HUD, CGSize(30, 30)
155 | class var logoSize: CGSize
156 | // set logo image of HUD, default is nil
157 | class var logo: UIImage
158 | ```
159 |
160 | ### Custom properties
161 |
162 | ```
163 | // set displayStyle type of HUD, default is dark.
164 | class var displayStyle: DisplayStyle
165 |
166 | // set mask type of HUD
167 | class var maskType: MaskType
168 |
169 | // the cornerRadius of basic view
170 | class var cornerRadius: CGFloat
171 |
172 | // the offset of basic view
173 | class var offset: UIOffset
174 |
175 | // the font of title label
176 | class var font: UIFont
177 |
178 | // you can change the line width of indicator when animation type is `flat`
179 | class var strokeWith: CGFloat
180 |
181 | // the size of indicator
182 | class var indicatorSize: CGSize
183 |
184 | // the animation type, default is `flat`
185 | class var animationType: IndicatorView.AnimationType
186 |
187 | ```
188 |
189 | ### Custom Insets of content
190 |
191 | ```
192 | class var contentInsets: UIEdgeInsets
193 |
194 | class var titleEdgeInsets: UIEdgeInsets
195 |
196 | class var indicatorEdgeInsets: UIEdgeInsets
197 | ```
198 |
199 | ### Notifications
200 |
201 | you can add an observer to do something from hud's notifications.
202 |
203 | ```
204 | extension NSNotification.Name {
205 |
206 | // this hud did disappear
207 | public static let ProgressHUDReceivedTouchUpInsideEvent: Notification.Name
208 |
209 | // this hud will appear
210 | public static let ProgressHUDWillAppear: Notification.Name
211 |
212 | // this hud did appear
213 | public static let ProgressHUDDidAppear: Notification.Name
214 |
215 | // this hud will disappear
216 | public static let ProgressHUDWillDisappear: Notification.Name
217 |
218 | // this hud did disappear
219 | public static let ProgressHUDDidDisappear: Notification.Name
220 | }
221 | ```
222 |
223 | ## License
224 | `ZVProgressHUD` distributed under the terms and conditions of the [MIT License](https://github.com/zevwings/ZVProgressHUD/blob/master/LICENSE)
225 |
226 |
227 |
228 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | CFPropertyList (3.0.4)
5 | rexml
6 | addressable (2.8.0)
7 | public_suffix (>= 2.0.2, < 5.0)
8 | artifactory (3.0.15)
9 | atomos (0.1.3)
10 | aws-eventstream (1.2.0)
11 | aws-partitions (1.519.0)
12 | aws-sdk-core (3.121.3)
13 | aws-eventstream (~> 1, >= 1.0.2)
14 | aws-partitions (~> 1, >= 1.239.0)
15 | aws-sigv4 (~> 1.1)
16 | jmespath (~> 1.0)
17 | aws-sdk-kms (1.50.0)
18 | aws-sdk-core (~> 3, >= 3.121.2)
19 | aws-sigv4 (~> 1.1)
20 | aws-sdk-s3 (1.104.0)
21 | aws-sdk-core (~> 3, >= 3.121.2)
22 | aws-sdk-kms (~> 1)
23 | aws-sigv4 (~> 1.4)
24 | aws-sigv4 (1.4.0)
25 | aws-eventstream (~> 1, >= 1.0.2)
26 | babosa (1.0.4)
27 | claide (1.0.3)
28 | colored (1.2)
29 | colored2 (3.1.2)
30 | commander (4.6.0)
31 | highline (~> 2.0.0)
32 | declarative (0.0.20)
33 | digest-crc (0.6.4)
34 | rake (>= 12.0.0, < 14.0.0)
35 | domain_name (0.5.20190701)
36 | unf (>= 0.0.5, < 1.0.0)
37 | dotenv (2.7.6)
38 | emoji_regex (3.2.3)
39 | excon (0.87.0)
40 | faraday (1.8.0)
41 | faraday-em_http (~> 1.0)
42 | faraday-em_synchrony (~> 1.0)
43 | faraday-excon (~> 1.1)
44 | faraday-httpclient (~> 1.0.1)
45 | faraday-net_http (~> 1.0)
46 | faraday-net_http_persistent (~> 1.1)
47 | faraday-patron (~> 1.0)
48 | faraday-rack (~> 1.0)
49 | multipart-post (>= 1.2, < 3)
50 | ruby2_keywords (>= 0.0.4)
51 | faraday-cookie_jar (0.0.7)
52 | faraday (>= 0.8.0)
53 | http-cookie (~> 1.0.0)
54 | faraday-em_http (1.0.0)
55 | faraday-em_synchrony (1.0.0)
56 | faraday-excon (1.1.0)
57 | faraday-httpclient (1.0.1)
58 | faraday-net_http (1.0.1)
59 | faraday-net_http_persistent (1.2.0)
60 | faraday-patron (1.0.0)
61 | faraday-rack (1.0.0)
62 | faraday_middleware (1.2.0)
63 | faraday (~> 1.0)
64 | fastimage (2.2.5)
65 | fastlane (2.197.0)
66 | CFPropertyList (>= 2.3, < 4.0.0)
67 | addressable (>= 2.8, < 3.0.0)
68 | artifactory (~> 3.0)
69 | aws-sdk-s3 (~> 1.0)
70 | babosa (>= 1.0.3, < 2.0.0)
71 | bundler (>= 1.12.0, < 3.0.0)
72 | colored
73 | commander (~> 4.6)
74 | dotenv (>= 2.1.1, < 3.0.0)
75 | emoji_regex (>= 0.1, < 4.0)
76 | excon (>= 0.71.0, < 1.0.0)
77 | faraday (~> 1.0)
78 | faraday-cookie_jar (~> 0.0.6)
79 | faraday_middleware (~> 1.0)
80 | fastimage (>= 2.1.0, < 3.0.0)
81 | gh_inspector (>= 1.1.2, < 2.0.0)
82 | google-apis-androidpublisher_v3 (~> 0.3)
83 | google-apis-playcustomapp_v1 (~> 0.1)
84 | google-cloud-storage (~> 1.31)
85 | highline (~> 2.0)
86 | json (< 3.0.0)
87 | jwt (>= 2.1.0, < 3)
88 | mini_magick (>= 4.9.4, < 5.0.0)
89 | multipart-post (~> 2.0.0)
90 | naturally (~> 2.2)
91 | optparse (~> 0.1.1)
92 | plist (>= 3.1.0, < 4.0.0)
93 | rubyzip (>= 2.0.0, < 3.0.0)
94 | security (= 0.1.3)
95 | simctl (~> 1.6.3)
96 | terminal-notifier (>= 2.0.0, < 3.0.0)
97 | terminal-table (>= 1.4.5, < 2.0.0)
98 | tty-screen (>= 0.6.3, < 1.0.0)
99 | tty-spinner (>= 0.8.0, < 1.0.0)
100 | word_wrap (~> 1.0.0)
101 | xcodeproj (>= 1.13.0, < 2.0.0)
102 | xcpretty (~> 0.3.0)
103 | xcpretty-travis-formatter (>= 0.0.3)
104 | gh_inspector (1.1.3)
105 | google-apis-androidpublisher_v3 (0.12.0)
106 | google-apis-core (>= 0.4, < 2.a)
107 | google-apis-core (0.4.1)
108 | addressable (~> 2.5, >= 2.5.1)
109 | googleauth (>= 0.16.2, < 2.a)
110 | httpclient (>= 2.8.1, < 3.a)
111 | mini_mime (~> 1.0)
112 | representable (~> 3.0)
113 | retriable (>= 2.0, < 4.a)
114 | rexml
115 | webrick
116 | google-apis-iamcredentials_v1 (0.7.0)
117 | google-apis-core (>= 0.4, < 2.a)
118 | google-apis-playcustomapp_v1 (0.5.0)
119 | google-apis-core (>= 0.4, < 2.a)
120 | google-apis-storage_v1 (0.8.0)
121 | google-apis-core (>= 0.4, < 2.a)
122 | google-cloud-core (1.6.0)
123 | google-cloud-env (~> 1.0)
124 | google-cloud-errors (~> 1.0)
125 | google-cloud-env (1.5.0)
126 | faraday (>= 0.17.3, < 2.0)
127 | google-cloud-errors (1.2.0)
128 | google-cloud-storage (1.34.1)
129 | addressable (~> 2.5)
130 | digest-crc (~> 0.4)
131 | google-apis-iamcredentials_v1 (~> 0.1)
132 | google-apis-storage_v1 (~> 0.1)
133 | google-cloud-core (~> 1.6)
134 | googleauth (>= 0.16.2, < 2.a)
135 | mini_mime (~> 1.0)
136 | googleauth (1.1.0)
137 | faraday (>= 0.17.3, < 2.0)
138 | jwt (>= 1.4, < 3.0)
139 | memoist (~> 0.16)
140 | multi_json (~> 1.11)
141 | os (>= 0.9, < 2.0)
142 | signet (>= 0.16, < 2.a)
143 | highline (2.0.3)
144 | http-cookie (1.0.4)
145 | domain_name (~> 0.5)
146 | httpclient (2.8.3)
147 | jmespath (1.4.0)
148 | json (2.6.1)
149 | jwt (2.3.0)
150 | memoist (0.16.2)
151 | mini_magick (4.11.0)
152 | mini_mime (1.1.2)
153 | multi_json (1.15.0)
154 | multipart-post (2.0.0)
155 | nanaimo (0.3.0)
156 | naturally (2.2.1)
157 | optparse (0.1.1)
158 | os (1.1.1)
159 | plist (3.6.0)
160 | public_suffix (4.0.6)
161 | rake (13.0.6)
162 | representable (3.1.1)
163 | declarative (< 0.1.0)
164 | trailblazer-option (>= 0.1.1, < 0.2.0)
165 | uber (< 0.2.0)
166 | retriable (3.1.2)
167 | rexml (3.2.5)
168 | rouge (2.0.7)
169 | ruby2_keywords (0.0.5)
170 | rubyzip (2.3.2)
171 | security (0.1.3)
172 | signet (0.16.0)
173 | addressable (~> 2.8)
174 | faraday (>= 0.17.3, < 2.0)
175 | jwt (>= 1.5, < 3.0)
176 | multi_json (~> 1.10)
177 | simctl (1.6.8)
178 | CFPropertyList
179 | naturally
180 | terminal-notifier (2.0.0)
181 | terminal-table (1.8.0)
182 | unicode-display_width (~> 1.1, >= 1.1.1)
183 | trailblazer-option (0.1.1)
184 | tty-cursor (0.7.1)
185 | tty-screen (0.8.1)
186 | tty-spinner (0.9.3)
187 | tty-cursor (~> 0.7)
188 | uber (0.1.0)
189 | unf (0.1.4)
190 | unf_ext
191 | unf_ext (0.0.8)
192 | unicode-display_width (1.8.0)
193 | webrick (1.7.0)
194 | word_wrap (1.0.0)
195 | xcodeproj (1.21.0)
196 | CFPropertyList (>= 2.3.3, < 4.0)
197 | atomos (~> 0.1.3)
198 | claide (>= 1.0.2, < 2.0)
199 | colored2 (~> 3.1)
200 | nanaimo (~> 0.3.0)
201 | rexml (~> 3.2.4)
202 | xcpretty (0.3.0)
203 | rouge (~> 2.0.7)
204 | xcpretty-travis-formatter (1.0.1)
205 | xcpretty (~> 0.2, >= 0.0.7)
206 |
207 | PLATFORMS
208 | ruby
209 |
210 | DEPENDENCIES
211 | fastlane
212 |
213 | BUNDLED WITH
214 | 2.2.15
215 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/ZVDownloadingView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ZVDownloadingView.swift
3 | // ZVProgressHUDExample
4 | //
5 | // Created by zevwings on 2020/12/22.
6 | // Copyright © 2020 zevwings. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ZVProgressHUD
11 |
12 | class ZVDownloadingView: UIView {
13 |
14 | private lazy var containerView: UIView = {
15 | let view = UIView(frame: CGRect(x: 0, y: 28, width: 210, height: 104))
16 | view.backgroundColor = .white
17 | view.layer.cornerRadius = 10
18 | return view
19 | }()
20 |
21 | private lazy var closeButton: UIButton = {
22 | let button = UIButton()
23 | button.setImage(UIImage(named: "close"), for: .normal)
24 | button.contentMode = .topRight
25 | button.addTarget(self, action: #selector(closeButonClicked(_:)), for: .touchUpInside)
26 | button.imageEdgeInsets = UIEdgeInsets(top: 12, left: 0, bottom: 0, right: 12)
27 | return button
28 | }()
29 |
30 | private lazy var progressView: ZVProgressView = {
31 | let view = ZVProgressView(frame: CGRect(x: 76, y: 42, width: 58, height: 58))
32 | view.strokeColor = UIColor(red: 0.90, green: 0, blue: 0.27, alpha: 1)
33 | view.progressLabelColor = UIColor(red: 0.20, green: 0.20, blue: 0.20, alpha: 1)
34 | view.font = .systemFont(ofSize: 14.0, weight: .semibold)
35 | return view
36 | }()
37 |
38 | private lazy var describeLabel: UILabel = {
39 | let label = UILabel(frame: CGRect(x: 20, y: 44, width: 170, height: 20))
40 | label.textColor = UIColor(red: 0.20, green: 0.20, blue: 0.20, alpha: 1)
41 | label.font = .systemFont(ofSize: 14.0, weight: .regular)
42 | label.textAlignment = .center
43 | return label
44 | }()
45 |
46 | init() {
47 | super.init(frame: CGRect(x: 0, y: 0, width: 210, height: 160))
48 |
49 | addSubview(containerView)
50 |
51 | containerView.frame = CGRect(x: 0, y: 28, width: 210, height: 104)
52 | containerView.addSubview(closeButton)
53 | closeButton.frame = CGRect(x: 166, y: 0, width: 44, height: 44)
54 | containerView.addSubview(describeLabel)
55 | describeLabel.frame = CGRect(x: 42, y: 44, width: 126.0, height: 20)
56 | }
57 |
58 | required init?(coder: NSCoder) {
59 | fatalError("init(coder:) has not been implemented")
60 | }
61 |
62 | func start() {
63 | containerView.frame = CGRect(x: 0, y: 0, width: 210, height: 160)
64 | containerView.addSubview(progressView)
65 | progressView.frame = CGRect(x: 76, y: 42, width: 58, height: 58)
66 | describeLabel.frame = CGRect(x: 63, y: 111, width: 84, height: 20)
67 | }
68 |
69 | func update(_ progress: Float) {
70 | describeLabel.text = "Progress \("\(Int(progress * 100))%")"
71 | progressView.updateProgress(progress)
72 | }
73 |
74 | func show(with title: String) {
75 | describeLabel.text = title
76 | }
77 |
78 | func dismiss() {
79 | progressView.removeFromSuperview()
80 | containerView.frame = CGRect(x: 0, y: 28, width: 210, height: 104)
81 | describeLabel.frame = CGRect(x: 42, y: 44, width: 126.0, height: 20)
82 | }
83 |
84 | @objc private func closeButonClicked(_ sender: Any) {
85 | dismiss()
86 | ZVProgressHUD.dismiss()
87 |
88 | }
89 | }
90 |
91 | private class ZVProgressView: UIView {
92 |
93 | var strokeWidth: CGFloat = 3.0 {
94 | didSet {
95 | foregroundLayer.lineWidth = strokeWidth
96 | backgroundLayer.lineWidth = strokeWidth
97 | }
98 | }
99 |
100 | var strokeColor: UIColor = .black {
101 | didSet {
102 | foregroundLayer.strokeColor = strokeColor.cgColor
103 | backgroundLayer.strokeColor = strokeColor.withAlphaComponent(0.5).cgColor
104 | }
105 | }
106 |
107 | var progressLabelColor: UIColor = .black {
108 | didSet {
109 | progressLabel.textColor = progressLabelColor
110 | }
111 | }
112 |
113 | var font: UIFont = .systemFont(ofSize: 12) {
114 | didSet {
115 | progressLabel.font = font
116 | }
117 | }
118 |
119 | var isProgressLabelHidden: Bool = false {
120 | didSet {
121 | progressLabel.isHidden = isProgressLabelHidden
122 | }
123 | }
124 |
125 | var progress: Float = 0.0 {
126 | didSet {
127 | foregroundLayer.strokeEnd = CGFloat(progress)
128 | setNeedsDisplay()
129 | }
130 | }
131 |
132 | private lazy var progressLabel : UILabel = {
133 | let label = UILabel()
134 | label.textColor = strokeColor
135 | label.font = font
136 | label.textAlignment = .center
137 | label.frame = bounds
138 | return label
139 | }()
140 |
141 | private lazy var foregroundLayer: CAShapeLayer = {
142 |
143 | let foregroundLayer = CAShapeLayer()
144 | foregroundLayer.lineCap = .round
145 | foregroundLayer.lineWidth = strokeWidth
146 | foregroundLayer.frame = bounds
147 | foregroundLayer.fillColor = UIColor.clear.cgColor
148 | foregroundLayer.strokeStart = 0.0
149 | foregroundLayer.strokeEnd = 0.0
150 |
151 | return foregroundLayer
152 | }()
153 |
154 | private lazy var backgroundLayer: CAShapeLayer = {
155 |
156 | let backgroundLayer = CAShapeLayer()
157 | backgroundLayer.lineCap = .round
158 | backgroundLayer.lineWidth = strokeWidth
159 | backgroundLayer.frame = bounds
160 | backgroundLayer.fillColor = UIColor.clear.cgColor
161 | backgroundLayer.strokeStart = 0.0
162 | backgroundLayer.strokeEnd = 1.0
163 |
164 | return backgroundLayer
165 | }()
166 |
167 | override init(frame: CGRect) {
168 | super.init(frame: frame)
169 |
170 | addSubview(progressLabel)
171 | layer.addSublayer(backgroundLayer)
172 | layer.addSublayer(foregroundLayer)
173 | layer.masksToBounds = true
174 | }
175 |
176 | required init?(coder aDecoder: NSCoder) {
177 | fatalError("init(coder:) has not been implemented")
178 | }
179 |
180 | override func layoutSubviews() {
181 | super.layoutSubviews()
182 |
183 | backgroundColor = .clear
184 |
185 | let rect = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
186 | foregroundLayer.frame = rect
187 | backgroundLayer.frame = rect
188 | progressLabel.frame = rect
189 | prepare()
190 | }
191 |
192 | private func prepare() {
193 |
194 | let arcCenter = CGPoint(x: self.frame.width / 2.0, y: self.frame.height / 2.0)
195 | let radius = (min(self.bounds.height, self.bounds.width) - self.strokeWidth * 2) / 2.0
196 | let startAngle = -CGFloat.pi / 2
197 | let endAngle = CGFloat.pi * 3 / 2
198 |
199 | let bezierPath = UIBezierPath(
200 | arcCenter: arcCenter,
201 | radius: radius,
202 | startAngle: startAngle,
203 | endAngle: endAngle,
204 | clockwise: true
205 | )
206 |
207 | foregroundLayer.path = bezierPath.cgPath
208 | backgroundLayer.path = bezierPath.cgPath
209 |
210 | }
211 |
212 | func updateProgress(_ progress: Float) {
213 |
214 | CATransaction.begin()
215 | CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut))
216 | CATransaction.setAnimationDuration(0.15)
217 | foregroundLayer.strokeEnd = CGFloat(progress)
218 | progressLabel.text = "\(Int(progress * 100))%"
219 | CATransaction.commit()
220 | }
221 | }
222 |
223 |
--------------------------------------------------------------------------------
/ZVProgressHUD/ZVIndicatorView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ZVStateView.swift
3 | // ZVProgressHUD
4 | //
5 | // Created by zevwings on 2017/7/13.
6 | // Copyright © 2017-2019 zevwings. All rights reserved.
7 | //
8 |
9 | #if !os(macOS)
10 |
11 | import UIKit
12 | import ZVActivityIndicatorView
13 |
14 | public class ZVIndicatorView: UIView {
15 |
16 | public enum AnimationType {
17 | case flat
18 | case native
19 | }
20 |
21 | public enum IndicatorType {
22 | case none
23 | case error, success, warning
24 | case indicator(style: AnimationType)
25 | case progress(value: Float)
26 | case image(value: UIImage, dismissAtomically: Bool)
27 | case animation(value: [UIImage], duration: TimeInterval)
28 | }
29 |
30 | var strokeWidth: CGFloat = 3.0 {
31 | didSet {
32 | flatActivityIndicatorView?.strokeWidth = strokeWidth
33 | progressIndicatorView?.strokeWidth = strokeWidth
34 | }
35 | }
36 |
37 | var progressForegroundColor: UIColor = .black {
38 | didSet {
39 | progressIndicatorView?.progressForegroundColor = progressForegroundColor
40 | }
41 | }
42 |
43 | var progressBackgroundColor: UIColor = .black {
44 | didSet {
45 | progressIndicatorView?.progressBackgroundColor = progressBackgroundColor
46 | }
47 | }
48 |
49 | var progressLabelFont : UIFont = .systemFont(ofSize: 12) {
50 | didSet {
51 | progressIndicatorView?.font = progressLabelFont
52 | }
53 | }
54 |
55 | var progressLabelColor: UIColor = .black {
56 | didSet {
57 | progressIndicatorView?.progressLabelColor = progressLabelColor
58 | }
59 | }
60 |
61 | var isProgressLabelHidden: Bool = false {
62 | didSet {
63 | progressIndicatorView?.isProgressLabelHidden = isProgressLabelHidden
64 | }
65 | }
66 |
67 | var indcatorType: IndicatorType = .none {
68 | didSet {
69 | switch indcatorType {
70 | case .indicator(let style):
71 | switch (style) {
72 | case .native:
73 | configNativeActivityIndicatorView()
74 | case .flat:
75 | configFlatActivityIndicatorView()
76 | }
77 | case .progress(let value):
78 | configProgressIndicatorView(with: value)
79 | case .error, .success, .warning:
80 | configImageIndicatorView(indcatorType.resource)
81 | case .image(let value, _):
82 | configImageIndicatorView(value)
83 | case .animation(let value, let duration):
84 | configImageIndicatorView(value, animationDuration: duration)
85 | default:
86 | break
87 | }
88 | isHidden = indcatorType.shouldHidden
89 | }
90 | }
91 |
92 | private var imageIndicaotorView: UIImageView?
93 | private var nativeActivityIndicatorView: UIActivityIndicatorView?
94 | private var flatActivityIndicatorView: ZVActivityIndicatorView?
95 | private var progressIndicatorView: ZVProgressView?
96 |
97 | convenience init() {
98 | self.init(frame: .zero)
99 | }
100 |
101 | override init(frame: CGRect) {
102 | super.init(frame: frame)
103 | backgroundColor = .clear
104 | isUserInteractionEnabled = false
105 | }
106 |
107 | required public init?(coder aDecoder: NSCoder) {
108 | fatalError("init(coder:) has not been implemented")
109 | }
110 | }
111 |
112 | // MARK: - Override
113 |
114 | extension ZVIndicatorView {
115 |
116 | override public var tintColor: UIColor! {
117 | didSet {
118 | imageIndicaotorView?.tintColor = tintColor
119 | nativeActivityIndicatorView?.color = tintColor
120 | flatActivityIndicatorView?.tintColor = tintColor
121 | }
122 | }
123 |
124 | public override func layoutSubviews() {
125 | super.layoutSubviews()
126 |
127 | let subViewFrame = CGRect(origin: .zero, size: frame.size)
128 |
129 | imageIndicaotorView?.frame = subViewFrame
130 | flatActivityIndicatorView?.frame = subViewFrame
131 | nativeActivityIndicatorView?.frame = subViewFrame
132 | progressIndicatorView?.frame = subViewFrame
133 | }
134 | }
135 |
136 | // MARK: - Private Method
137 |
138 | private extension ZVIndicatorView {
139 |
140 | func configImageIndicatorView(_ value: Any, animationDuration: TimeInterval = 0.0) {
141 |
142 | flatActivityIndicatorView?.stopAnimating()
143 | flatActivityIndicatorView?.removeFromSuperview()
144 |
145 | nativeActivityIndicatorView?.stopAnimating()
146 | nativeActivityIndicatorView?.removeFromSuperview()
147 |
148 | imageIndicaotorView?.stopAnimating()
149 | imageIndicaotorView?.animationImages = nil
150 | imageIndicaotorView?.image = nil
151 |
152 | progressIndicatorView?.removeFromSuperview()
153 |
154 | if imageIndicaotorView == nil {
155 | imageIndicaotorView = UIImageView(frame: .zero)
156 | imageIndicaotorView?.isUserInteractionEnabled = false
157 | }
158 |
159 | if imageIndicaotorView?.superview == nil {
160 | addSubview(imageIndicaotorView!)
161 | }
162 |
163 | if let resource = value as? String {
164 | #if ZVProgressHUD_SPM
165 | let bundlePath = Bundle.module.path(forResource: "Resource", ofType: "bundle")
166 | #else
167 | let bundlePath = Bundle(for: ZVProgressHUD.self).path(forResource: "Resource", ofType: "bundle")
168 | #endif
169 | guard let path = bundlePath,
170 | let bundle = Bundle(path: path),
171 | let fileName = bundle.path(forResource: resource, ofType: "png")
172 | else { return }
173 |
174 | let image = UIImage(contentsOfFile: fileName)?.withRenderingMode(.alwaysTemplate)
175 | imageIndicaotorView?.tintColor = tintColor
176 | imageIndicaotorView?.image = image
177 | } else if let image = value as? UIImage {
178 |
179 | imageIndicaotorView?.image = image
180 | } else if let animationImages = value as? [UIImage] {
181 |
182 | if animationImages.isEmpty {
183 | imageIndicaotorView?.image = nil
184 | } else if animationImages.count == 1 {
185 | imageIndicaotorView?.image = animationImages[0]
186 | } else {
187 | imageIndicaotorView?.animationImages = animationImages
188 | imageIndicaotorView?.animationDuration = animationDuration
189 | imageIndicaotorView?.startAnimating()
190 | }
191 |
192 | imageIndicaotorView?.animationImages = animationImages
193 | imageIndicaotorView?.startAnimating()
194 | }
195 | }
196 |
197 | func configProgressIndicatorView(with value: Float) {
198 |
199 | flatActivityIndicatorView?.stopAnimating()
200 | flatActivityIndicatorView?.removeFromSuperview()
201 |
202 | imageIndicaotorView?.animationImages = nil
203 | imageIndicaotorView?.image = nil
204 | imageIndicaotorView?.stopAnimating()
205 | imageIndicaotorView?.removeFromSuperview()
206 |
207 | nativeActivityIndicatorView?.stopAnimating()
208 | nativeActivityIndicatorView?.removeFromSuperview()
209 |
210 | if progressIndicatorView == nil {
211 | progressIndicatorView = ZVProgressView(frame: .zero)
212 | progressIndicatorView?.progressBackgroundColor = progressBackgroundColor
213 | progressIndicatorView?.progressForegroundColor = progressForegroundColor
214 | progressIndicatorView?.progressLabelColor = progressLabelColor
215 | progressIndicatorView?.font = progressLabelFont
216 | }
217 |
218 | if progressIndicatorView?.superview == nil {
219 | addSubview(progressIndicatorView!)
220 | }
221 |
222 | progressIndicatorView?.updateProgress(value)
223 | }
224 |
225 | private func configNativeActivityIndicatorView() {
226 |
227 | flatActivityIndicatorView?.stopAnimating()
228 | flatActivityIndicatorView?.removeFromSuperview()
229 |
230 | imageIndicaotorView?.animationImages = nil
231 | imageIndicaotorView?.image = nil
232 | imageIndicaotorView?.stopAnimating()
233 | imageIndicaotorView?.removeFromSuperview()
234 |
235 | progressIndicatorView?.removeFromSuperview()
236 |
237 | if nativeActivityIndicatorView == nil {
238 | nativeActivityIndicatorView = UIActivityIndicatorView(style: .whiteLarge)
239 | nativeActivityIndicatorView?.color = tintColor
240 | nativeActivityIndicatorView?.hidesWhenStopped = true
241 | }
242 |
243 | if nativeActivityIndicatorView?.superview == nil {
244 | addSubview(nativeActivityIndicatorView!)
245 | }
246 |
247 | nativeActivityIndicatorView?.startAnimating()
248 | }
249 |
250 | private func configFlatActivityIndicatorView() {
251 |
252 | nativeActivityIndicatorView?.stopAnimating()
253 | nativeActivityIndicatorView?.removeFromSuperview()
254 |
255 | imageIndicaotorView?.image = nil
256 | imageIndicaotorView?.animationImages = nil
257 | imageIndicaotorView?.stopAnimating()
258 | imageIndicaotorView?.removeFromSuperview()
259 |
260 | progressIndicatorView?.removeFromSuperview()
261 |
262 | if flatActivityIndicatorView == nil {
263 | flatActivityIndicatorView = ZVActivityIndicatorView()
264 | flatActivityIndicatorView?.tintColor = tintColor
265 | flatActivityIndicatorView?.hidesWhenStopped = true
266 | flatActivityIndicatorView?.strokeWidth = strokeWidth
267 | }
268 |
269 | if flatActivityIndicatorView?.superview == nil {
270 | addSubview(flatActivityIndicatorView!)
271 | }
272 |
273 | flatActivityIndicatorView?.startAnimating()
274 | }
275 | }
276 |
277 | #endif
278 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Example
4 | //
5 | // Created by zevwings on 2017/7/11.
6 | // Copyright © 2017-2019 zevwings. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ZVProgressHUD
11 |
12 | class ViewController: UIViewController {
13 |
14 | var rows = [
15 | ("show", #selector(showIndicator)),
16 | ("showWithLabel", #selector(showWithLabel)),
17 | ("showProgress", #selector(showProgress)),
18 | ("showProgressWithLabel", #selector(showProgressWithLabel)),
19 | ("showError", #selector(showError)),
20 | ("showSuccess", #selector(showSuccess)),
21 | ("showWarning", #selector(showWarning)),
22 | ("showCustomImage", #selector(showCustomImage)),
23 | ("showCustomImageWithLabel", #selector(showCustomImageWithLabel)),
24 | ("showAnimation", #selector(showAnimation)),
25 | ("showCustomView", #selector(showCustomView)),
26 | ("showLabel", #selector(showLabel)),
27 | ("dismiss", #selector(dismissHUD))
28 | ]
29 |
30 | @IBOutlet weak var tableView: UITableView!
31 |
32 | @IBOutlet weak var delayShowTimeLabel: UIView!
33 | @IBOutlet weak var delayDismissTimeLabel: UIView!
34 |
35 | var showDelay: TimeInterval = 0
36 | var dismissDelay: TimeInterval = 0
37 |
38 | var progress: Float = 0.0
39 | var timer: Timer?
40 |
41 | var countDown: Int = 0
42 | private lazy var loadingView: ZVDownloadingView = {
43 | let loadingView = ZVDownloadingView()
44 | return loadingView
45 | }()
46 |
47 | @IBOutlet weak var indicatorSizeLabel: UILabel!
48 | @IBOutlet weak var logoSizeLabel: UILabel!
49 |
50 | override func viewDidLoad() {
51 | super.viewDidLoad()
52 |
53 | ZVProgressHUD.setMaskType(.black)
54 | ZVProgressHUD.setDisplayStyle(.dark)
55 | ZVProgressHUD.setLogoSize(CGSize(width: 30.0, height: 30.0))
56 |
57 | // ZVProgressHUD.setProgressLabelColor(.green)
58 | // ZVProgressHUD.setTitleLabelColor(.cyan)
59 |
60 | let logo = UIImage(named: "logo_crown")?.withRenderingMode(.alwaysTemplate)
61 | ZVProgressHUD.setLogo(logo)
62 |
63 | NotificationCenter.default.addObserver(self,
64 | selector: #selector(ZVProgressHUDTouchEvent(_:)),
65 | name: .ZVProgressHUDReceivedTouchUpInsideEvent,
66 | object: nil)
67 | }
68 |
69 | override func didReceiveMemoryWarning() {
70 | super.didReceiveMemoryWarning()
71 |
72 | }
73 | }
74 |
75 | // MARK: - ZVProgressHUD Notification
76 |
77 | extension ViewController {
78 |
79 | @objc func ZVProgressHUDTouchEvent(_ notification: Notification) {
80 | timer?.invalidate()
81 | timer = nil
82 | self.dismissHUD()
83 | }
84 | }
85 |
86 | // MARK: - ZVProgressHUD
87 |
88 | extension ViewController {
89 |
90 | @objc func showIndicator() {
91 |
92 | ZVProgressHUD.show(delay: showDelay)
93 | }
94 |
95 | @objc func showWithLabel() {
96 |
97 | ZVProgressHUD.show(with: "loading", delay: showDelay)
98 | }
99 |
100 | @objc func showError() {
101 |
102 | ZVProgressHUD.showError(with: "error", delay: showDelay)
103 | }
104 |
105 | @objc func showSuccess() {
106 |
107 | ZVProgressHUD.showSuccess(with: "success", delay: showDelay)
108 | }
109 |
110 | @objc func showWarning() {
111 |
112 | ZVProgressHUD.showWarning(with: "warning", delay: showDelay)
113 | }
114 |
115 | @objc func showCustomImage() {
116 |
117 | let image = UIImage(named: "smile")
118 | ZVProgressHUD.showImage(image!, delay: showDelay)
119 | }
120 |
121 | @objc func showCustomImageWithLabel() {
122 |
123 | let image = UIImage(named: "smile")
124 | ZVProgressHUD.showImage(image!, title: "smile everyday", delay: showDelay)
125 | }
126 |
127 | @objc func showProgress() {
128 |
129 | self.progress = 0
130 | if self.timer != nil {
131 | timer?.invalidate()
132 | timer = nil
133 | }
134 |
135 | ZVProgressHUD.showProgress(0.0)
136 |
137 | self.timer = Timer.scheduledTimer(
138 | timeInterval: 0.25,
139 | target: self,
140 | selector: #selector(ViewController.progressTimerAction(_:)),
141 | userInfo: nil,
142 | repeats: true
143 | )
144 | }
145 |
146 | @objc func showProgressWithLabel() {
147 |
148 | self.progress = 0
149 | if self.timer != nil {
150 | timer?.invalidate()
151 | timer = nil
152 | }
153 |
154 | ZVProgressHUD.showProgress(0.0, title: "Progress", delay: showDelay)
155 |
156 | self.timer = Timer.scheduledTimer(
157 | timeInterval: 0.25,
158 | target: self,
159 | selector: #selector(ViewController.progressTimerAction(_:)),
160 | userInfo: ["title": "Progress"],
161 | repeats: true
162 | )
163 | }
164 |
165 | @objc func showAnimation() {
166 |
167 | var images = [UIImage]()
168 | for index in 1 ... 3 {
169 | let image = UIImage(named: "loading_0\(index)")
170 | images.append(image!)
171 | }
172 |
173 | ZVProgressHUD.showAnimation(images, delay: showDelay)
174 |
175 | }
176 |
177 | @objc func showCustomView() {
178 |
179 | var configuration = ZVProgressHUD.Configuration()
180 | configuration.animationType = .native
181 | configuration.displayStyle = .custom((.clear, .clear))
182 | configuration.maskType = .black
183 |
184 | loadingView.show(with: "Request Data ....")
185 | ZVProgressHUD.showCustomView(loadingView, with: configuration)
186 |
187 | countDown = 0
188 | progress = 0
189 |
190 | self.timer = Timer.scheduledTimer(
191 | timeInterval: 0.25,
192 | target: self,
193 | selector: #selector(ViewController.customProgressTimerAction(_:)),
194 | userInfo: ["title": "Progress"],
195 | repeats: true
196 | )
197 |
198 | }
199 |
200 | @objc func showLabel() {
201 |
202 | ZVProgressHUD.showText("pure text", in: self.view, delay: showDelay)
203 |
204 | }
205 |
206 | @objc func dismissHUD() {
207 |
208 | ZVProgressHUD.dismiss(delay: dismissDelay) {
209 | print("dimiss")
210 | }
211 | }
212 |
213 |
214 | @IBAction func setDisplayStyle(_ sender: UISegmentedControl) {
215 |
216 | switch sender.selectedSegmentIndex {
217 | case 0:
218 | ZVProgressHUD.setDisplayStyle(.dark)
219 | case 1:
220 | ZVProgressHUD.setDisplayStyle(.light)
221 | case 2:
222 | let backgroundColor = UIColor(red: 86.0 / 255.0, green: 75.0 / 255.0, blue: 151.0 / 255.0, alpha: 1.0)
223 | let foregroundColor = UIColor(red: 239.0 / 255.0, green: 83.0 / 255.0, blue: 64.0 / 255.0, alpha: 1.0)
224 | ZVProgressHUD.setDisplayStyle(.custom((backgroundColor, foregroundColor)))
225 | default:
226 | break
227 | }
228 | }
229 |
230 | @IBAction func setMaskType(_ sender: UISegmentedControl) {
231 |
232 | switch sender.selectedSegmentIndex {
233 | case 0:
234 | ZVProgressHUD.setMaskType(.clear)
235 | case 1:
236 | ZVProgressHUD.setMaskType(.none)
237 | case 2:
238 | ZVProgressHUD.setMaskType(.black)
239 | case 3:
240 | let color = UIColor(red: 215.0 / 255.0, green: 22.0 / 255.0, blue: 59.0 / 255.0, alpha: 0.35)
241 | ZVProgressHUD.setMaskType(.custom(color: color))
242 | default:
243 | break
244 | }
245 | }
246 |
247 | @IBAction func setAnimationType(_ sender: UISegmentedControl) {
248 | switch sender.selectedSegmentIndex {
249 | case 0:
250 | ZVProgressHUD.setAnimationType(.flat)
251 | case 1:
252 | ZVProgressHUD.setAnimationType(.native)
253 | default:
254 | break
255 | }
256 | }
257 |
258 | @IBAction func setIndicatorViewSize(_ sender: UISlider) {
259 | let size = CGFloat(sender.value)
260 | ZVProgressHUD.setIndicatorSize(CGSize(width: size, height: size))
261 | indicatorSizeLabel.text = "Indicator Size (\(String(format: "%.2f", size)))"
262 |
263 | }
264 |
265 | @IBAction func setLogoViewSize(_ sender: UISlider) {
266 | let size = CGFloat(sender.value)
267 |
268 | ZVProgressHUD.setLogoSize(CGSize(width: size, height: size))
269 | logoSizeLabel.text = "Logo Size (\(String(format: "%.2f", size)))"
270 | }
271 |
272 | @IBAction func setDelayShow(_ sender: UISlider) {
273 | self.showDelay = TimeInterval(sender.value)
274 | }
275 |
276 | @IBAction func setDelayDismiss(_ sender: UISlider) {
277 | self.dismissDelay = TimeInterval(sender.value)
278 | }
279 |
280 | @objc func progressTimerAction(_ sender: Timer?) {
281 |
282 | let userInfo = sender?.userInfo as? [String: String]
283 | let title = userInfo?["title"] ?? ""
284 | progress += 0.05
285 | ZVProgressHUD.showProgress(progress, title: title)
286 |
287 | print("timer action : \(progress)")
288 |
289 | if progress > 1.0 {
290 | timer?.invalidate()
291 | timer = nil
292 | }
293 | }
294 |
295 | @objc func customProgressTimerAction(_ sender: Timer?) {
296 |
297 | let userInfo = sender?.userInfo as? [String: String]
298 | let title = userInfo?["title"] ?? ""
299 | // progress += 0.05
300 |
301 | countDown += 1
302 |
303 | guard countDown >= 10 else { return }
304 |
305 | if countDown == 10 {
306 | loadingView.start()
307 | }
308 |
309 | progress += 0.05
310 |
311 | loadingView.update(progress)
312 |
313 | print("timer action : \(progress)")
314 |
315 | if progress > 1.0 {
316 | timer?.invalidate()
317 | timer = nil
318 |
319 | loadingView.dismiss()
320 | ZVProgressHUD.dismiss()
321 | }
322 | }
323 | }
324 |
325 | extension ViewController: UITableViewDataSource {
326 |
327 | public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
328 | return self.rows.count
329 | }
330 |
331 | public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
332 |
333 | let cell = tableView.dequeueReusableCell(withIdentifier: "ReuseIdentifier")
334 | cell?.textLabel?.text = self.rows[indexPath.row].0
335 | cell?.textLabel?.font = UIFont.systemFont(ofSize: 14.0)
336 | cell?.textLabel?.textColor = UIColor(white: 0.2, alpha: 1.0)
337 | return cell!
338 | }
339 | }
340 |
341 | extension ViewController: UITableViewDelegate {
342 |
343 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
344 | let selector = self.rows[indexPath.row].1
345 | self.perform(selector)
346 | }
347 | }
348 |
349 | extension ViewController: UITextFieldDelegate {
350 |
351 | func textFieldShouldReturn(_ textField: UITextField) -> Bool {
352 |
353 | textField.resignFirstResponder()
354 |
355 | return true
356 | }
357 | }
358 |
359 | extension ViewController {
360 |
361 | override var preferredStatusBarStyle: UIStatusBarStyle {
362 | return .lightContent
363 | }
364 | }
365 |
366 | extension UINavigationController {
367 |
368 | open override var childForStatusBarStyle: UIViewController? {
369 | return self.topViewController
370 | }
371 | }
372 |
373 |
--------------------------------------------------------------------------------
/ZVProgressHUD/ZVProgressHUDExtensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProgressHUD+Operations.swift
3 | // ZVProgressHUD
4 | //
5 | // Created by zevwings on 2019/9/29.
6 | // Copyright © 2019 zevwings. All rights reserved.
7 | //
8 |
9 | #if !os(macOS)
10 |
11 | import UIKit
12 |
13 | // MARK: - Configuration
14 |
15 | public extension ZVProgressHUD {
16 |
17 | class func setDisplayStyle(_ displayStyle: DisplayStyle) {
18 | shared.configuration.displayStyle = displayStyle
19 | }
20 |
21 | class func setMaskType(_ maskType: MaskType) {
22 | shared.configuration.maskType = maskType
23 | }
24 |
25 | class func setCornerRadius(_ cornerRadius: CGFloat) {
26 | shared.configuration.cornerRadius = cornerRadius
27 | }
28 |
29 | class func setOffset(_ offset: UIOffset) {
30 | shared.configuration.offset = offset
31 | }
32 |
33 | class func setTitleLabelFont(_ font: UIFont) {
34 | shared.configuration.titleLabelFont = font
35 | }
36 |
37 | class func setTitleLabelColor(_ color: UIColor?) {
38 | shared.configuration.titleLabelColor = color
39 | }
40 |
41 | class func setProgressLabelFont(_ font: UIFont) {
42 | shared.configuration.progressLabelFont = font
43 | }
44 |
45 | class func setProgressLabelColor(_ color: UIColor?) {
46 | shared.configuration.progressLabelColor = color
47 | }
48 |
49 | class func setProgressLabelHidden(_ isProgressLabelHidden: Bool) {
50 | shared.configuration.isProgressLabelHidden = isProgressLabelHidden
51 | }
52 |
53 | class func setStrokeWidth(_ strokeWidth: CGFloat) {
54 | shared.configuration.strokeWidth = strokeWidth
55 | }
56 |
57 | class func setIndicatorSize(_ size: CGSize) {
58 | shared.configuration.indicatorSize = size
59 | }
60 |
61 | class func setAnimationType(_ animationType: ZVIndicatorView.AnimationType) {
62 | shared.configuration.animationType = animationType
63 | }
64 |
65 | class func setContentInsets(_ indets: UIEdgeInsets) {
66 | shared.configuration.contentInsets = indets
67 | }
68 |
69 | class func setTitleEdgeInsets(_ indets: UIEdgeInsets) {
70 | shared.configuration.titleEdgeInsets = indets
71 | }
72 |
73 | class func setIndicatorEdgeInsets(_ indets: UIEdgeInsets) {
74 | shared.configuration.indicatorEdgeInsets = indets
75 | }
76 |
77 | class func setLogo(_ logo: UIImage?) {
78 | shared.configuration.logo = logo
79 | }
80 |
81 | class func setLogoSize(_ size: CGSize) {
82 | shared.configuration.logoSize = size
83 | }
84 | }
85 |
86 | // MARK: - Props
87 |
88 | public extension ZVProgressHUD {
89 |
90 | class func setMaxSupportedWindowLevel(_ windowLevel: UIWindow.Level) {
91 | shared.maxSupportedWindowLevel = windowLevel
92 | }
93 |
94 | class func setFadeInAnimationTimeInterval(_ timeInterval: TimeInterval) {
95 | shared.fadeInAnimationTimeInterval = timeInterval
96 | }
97 |
98 | class func setFadeOutAnimationTImeInterval(_ timeInterval: TimeInterval) {
99 | shared.fadeOutAnimationTImeInterval = timeInterval
100 | }
101 |
102 | class func setMinimumDismissTimeInterval(_ timeInterval: TimeInterval) {
103 | shared.minimumDismissTimeInterval = timeInterval
104 | }
105 |
106 | class func setMaximumDismissTimeInterval(_ timeInterval: TimeInterval) {
107 | shared.maximumDismissTimeInterval = timeInterval
108 | }
109 |
110 | class func setMaximumContentSize(_ size: CGSize) {
111 | shared.maximumContentSize = size
112 | }
113 |
114 | }
115 |
116 | // MARK: - Handle
117 |
118 | public extension ZVProgressHUD {
119 |
120 | /// show a toast
121 | ///
122 | /// - Parameters:
123 | /// - text: toast content
124 | /// - superview: super view, if superview is nil, show on main window
125 | /// - delayTimeInterval: the view will show delay the `delayTimeInterval`
126 | class func showText(
127 | _ text: String,
128 | in superview: UIView? = nil,
129 | delay delayTimeInterval: TimeInterval = 0.0,
130 | with configuration: Configuration? = nil
131 | ) {
132 | shared.internalShow(
133 | displayType: .text(value: text),
134 | in: superview,
135 | delay: delayTimeInterval,
136 | with: configuration
137 | )
138 | }
139 |
140 | /// show a success message
141 | ///
142 | /// - Parameters:
143 | /// - title: the success message remind users what you want
144 | /// - superview: super view, if superview is nil, show on main window
145 | /// - delayTimeInterval: the view will show delay the `delayTimeInterval`
146 | class func showSuccess(
147 | with title: String = "",
148 | in superview: UIView? = nil,
149 | delay delayTimeInterval: TimeInterval = 0.0,
150 | with configuration: Configuration? = nil
151 | ) {
152 | shared.internalShow(
153 | displayType: .indicator(title: title, type: .success),
154 | in: superview,
155 | delay: delayTimeInterval,
156 | with: configuration
157 | )
158 | }
159 |
160 | /// show a error message
161 | ///
162 | /// - Parameters:
163 | /// - title: the error message remind users what you want
164 | /// - superview: super view, if superview is nil, show on main window
165 | /// - delayTimeInterval: the view will show delay the `delayTimeInterval`
166 | class func showError(
167 | with title: String = "",
168 | in superview: UIView? = nil,
169 | delay delayTimeInterval: TimeInterval = 0.0,
170 | with configuration: Configuration? = nil
171 | ) {
172 | shared.internalShow(
173 | displayType: .indicator(title: title, type: .error),
174 | in: superview,
175 | delay: delayTimeInterval,
176 | with: configuration
177 | )
178 | }
179 |
180 | /// show a warning message
181 | ///
182 | /// - Parameters:
183 | /// - title: the warning message remind users what you want
184 | /// - superview: super view, if superview is nil, show on main window
185 | /// - delayTimeInterval: the view will show delay the `delayTimeInterval`
186 | class func showWarning(
187 | with title: String = "",
188 | in superview: UIView? = nil,
189 | delay delayTimeInterval: TimeInterval = 0.0,
190 | with configuration: Configuration? = nil
191 | ) {
192 | shared.internalShow(
193 | displayType: .indicator(title: title, type: .warning),
194 | in: superview,
195 | delay: delayTimeInterval,
196 | with: configuration
197 | )
198 | }
199 |
200 | /// show a waiting alert
201 | ///
202 | /// - Parameters:
203 | /// - title: the message remind users what you want
204 | /// - superview: super view, if superview is nil, show on main window
205 | /// - delayTimeInterval: the view will show delay the `delayTimeInterval`
206 | class func show(
207 | with title: String = "",
208 | in superview: UIView? = nil,
209 | delay delayTimeInterval: TimeInterval = 0.0,
210 | with configuration: Configuration? = nil
211 | ) {
212 | let animationType: ZVIndicatorView.AnimationType
213 | if let configuration = configuration {
214 | animationType = configuration.animationType
215 | } else {
216 | animationType = shared.configuration.animationType
217 | }
218 | shared.internalShow(
219 | displayType: .indicator(title: title, type: .indicator(style: animationType)),
220 | in: superview,
221 | delay: delayTimeInterval,
222 | with: configuration
223 | )
224 | }
225 |
226 | /// show the progress of some task
227 | ///
228 | /// - Parameters:
229 | /// - progress: the progress of your task
230 | /// - title: the message remind users what you want
231 | /// - superview: super view, if superview is nil, show on main window
232 | /// - delayTimeInterval: the view will show delay the `delayTimeInterval`
233 | class func showProgress(
234 | _ progress: Float,
235 | title: String = "",
236 | in superview: UIView? = nil,
237 | delay delayTimeInterval: TimeInterval = 0.0,
238 | with configuration: Configuration? = nil
239 | ) {
240 | shared.internalShow(
241 | displayType: .indicator(title: title, type: .progress(value: progress)),
242 | in: superview,
243 | delay: delayTimeInterval,
244 | with: configuration
245 | )
246 | }
247 |
248 | /// show a custom image
249 | ///
250 | /// - Parameters:
251 | /// - image: your image
252 | /// - title: the message remind users what you want
253 | /// - superview: super view, if superview is nil, show on main window
254 | /// - dismissAtomically: if `true` the `HUD` will dissmiss atomically
255 | /// - delayTimeInterval: the view will show delay the `delayTimeInterval`
256 | class func showImage(
257 | _ image: UIImage,
258 | title: String = "",
259 | in superview: UIView? = nil,
260 | dismissAtomically: Bool = true,
261 | delay delayTimeInterval: TimeInterval = 0.0,
262 | with configuration: Configuration? = nil
263 | ) {
264 | shared.internalShow(
265 | displayType: .indicator(title: title, type: .image(value: image, dismissAtomically: dismissAtomically)),
266 | in: superview,
267 | delay: delayTimeInterval,
268 | with: configuration
269 | )
270 | }
271 |
272 | /// show the animation waiting alert
273 | ///
274 | /// - Parameters:
275 | /// - images: animation image array
276 | /// - duration: animation duration @see UIImage
277 | /// - title: the message remind users what you want
278 | /// - superview: super view, if superview is nil, show on main window
279 | /// - delayTimeInterval: the view will show delay the `delayTimeInterval`
280 | class func showAnimation(
281 | _ images: [UIImage],
282 | duration: TimeInterval = 0.0,
283 | title: String = "",
284 | in superview: UIView? = nil,
285 | delay delayTimeInterval: TimeInterval = 0.0,
286 | with configuration: Configuration? = nil
287 | ) {
288 | if images.isEmpty { return }
289 |
290 | let animationDuration: TimeInterval
291 | if duration == 0 {
292 | animationDuration = Double(images.count) * 0.1
293 | } else {
294 | animationDuration = duration
295 | }
296 |
297 | shared.internalShow(
298 | displayType: .indicator(title: title, type: .animation(value: images, duration: animationDuration)),
299 | in: superview,
300 | delay: delayTimeInterval,
301 | with: configuration
302 | )
303 | }
304 |
305 | /// show the animation waiting alert
306 | ///
307 | /// - Parameters:
308 | /// - images: animation image array
309 | /// - duration: animation duration @see UIImage
310 | /// - title: the message remind users what you want
311 | /// - superview: super view, if superview is nil, show on main window
312 | /// - delayTimeInterval: the view will show delay the `delayTimeInterval`
313 | class func showCustomView(
314 | _ view: UIView,
315 | in superview: UIView? = nil,
316 | delay delayTimeInterval: TimeInterval = 0.0,
317 | with configuration: Configuration? = nil
318 | ) {
319 | shared.internalShow(
320 | displayType: .customeView(view: view),
321 | in: superview,
322 | delay: delayTimeInterval,
323 | with: configuration
324 | )
325 | }
326 |
327 | /// show custom display type @see ZVProgressHUD.DisplayType
328 | ///
329 | /// - Parameters:
330 | /// - displayType: ZVProgressHUD.DisplayType
331 | /// - superview: super view, if superview is nil, show on main window
332 | /// - delayTimeInterval: the view will show delay the `delayTimeInterval`
333 | class func show(
334 | with displayType: DisplayType,
335 | in superview: UIView? = nil,
336 | delay delayTimeInterval: TimeInterval = 0.0,
337 | with configuration: Configuration? = nil
338 | ) {
339 | shared.internalShow(
340 | displayType: displayType,
341 | in: superview,
342 | delay: delayTimeInterval,
343 | with: configuration
344 | )
345 | }
346 |
347 | /// dismiss the hud
348 | ///
349 | /// - Parameters:
350 | /// - delay: the view will dissmiss delay the `delayTimeInterval`
351 | /// - completion: dismiss completion handler
352 | class func dismiss(
353 | delay: TimeInterval = 0.0,
354 | completion: CompletionHandler? = nil
355 | ) {
356 | shared.internalDismiss(with: delay, completion: completion)
357 | }
358 | }
359 |
360 | #endif
361 |
--------------------------------------------------------------------------------
/ZVProgressHUDExample/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
99 |
108 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
149 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
--------------------------------------------------------------------------------
/ZVProgressHUD.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 52;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4D4445FC20A17185006FCEEC /* ZVProgressHUD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D5BDA8D1F146CAC00E68CB6 /* ZVProgressHUD.framework */; };
11 | 4D4445FD20A17185006FCEEC /* ZVProgressHUD.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4D5BDA8D1F146CAC00E68CB6 /* ZVProgressHUD.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
12 | 4D5797D724CEACF900C0E6E8 /* ZVProgressHUDExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D5797D424CEACF900C0E6E8 /* ZVProgressHUDExtensions.swift */; };
13 | 4D5797D924CEACF900C0E6E8 /* ZVProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D5797D624CEACF900C0E6E8 /* ZVProgressView.swift */; };
14 | 4D5BDA9E1F146CAC00E68CB6 /* ZVProgressHUD.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D5BDA901F146CAC00E68CB6 /* ZVProgressHUD.h */; settings = {ATTRIBUTES = (Public, ); }; };
15 | 4D5F00102591AEC400E68D49 /* ZVProgressHUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D5F000E2591AEC400E68D49 /* ZVProgressHUD.swift */; };
16 | 4D5F00152591AF6500E68D49 /* ZVDownloadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D5F00142591AF6500E68D49 /* ZVDownloadingView.swift */; };
17 | 4D60771620327D4F00474944 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D60771520327D4F00474944 /* ViewController.swift */; };
18 | 4D8046F91F14CBFD0069F9F2 /* Resource.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 4D8046F81F14CBFD0069F9F2 /* Resource.bundle */; };
19 | 4DB03ACA2531B329003F8300 /* ZVActivityIndicatorView in Frameworks */ = {isa = PBXBuildFile; productRef = 4DB03AC92531B329003F8300 /* ZVActivityIndicatorView */; };
20 | 4DC8B6982306A61900170426 /* ZVIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DC8B6962306A61900170426 /* ZVIndicatorView.swift */; };
21 | 4DFF5B4C20318D7A0098BA7D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DFF5B4B20318D7A0098BA7D /* AppDelegate.swift */; };
22 | 4DFF5B5120318D7A0098BA7D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4DFF5B4F20318D7A0098BA7D /* Main.storyboard */; };
23 | 4DFF5B5320318D7A0098BA7D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4DFF5B5220318D7A0098BA7D /* Assets.xcassets */; };
24 | 4DFF5B5620318D7A0098BA7D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4DFF5B5420318D7A0098BA7D /* LaunchScreen.storyboard */; };
25 | /* End PBXBuildFile section */
26 |
27 | /* Begin PBXContainerItemProxy section */
28 | 4D4445FE20A17185006FCEEC /* PBXContainerItemProxy */ = {
29 | isa = PBXContainerItemProxy;
30 | containerPortal = 4D5BDA841F146CAC00E68CB6 /* Project object */;
31 | proxyType = 1;
32 | remoteGlobalIDString = 4D5BDA8C1F146CAC00E68CB6;
33 | remoteInfo = ZVProgressHUD;
34 | };
35 | /* End PBXContainerItemProxy section */
36 |
37 | /* Begin PBXCopyFilesBuildPhase section */
38 | 4D44460020A17185006FCEEC /* Embed Frameworks */ = {
39 | isa = PBXCopyFilesBuildPhase;
40 | buildActionMask = 2147483647;
41 | dstPath = "";
42 | dstSubfolderSpec = 10;
43 | files = (
44 | 4D4445FD20A17185006FCEEC /* ZVProgressHUD.framework in Embed Frameworks */,
45 | );
46 | name = "Embed Frameworks";
47 | runOnlyForDeploymentPostprocessing = 0;
48 | };
49 | /* End PBXCopyFilesBuildPhase section */
50 |
51 | /* Begin PBXFileReference section */
52 | 4D5797D424CEACF900C0E6E8 /* ZVProgressHUDExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZVProgressHUDExtensions.swift; sourceTree = ""; };
53 | 4D5797D624CEACF900C0E6E8 /* ZVProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZVProgressView.swift; sourceTree = ""; };
54 | 4D5BDA8D1F146CAC00E68CB6 /* ZVProgressHUD.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ZVProgressHUD.framework; sourceTree = BUILT_PRODUCTS_DIR; };
55 | 4D5BDA901F146CAC00E68CB6 /* ZVProgressHUD.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZVProgressHUD.h; sourceTree = ""; };
56 | 4D5BDA911F146CAC00E68CB6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
57 | 4D5F000E2591AEC400E68D49 /* ZVProgressHUD.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZVProgressHUD.swift; sourceTree = ""; };
58 | 4D5F00142591AF6500E68D49 /* ZVDownloadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZVDownloadingView.swift; sourceTree = ""; };
59 | 4D60771520327D4F00474944 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
60 | 4D8046F81F14CBFD0069F9F2 /* Resource.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Resource.bundle; sourceTree = ""; };
61 | 4DC8B6962306A61900170426 /* ZVIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZVIndicatorView.swift; sourceTree = ""; };
62 | 4DCDC08C207F4E0100CB78B8 /* ZVActivityIndicatorView.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ZVActivityIndicatorView.framework; path = Carthage/Build/iOS/ZVActivityIndicatorView.framework; sourceTree = ""; };
63 | 4DDCB2D7272792560089BB96 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; };
64 | 4DDCB2D8272792560089BB96 /* Cartfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Cartfile; sourceTree = ""; };
65 | 4DDCB2D9272792560089BB96 /* ZVProgressHUD.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ZVProgressHUD.podspec; sourceTree = ""; };
66 | 4DFF5B4920318D7A0098BA7D /* ZVProgressHUDExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ZVProgressHUDExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
67 | 4DFF5B4B20318D7A0098BA7D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
68 | 4DFF5B5020318D7A0098BA7D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
69 | 4DFF5B5220318D7A0098BA7D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
70 | 4DFF5B5520318D7A0098BA7D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
71 | 4DFF5B5720318D7A0098BA7D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
72 | /* End PBXFileReference section */
73 |
74 | /* Begin PBXFrameworksBuildPhase section */
75 | 4D5BDA891F146CAC00E68CB6 /* Frameworks */ = {
76 | isa = PBXFrameworksBuildPhase;
77 | buildActionMask = 2147483647;
78 | files = (
79 | 4DB03ACA2531B329003F8300 /* ZVActivityIndicatorView in Frameworks */,
80 | );
81 | runOnlyForDeploymentPostprocessing = 0;
82 | };
83 | 4DFF5B4620318D7A0098BA7D /* Frameworks */ = {
84 | isa = PBXFrameworksBuildPhase;
85 | buildActionMask = 2147483647;
86 | files = (
87 | 4D4445FC20A17185006FCEEC /* ZVProgressHUD.framework in Frameworks */,
88 | );
89 | runOnlyForDeploymentPostprocessing = 0;
90 | };
91 | /* End PBXFrameworksBuildPhase section */
92 |
93 | /* Begin PBXGroup section */
94 | 4D5BDA831F146CAC00E68CB6 = {
95 | isa = PBXGroup;
96 | children = (
97 | 4DDCB2DE2727926D0089BB96 /* Deployment */,
98 | 4DDCB2DD272792600089BB96 /* Dependencies */,
99 | 4D5BDA8F1F146CAC00E68CB6 /* ZVProgressHUD */,
100 | 4DFF5B4A20318D7A0098BA7D /* ZVProgressHUDExample */,
101 | 4D5BDA8E1F146CAC00E68CB6 /* Products */,
102 | 4DFF5B6620318F0B0098BA7D /* Frameworks */,
103 | );
104 | sourceTree = "";
105 | };
106 | 4D5BDA8E1F146CAC00E68CB6 /* Products */ = {
107 | isa = PBXGroup;
108 | children = (
109 | 4D5BDA8D1F146CAC00E68CB6 /* ZVProgressHUD.framework */,
110 | 4DFF5B4920318D7A0098BA7D /* ZVProgressHUDExample.app */,
111 | );
112 | name = Products;
113 | sourceTree = "";
114 | };
115 | 4D5BDA8F1F146CAC00E68CB6 /* ZVProgressHUD */ = {
116 | isa = PBXGroup;
117 | children = (
118 | 4D5BDA901F146CAC00E68CB6 /* ZVProgressHUD.h */,
119 | 4D5797D624CEACF900C0E6E8 /* ZVProgressView.swift */,
120 | 4DC8B6962306A61900170426 /* ZVIndicatorView.swift */,
121 | 4D5F000E2591AEC400E68D49 /* ZVProgressHUD.swift */,
122 | 4D5797D424CEACF900C0E6E8 /* ZVProgressHUDExtensions.swift */,
123 | 4D5BDA911F146CAC00E68CB6 /* Info.plist */,
124 | 4D8046F81F14CBFD0069F9F2 /* Resource.bundle */,
125 | );
126 | path = ZVProgressHUD;
127 | sourceTree = "";
128 | };
129 | 4DDCB2DD272792600089BB96 /* Dependencies */ = {
130 | isa = PBXGroup;
131 | children = (
132 | 4DDCB2D8272792560089BB96 /* Cartfile */,
133 | );
134 | name = Dependencies;
135 | sourceTree = "";
136 | };
137 | 4DDCB2DE2727926D0089BB96 /* Deployment */ = {
138 | isa = PBXGroup;
139 | children = (
140 | 4DDCB2D7272792560089BB96 /* Package.swift */,
141 | 4DDCB2D9272792560089BB96 /* ZVProgressHUD.podspec */,
142 | );
143 | name = Deployment;
144 | sourceTree = "";
145 | };
146 | 4DFF5B4A20318D7A0098BA7D /* ZVProgressHUDExample */ = {
147 | isa = PBXGroup;
148 | children = (
149 | 4DFF5B4B20318D7A0098BA7D /* AppDelegate.swift */,
150 | 4D60771520327D4F00474944 /* ViewController.swift */,
151 | 4DFF5B4F20318D7A0098BA7D /* Main.storyboard */,
152 | 4DFF5B5220318D7A0098BA7D /* Assets.xcassets */,
153 | 4DFF5B5420318D7A0098BA7D /* LaunchScreen.storyboard */,
154 | 4DFF5B5720318D7A0098BA7D /* Info.plist */,
155 | 4D5F00142591AF6500E68D49 /* ZVDownloadingView.swift */,
156 | );
157 | path = ZVProgressHUDExample;
158 | sourceTree = "";
159 | };
160 | 4DFF5B6620318F0B0098BA7D /* Frameworks */ = {
161 | isa = PBXGroup;
162 | children = (
163 | 4DCDC08C207F4E0100CB78B8 /* ZVActivityIndicatorView.framework */,
164 | );
165 | name = Frameworks;
166 | sourceTree = "";
167 | };
168 | /* End PBXGroup section */
169 |
170 | /* Begin PBXHeadersBuildPhase section */
171 | 4D5BDA8A1F146CAC00E68CB6 /* Headers */ = {
172 | isa = PBXHeadersBuildPhase;
173 | buildActionMask = 2147483647;
174 | files = (
175 | 4D5BDA9E1F146CAC00E68CB6 /* ZVProgressHUD.h in Headers */,
176 | );
177 | runOnlyForDeploymentPostprocessing = 0;
178 | };
179 | /* End PBXHeadersBuildPhase section */
180 |
181 | /* Begin PBXNativeTarget section */
182 | 4D5BDA8C1F146CAC00E68CB6 /* ZVProgressHUD */ = {
183 | isa = PBXNativeTarget;
184 | buildConfigurationList = 4D5BDAA11F146CAC00E68CB6 /* Build configuration list for PBXNativeTarget "ZVProgressHUD" */;
185 | buildPhases = (
186 | 4D5BDA881F146CAC00E68CB6 /* Sources */,
187 | 4D5BDA891F146CAC00E68CB6 /* Frameworks */,
188 | 4D5BDA8A1F146CAC00E68CB6 /* Headers */,
189 | 4D5BDA8B1F146CAC00E68CB6 /* Resources */,
190 | 4DAE474B2340B1B3008773D2 /* SwiftLint */,
191 | );
192 | buildRules = (
193 | );
194 | dependencies = (
195 | );
196 | name = ZVProgressHUD;
197 | packageProductDependencies = (
198 | 4DB03AC92531B329003F8300 /* ZVActivityIndicatorView */,
199 | );
200 | productName = ZVProgressHUD;
201 | productReference = 4D5BDA8D1F146CAC00E68CB6 /* ZVProgressHUD.framework */;
202 | productType = "com.apple.product-type.framework";
203 | };
204 | 4DFF5B4820318D7A0098BA7D /* ZVProgressHUDExample */ = {
205 | isa = PBXNativeTarget;
206 | buildConfigurationList = 4DFF5B5820318D7A0098BA7D /* Build configuration list for PBXNativeTarget "ZVProgressHUDExample" */;
207 | buildPhases = (
208 | 4DFF5B4520318D7A0098BA7D /* Sources */,
209 | 4DFF5B4620318D7A0098BA7D /* Frameworks */,
210 | 4DFF5B4720318D7A0098BA7D /* Resources */,
211 | 4D44460020A17185006FCEEC /* Embed Frameworks */,
212 | );
213 | buildRules = (
214 | );
215 | dependencies = (
216 | 4D4445FF20A17185006FCEEC /* PBXTargetDependency */,
217 | );
218 | name = ZVProgressHUDExample;
219 | packageProductDependencies = (
220 | );
221 | productName = ZVProgressHUDExample;
222 | productReference = 4DFF5B4920318D7A0098BA7D /* ZVProgressHUDExample.app */;
223 | productType = "com.apple.product-type.application";
224 | };
225 | /* End PBXNativeTarget section */
226 |
227 | /* Begin PBXProject section */
228 | 4D5BDA841F146CAC00E68CB6 /* Project object */ = {
229 | isa = PBXProject;
230 | attributes = {
231 | LastSwiftUpdateCheck = 0920;
232 | LastUpgradeCheck = 1300;
233 | ORGANIZATIONNAME = zevwings;
234 | TargetAttributes = {
235 | 4D5BDA8C1F146CAC00E68CB6 = {
236 | CreatedOnToolsVersion = 8.3.3;
237 | LastSwiftMigration = 1020;
238 | ProvisioningStyle = Automatic;
239 | };
240 | 4DFF5B4820318D7A0098BA7D = {
241 | CreatedOnToolsVersion = 9.2;
242 | LastSwiftMigration = 1030;
243 | ProvisioningStyle = Automatic;
244 | };
245 | };
246 | };
247 | buildConfigurationList = 4D5BDA871F146CAC00E68CB6 /* Build configuration list for PBXProject "ZVProgressHUD" */;
248 | compatibilityVersion = "Xcode 8.0";
249 | developmentRegion = en;
250 | hasScannedForEncodings = 0;
251 | knownRegions = (
252 | en,
253 | Base,
254 | );
255 | mainGroup = 4D5BDA831F146CAC00E68CB6;
256 | packageReferences = (
257 | 4DB03AC82531B329003F8300 /* XCRemoteSwiftPackageReference "ZVActivityIndicatorView" */,
258 | );
259 | productRefGroup = 4D5BDA8E1F146CAC00E68CB6 /* Products */;
260 | projectDirPath = "";
261 | projectRoot = "";
262 | targets = (
263 | 4D5BDA8C1F146CAC00E68CB6 /* ZVProgressHUD */,
264 | 4DFF5B4820318D7A0098BA7D /* ZVProgressHUDExample */,
265 | );
266 | };
267 | /* End PBXProject section */
268 |
269 | /* Begin PBXResourcesBuildPhase section */
270 | 4D5BDA8B1F146CAC00E68CB6 /* Resources */ = {
271 | isa = PBXResourcesBuildPhase;
272 | buildActionMask = 2147483647;
273 | files = (
274 | 4D8046F91F14CBFD0069F9F2 /* Resource.bundle in Resources */,
275 | );
276 | runOnlyForDeploymentPostprocessing = 0;
277 | };
278 | 4DFF5B4720318D7A0098BA7D /* Resources */ = {
279 | isa = PBXResourcesBuildPhase;
280 | buildActionMask = 2147483647;
281 | files = (
282 | 4DFF5B5620318D7A0098BA7D /* LaunchScreen.storyboard in Resources */,
283 | 4DFF5B5320318D7A0098BA7D /* Assets.xcassets in Resources */,
284 | 4DFF5B5120318D7A0098BA7D /* Main.storyboard in Resources */,
285 | );
286 | runOnlyForDeploymentPostprocessing = 0;
287 | };
288 | /* End PBXResourcesBuildPhase section */
289 |
290 | /* Begin PBXShellScriptBuildPhase section */
291 | 4DAE474B2340B1B3008773D2 /* SwiftLint */ = {
292 | isa = PBXShellScriptBuildPhase;
293 | buildActionMask = 2147483647;
294 | files = (
295 | );
296 | inputFileListPaths = (
297 | );
298 | inputPaths = (
299 | );
300 | name = SwiftLint;
301 | outputFileListPaths = (
302 | );
303 | outputPaths = (
304 | );
305 | runOnlyForDeploymentPostprocessing = 0;
306 | shellPath = /bin/sh;
307 | shellScript = "if [ \"${CONFIGURATION}\" = \"Debug\" ]; then\n if which swiftlint > /dev/null; then\n swiftlint\n else\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint to lint!\"\n fi\nfi\n";
308 | };
309 | /* End PBXShellScriptBuildPhase section */
310 |
311 | /* Begin PBXSourcesBuildPhase section */
312 | 4D5BDA881F146CAC00E68CB6 /* Sources */ = {
313 | isa = PBXSourcesBuildPhase;
314 | buildActionMask = 2147483647;
315 | files = (
316 | 4DC8B6982306A61900170426 /* ZVIndicatorView.swift in Sources */,
317 | 4D5797D724CEACF900C0E6E8 /* ZVProgressHUDExtensions.swift in Sources */,
318 | 4D5797D924CEACF900C0E6E8 /* ZVProgressView.swift in Sources */,
319 | 4D5F00102591AEC400E68D49 /* ZVProgressHUD.swift in Sources */,
320 | );
321 | runOnlyForDeploymentPostprocessing = 0;
322 | };
323 | 4DFF5B4520318D7A0098BA7D /* Sources */ = {
324 | isa = PBXSourcesBuildPhase;
325 | buildActionMask = 2147483647;
326 | files = (
327 | 4D60771620327D4F00474944 /* ViewController.swift in Sources */,
328 | 4D5F00152591AF6500E68D49 /* ZVDownloadingView.swift in Sources */,
329 | 4DFF5B4C20318D7A0098BA7D /* AppDelegate.swift in Sources */,
330 | );
331 | runOnlyForDeploymentPostprocessing = 0;
332 | };
333 | /* End PBXSourcesBuildPhase section */
334 |
335 | /* Begin PBXTargetDependency section */
336 | 4D4445FF20A17185006FCEEC /* PBXTargetDependency */ = {
337 | isa = PBXTargetDependency;
338 | target = 4D5BDA8C1F146CAC00E68CB6 /* ZVProgressHUD */;
339 | targetProxy = 4D4445FE20A17185006FCEEC /* PBXContainerItemProxy */;
340 | };
341 | /* End PBXTargetDependency section */
342 |
343 | /* Begin PBXVariantGroup section */
344 | 4DFF5B4F20318D7A0098BA7D /* Main.storyboard */ = {
345 | isa = PBXVariantGroup;
346 | children = (
347 | 4DFF5B5020318D7A0098BA7D /* Base */,
348 | );
349 | name = Main.storyboard;
350 | sourceTree = "";
351 | };
352 | 4DFF5B5420318D7A0098BA7D /* LaunchScreen.storyboard */ = {
353 | isa = PBXVariantGroup;
354 | children = (
355 | 4DFF5B5520318D7A0098BA7D /* Base */,
356 | );
357 | name = LaunchScreen.storyboard;
358 | sourceTree = "";
359 | };
360 | /* End PBXVariantGroup section */
361 |
362 | /* Begin XCBuildConfiguration section */
363 | 4D5BDA9F1F146CAC00E68CB6 /* Debug */ = {
364 | isa = XCBuildConfiguration;
365 | buildSettings = {
366 | ALWAYS_SEARCH_USER_PATHS = NO;
367 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
368 | CLANG_ANALYZER_NONNULL = YES;
369 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
371 | CLANG_CXX_LIBRARY = "libc++";
372 | CLANG_ENABLE_MODULES = YES;
373 | CLANG_ENABLE_OBJC_ARC = YES;
374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
375 | CLANG_WARN_BOOL_CONVERSION = YES;
376 | CLANG_WARN_COMMA = YES;
377 | CLANG_WARN_CONSTANT_CONVERSION = YES;
378 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
380 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
381 | CLANG_WARN_EMPTY_BODY = YES;
382 | CLANG_WARN_ENUM_CONVERSION = YES;
383 | CLANG_WARN_INFINITE_RECURSION = YES;
384 | CLANG_WARN_INT_CONVERSION = YES;
385 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
386 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
387 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
388 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
389 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
390 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
391 | CLANG_WARN_STRICT_PROTOTYPES = YES;
392 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
393 | CLANG_WARN_UNREACHABLE_CODE = YES;
394 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
395 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
396 | COPY_PHASE_STRIP = NO;
397 | CURRENT_PROJECT_VERSION = 1;
398 | DEBUG_INFORMATION_FORMAT = dwarf;
399 | ENABLE_STRICT_OBJC_MSGSEND = YES;
400 | ENABLE_TESTABILITY = YES;
401 | GCC_C_LANGUAGE_STANDARD = gnu99;
402 | GCC_DYNAMIC_NO_PIC = NO;
403 | GCC_NO_COMMON_BLOCKS = YES;
404 | GCC_OPTIMIZATION_LEVEL = 0;
405 | GCC_PREPROCESSOR_DEFINITIONS = (
406 | "DEBUG=1",
407 | "$(inherited)",
408 | );
409 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
410 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
411 | GCC_WARN_UNDECLARED_SELECTOR = YES;
412 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
413 | GCC_WARN_UNUSED_FUNCTION = YES;
414 | GCC_WARN_UNUSED_VARIABLE = YES;
415 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
416 | MTL_ENABLE_DEBUG_INFO = YES;
417 | ONLY_ACTIVE_ARCH = YES;
418 | SDKROOT = iphoneos;
419 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
420 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
421 | TARGETED_DEVICE_FAMILY = "1,2";
422 | VERSIONING_SYSTEM = "apple-generic";
423 | VERSION_INFO_PREFIX = "";
424 | };
425 | name = Debug;
426 | };
427 | 4D5BDAA01F146CAC00E68CB6 /* Release */ = {
428 | isa = XCBuildConfiguration;
429 | buildSettings = {
430 | ALWAYS_SEARCH_USER_PATHS = NO;
431 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
432 | CLANG_ANALYZER_NONNULL = YES;
433 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
434 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
435 | CLANG_CXX_LIBRARY = "libc++";
436 | CLANG_ENABLE_MODULES = YES;
437 | CLANG_ENABLE_OBJC_ARC = YES;
438 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
439 | CLANG_WARN_BOOL_CONVERSION = YES;
440 | CLANG_WARN_COMMA = YES;
441 | CLANG_WARN_CONSTANT_CONVERSION = YES;
442 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
443 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
444 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
445 | CLANG_WARN_EMPTY_BODY = YES;
446 | CLANG_WARN_ENUM_CONVERSION = YES;
447 | CLANG_WARN_INFINITE_RECURSION = YES;
448 | CLANG_WARN_INT_CONVERSION = YES;
449 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
450 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
451 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
452 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
453 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
454 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
455 | CLANG_WARN_STRICT_PROTOTYPES = YES;
456 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
457 | CLANG_WARN_UNREACHABLE_CODE = YES;
458 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
459 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
460 | COPY_PHASE_STRIP = NO;
461 | CURRENT_PROJECT_VERSION = 1;
462 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
463 | ENABLE_NS_ASSERTIONS = NO;
464 | ENABLE_STRICT_OBJC_MSGSEND = YES;
465 | GCC_C_LANGUAGE_STANDARD = gnu99;
466 | GCC_NO_COMMON_BLOCKS = YES;
467 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
468 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
469 | GCC_WARN_UNDECLARED_SELECTOR = YES;
470 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
471 | GCC_WARN_UNUSED_FUNCTION = YES;
472 | GCC_WARN_UNUSED_VARIABLE = YES;
473 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
474 | MTL_ENABLE_DEBUG_INFO = NO;
475 | SDKROOT = iphoneos;
476 | SWIFT_COMPILATION_MODE = wholemodule;
477 | SWIFT_OPTIMIZATION_LEVEL = "-O";
478 | TARGETED_DEVICE_FAMILY = "1,2";
479 | VALIDATE_PRODUCT = YES;
480 | VERSIONING_SYSTEM = "apple-generic";
481 | VERSION_INFO_PREFIX = "";
482 | };
483 | name = Release;
484 | };
485 | 4D5BDAA21F146CAC00E68CB6 /* Debug */ = {
486 | isa = XCBuildConfiguration;
487 | buildSettings = {
488 | CLANG_ENABLE_MODULES = YES;
489 | CODE_SIGN_IDENTITY = "";
490 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
491 | DEFINES_MODULE = YES;
492 | DEVELOPMENT_TEAM = DDWF823A49;
493 | DYLIB_COMPATIBILITY_VERSION = 1;
494 | DYLIB_CURRENT_VERSION = 1;
495 | DYLIB_INSTALL_NAME_BASE = "@rpath";
496 | FRAMEWORK_SEARCH_PATHS = "";
497 | INFOPLIST_FILE = ZVProgressHUD/Info.plist;
498 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
499 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
500 | LD_RUNPATH_SEARCH_PATHS = (
501 | "$(inherited)",
502 | "@executable_path/Frameworks",
503 | "@loader_path/Frameworks",
504 | );
505 | PRODUCT_BUNDLE_IDENTIFIER = com.zevwings.ZVProgressHUD;
506 | PRODUCT_NAME = "$(TARGET_NAME)";
507 | SKIP_INSTALL = YES;
508 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
509 | SWIFT_VERSION = 5.0;
510 | };
511 | name = Debug;
512 | };
513 | 4D5BDAA31F146CAC00E68CB6 /* Release */ = {
514 | isa = XCBuildConfiguration;
515 | buildSettings = {
516 | CLANG_ENABLE_MODULES = YES;
517 | CODE_SIGN_IDENTITY = "";
518 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
519 | DEFINES_MODULE = YES;
520 | DEVELOPMENT_TEAM = DDWF823A49;
521 | DYLIB_COMPATIBILITY_VERSION = 1;
522 | DYLIB_CURRENT_VERSION = 1;
523 | DYLIB_INSTALL_NAME_BASE = "@rpath";
524 | FRAMEWORK_SEARCH_PATHS = "";
525 | INFOPLIST_FILE = ZVProgressHUD/Info.plist;
526 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
527 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
528 | LD_RUNPATH_SEARCH_PATHS = (
529 | "$(inherited)",
530 | "@executable_path/Frameworks",
531 | "@loader_path/Frameworks",
532 | );
533 | PRODUCT_BUNDLE_IDENTIFIER = com.zevwings.ZVProgressHUD;
534 | PRODUCT_NAME = "$(TARGET_NAME)";
535 | SKIP_INSTALL = YES;
536 | SWIFT_VERSION = 5.0;
537 | };
538 | name = Release;
539 | };
540 | 4DFF5B5920318D7A0098BA7D /* Debug */ = {
541 | isa = XCBuildConfiguration;
542 | buildSettings = {
543 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
544 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
545 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
546 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
547 | CODE_SIGN_IDENTITY = "iPhone Developer";
548 | CODE_SIGN_STYLE = Automatic;
549 | DEVELOPMENT_TEAM = DDWF823A49;
550 | FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Carthage/Build/iOS";
551 | GCC_C_LANGUAGE_STANDARD = gnu11;
552 | INFOPLIST_FILE = ZVProgressHUDExample/Info.plist;
553 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
554 | LD_RUNPATH_SEARCH_PATHS = (
555 | "$(inherited)",
556 | "@executable_path/Frameworks",
557 | );
558 | OTHER_LDFLAGS = "";
559 | PRODUCT_BUNDLE_IDENTIFIER = com.zevwings.ZVProgressHUDExample;
560 | PRODUCT_NAME = "$(TARGET_NAME)";
561 | SWIFT_VERSION = 5.0;
562 | TARGETED_DEVICE_FAMILY = "1,2";
563 | };
564 | name = Debug;
565 | };
566 | 4DFF5B5A20318D7A0098BA7D /* Release */ = {
567 | isa = XCBuildConfiguration;
568 | buildSettings = {
569 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
570 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
571 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
572 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
573 | CODE_SIGN_IDENTITY = "iPhone Developer";
574 | CODE_SIGN_STYLE = Automatic;
575 | DEVELOPMENT_TEAM = DDWF823A49;
576 | FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Carthage/Build/iOS";
577 | GCC_C_LANGUAGE_STANDARD = gnu11;
578 | INFOPLIST_FILE = ZVProgressHUDExample/Info.plist;
579 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
580 | LD_RUNPATH_SEARCH_PATHS = (
581 | "$(inherited)",
582 | "@executable_path/Frameworks",
583 | );
584 | OTHER_LDFLAGS = "";
585 | PRODUCT_BUNDLE_IDENTIFIER = com.zevwings.ZVProgressHUDExample;
586 | PRODUCT_NAME = "$(TARGET_NAME)";
587 | SWIFT_VERSION = 5.0;
588 | TARGETED_DEVICE_FAMILY = "1,2";
589 | };
590 | name = Release;
591 | };
592 | /* End XCBuildConfiguration section */
593 |
594 | /* Begin XCConfigurationList section */
595 | 4D5BDA871F146CAC00E68CB6 /* Build configuration list for PBXProject "ZVProgressHUD" */ = {
596 | isa = XCConfigurationList;
597 | buildConfigurations = (
598 | 4D5BDA9F1F146CAC00E68CB6 /* Debug */,
599 | 4D5BDAA01F146CAC00E68CB6 /* Release */,
600 | );
601 | defaultConfigurationIsVisible = 0;
602 | defaultConfigurationName = Release;
603 | };
604 | 4D5BDAA11F146CAC00E68CB6 /* Build configuration list for PBXNativeTarget "ZVProgressHUD" */ = {
605 | isa = XCConfigurationList;
606 | buildConfigurations = (
607 | 4D5BDAA21F146CAC00E68CB6 /* Debug */,
608 | 4D5BDAA31F146CAC00E68CB6 /* Release */,
609 | );
610 | defaultConfigurationIsVisible = 0;
611 | defaultConfigurationName = Release;
612 | };
613 | 4DFF5B5820318D7A0098BA7D /* Build configuration list for PBXNativeTarget "ZVProgressHUDExample" */ = {
614 | isa = XCConfigurationList;
615 | buildConfigurations = (
616 | 4DFF5B5920318D7A0098BA7D /* Debug */,
617 | 4DFF5B5A20318D7A0098BA7D /* Release */,
618 | );
619 | defaultConfigurationIsVisible = 0;
620 | defaultConfigurationName = Release;
621 | };
622 | /* End XCConfigurationList section */
623 |
624 | /* Begin XCRemoteSwiftPackageReference section */
625 | 4DB03AC82531B329003F8300 /* XCRemoteSwiftPackageReference "ZVActivityIndicatorView" */ = {
626 | isa = XCRemoteSwiftPackageReference;
627 | repositoryURL = "https://github.com/zevwings/ZVActivityIndicatorView.git";
628 | requirement = {
629 | kind = upToNextMajorVersion;
630 | minimumVersion = 0.2.3;
631 | };
632 | };
633 | /* End XCRemoteSwiftPackageReference section */
634 |
635 | /* Begin XCSwiftPackageProductDependency section */
636 | 4DB03AC92531B329003F8300 /* ZVActivityIndicatorView */ = {
637 | isa = XCSwiftPackageProductDependency;
638 | package = 4DB03AC82531B329003F8300 /* XCRemoteSwiftPackageReference "ZVActivityIndicatorView" */;
639 | productName = ZVActivityIndicatorView;
640 | };
641 | /* End XCSwiftPackageProductDependency section */
642 | };
643 | rootObject = 4D5BDA841F146CAC00E68CB6 /* Project object */;
644 | }
645 |
--------------------------------------------------------------------------------
/ZVProgressHUD/ZVProgressHUD.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ZVProgressHUD.swift
3 | // ZVProgressHUD
4 | //
5 | // Created by zevwings on 2017/7/12.
6 | // Copyright © 2017-2019 zevwings. All rights reserved.
7 | //
8 |
9 | #if !os(macOS)
10 |
11 | import UIKit
12 |
13 | // MARK: - Notifications
14 |
15 | public extension Notification.Name {
16 |
17 | static let ZVProgressHUDReceivedTouchUpInsideEvent = Notification.Name("com.zevwings.progresshud.touchup.inside")
18 |
19 | static let ZVProgressHUDWillAppear = Notification.Name("com.zevwings.progresshud.willAppear")
20 | static let ZVProgressHUDDidAppear = Notification.Name("com.zevwings.progresshud.didAppear")
21 |
22 | static let ZVProgressHUDWillDisappear = Notification.Name("com.zevwings.progresshud.willDisappear")
23 | static let ZVProgressHUDDidDisappear = Notification.Name("com.zevwings.progresshud.didDisappear")
24 | }
25 |
26 | // MARK: - ZVProgressHUD
27 |
28 | open class ZVProgressHUD: UIControl {
29 |
30 | public typealias CompletionHandler = () -> Void
31 |
32 | public struct Configuration {
33 |
34 | public var displayStyle: DisplayStyle = .light
35 | public var maskType: MaskType = .none
36 | public var position: Position = .center
37 |
38 | public var cornerRadius: CGFloat = 8.0
39 | public var offset: UIOffset = .zero
40 |
41 | public var titleLabelFont: UIFont = .systemFont(ofSize: 16.0)
42 | public var titleLabelColor: UIColor?
43 |
44 | public var progressForegroundColor: UIColor?
45 | public var progressBackgroundColor: UIColor?
46 | public var progressLabelFont: UIFont = .systemFont(ofSize: 12.0)
47 | public var progressLabelColor: UIColor?
48 | public var isProgressLabelHidden: Bool = false
49 |
50 | public var strokeWidth: CGFloat = 3.0
51 | public var animationType: ZVIndicatorView.AnimationType = .flat
52 |
53 | public var contentInsets = UIEdgeInsets(top: 24.0, left: 24.0, bottom: 24.0, right: 24.0)
54 | public var titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0 )
55 | public var indicatorEdgeInsets = UIEdgeInsets(top: 12.0, left: 12.0, bottom: 12.0, right: 12.0)
56 |
57 | public var indicatorSize = CGSize(width: 56.0, height: 56.0)
58 |
59 | public var logo: UIImage?
60 | public var logoSize = CGSize(width: 30.0, height: 30.0)
61 |
62 | public init() {}
63 | }
64 |
65 | public enum DisplayType {
66 | case indicator(title: String?, type: ZVIndicatorView.IndicatorType)
67 | case text(value: String)
68 | case customeView(view: UIView)
69 | }
70 |
71 | public enum DisplayStyle {
72 | case light
73 | case dark
74 | case custom((backgroundColor: UIColor, foregroundColor: UIColor))
75 | }
76 |
77 | public enum MaskType {
78 | case none
79 | case clear
80 | case black
81 | case custom(color: UIColor)
82 | }
83 |
84 | public enum Position {
85 | case top
86 | case center
87 | case bottom
88 | }
89 |
90 | private struct AnimationDuration {
91 | static let fadeIn: TimeInterval = 0.15
92 | static let fadeOut: TimeInterval = 0.15
93 | static let keyboard: TimeInterval = 0.25
94 | }
95 |
96 | // MARK: Public
97 |
98 | internal static let shared = ZVProgressHUD(frame: .zero)
99 |
100 | var maxSupportedWindowLevel: UIWindow.Level = .normal
101 |
102 | var fadeInAnimationTimeInterval: TimeInterval = ZVProgressHUD.AnimationDuration.fadeIn
103 | var fadeOutAnimationTImeInterval: TimeInterval = ZVProgressHUD.AnimationDuration.fadeOut
104 |
105 | var minimumDismissTimeInterval: TimeInterval = 3.0
106 | var maximumDismissTimeInterval: TimeInterval = 10.0
107 |
108 | // swiftlint:disable:next line_length
109 | var maximumContentSize = CGSize(width: UIScreen.main.bounds.width * 0.618, height: UIScreen.main.bounds.width * 0.618)
110 | // swiftlint:disable:previous: line_length
111 |
112 | /// 全局配置属性
113 | internal var configuration = Configuration()
114 |
115 | // MARK: Private
116 |
117 | private var _fadeOutTimer: Timer?
118 | private var _fadeInDeleyTimer: Timer?
119 | private var _fadeOutDelayTimer: Timer?
120 |
121 | private var _displayType: DisplayType?
122 | public var displayType: DisplayType? {
123 | return _displayType
124 | }
125 |
126 | private var _containerView: UIView?
127 |
128 | /// 展示自定视图时,保存临时视图
129 | private weak var _tempCustomView: UIView?
130 |
131 | /// 临时配置属性,在`HUD`消失时,清空
132 | private var _tempConfiguration: Configuration?
133 |
134 | // MARK: UI
135 |
136 | private lazy var maskLayer: CALayer = { [unowned self] in
137 | let maskLayer = CALayer()
138 | return maskLayer
139 | }()
140 |
141 | private lazy var baseView: UIControl = {
142 | let baseView = UIControl()
143 | baseView.backgroundColor = .clear
144 | baseView.alpha = 0
145 | baseView.layer.masksToBounds = true
146 | return baseView
147 | }()
148 |
149 | private lazy var indicatorView: ZVIndicatorView = {
150 | let indicatorView = ZVIndicatorView()
151 | indicatorView.isUserInteractionEnabled = false
152 | indicatorView.alpha = 0
153 | return indicatorView
154 | }()
155 |
156 | private lazy var titleLabel: UILabel = { [unowned self] in
157 |
158 | let titleLabel = UILabel(frame: .zero)
159 | titleLabel.minimumScaleFactor = 0.5
160 | titleLabel.textAlignment = .center
161 | titleLabel.isUserInteractionEnabled = false
162 | titleLabel.backgroundColor = .clear
163 | titleLabel.lineBreakMode = .byTruncatingTail
164 | titleLabel.numberOfLines = 0
165 | titleLabel.alpha = 0
166 | return titleLabel
167 | }()
168 |
169 | private lazy var logoView: UIImageView = { [unowned self] in
170 |
171 | let logoView = UIImageView(frame: .zero)
172 | logoView.contentMode = .scaleAspectFit
173 | logoView.layer.masksToBounds = true
174 | return logoView
175 | }()
176 |
177 | // MARK: Init
178 |
179 | deinit {
180 | NotificationCenter.default.removeObserver(self)
181 | }
182 |
183 | private override init(frame: CGRect) {
184 | super.init(frame: frame)
185 |
186 | alpha = 0
187 | backgroundColor = .clear
188 |
189 | addTarget(self, action: #selector(overlayRecievedTouchUpInsideEvent(_:)), for: .touchUpInside)
190 | }
191 |
192 | public required init?(coder aDecoder: NSCoder) {
193 | fatalError("init(coder:) has not been implemented")
194 | }
195 | }
196 |
197 | // MARK: - Internal Operations
198 |
199 | extension ZVProgressHUD {
200 |
201 | func internalShow(
202 | displayType: DisplayType,
203 | in superview: UIView?,
204 | delay delayTimeInterval: TimeInterval,
205 | with configuration: Configuration?
206 | ) {
207 | OperationQueue.main.addOperation { [weak self] in
208 |
209 | guard let `self` = self else { return }
210 |
211 | self._tempConfiguration = configuration
212 |
213 | if self.superview != superview {
214 | self.indicatorView.removeFromSuperview()
215 | self.titleLabel.removeFromSuperview()
216 | self.baseView.removeFromSuperview()
217 | self.logoView.removeFromSuperview()
218 | self.removeFromSuperview()
219 | }
220 |
221 | /// 确保自定义视图不会重复添加
222 | if let customView = self._tempCustomView {
223 | customView.removeFromSuperview()
224 | }
225 |
226 | self.fadeOutTimer = nil
227 | self.fadeInDeleyTimer = nil
228 | self.fadeOutDelayTimer = nil
229 |
230 | if let superview = superview {
231 | self._containerView = superview
232 | } else {
233 | self._containerView = self.getKeyWindow()
234 | }
235 |
236 | // set property form displayType
237 | self._displayType = displayType
238 |
239 | self.updateViewHierarchy()
240 |
241 | // set property form maskType
242 | self.isUserInteractionEnabled = self.maskType.isUserInteractionEnabled
243 | self.maskLayer.backgroundColor = self.maskType.backgroundColor
244 |
245 | self.baseView.layer.cornerRadius = self.cornerRadius
246 | self.baseView.backgroundColor = self.displayStyle.backgroundColor
247 |
248 | self.titleLabel.text = displayType.title
249 | self.titleLabel.isHidden = displayType.title.isEmpty
250 | self.titleLabel.font = self.titleLabelFont
251 | self.titleLabel.textColor = self.titleLabelColor
252 |
253 | self.indicatorView.indcatorType = displayType.indicatorType
254 | self.indicatorView.strokeWidth = self.strokeWidth
255 | self.indicatorView.tintColor = self.displayStyle.foregroundColor
256 | self.indicatorView.progressForegroundColor = self.progressForegroundColor
257 | self.indicatorView.progressBackgroundColor = self.progressBackgroundColor
258 | self.indicatorView.progressLabelFont = self.progressLabelFont
259 | self.indicatorView.progressLabelColor = self.progressLabelColor
260 | self.indicatorView.isProgressLabelHidden = self.isProgressLabelHidden
261 |
262 | self.logoView.image = self.logo
263 | self.logoView.tintColor = self.displayStyle.foregroundColor
264 |
265 | // display
266 | if delayTimeInterval > 0 {
267 | self.fadeInDeleyTimer = Timer.scheduledTimer(
268 | timeInterval: delayTimeInterval,
269 | target: self,
270 | selector: #selector(self.fadeInTimerAction(_:)),
271 | userInfo: nil,
272 | repeats: false
273 | )
274 | } else {
275 | self.fadeIn()
276 | }
277 | }
278 | }
279 |
280 | func internalDismiss(
281 | with delayTimeInterval: TimeInterval = 0,
282 | completion: CompletionHandler? = nil
283 | ) {
284 |
285 | if delayTimeInterval > 0 {
286 | fadeOutDelayTimer = Timer.scheduledTimer(
287 | timeInterval: delayTimeInterval,
288 | target: self,
289 | selector: #selector(fadeOutTimerAction(_:)),
290 | userInfo: completion,
291 | repeats: false
292 | )
293 | } else {
294 | fadeOut(with: completion)
295 | }
296 | }
297 |
298 | @objc private func fadeInTimerAction(_ timer: Timer?) {
299 | fadeIn()
300 | }
301 |
302 | @objc private func fadeIn() {
303 |
304 | guard let displayType = _displayType else { return }
305 |
306 | // swiftlint:disable:next line_length
307 | let displayTimeInterval = displayType.getDisplayTimeInterval(minimumDismissTimeInterval, maximumDismissTimeInterval)
308 | // swiftlint:disable:previous: line_length
309 |
310 | updateSubviews()
311 |
312 | let keybordHeight = getVisibleKeyboardHeight()
313 | placeSubviews(keybordHeight)
314 |
315 | if self.alpha != 1.0 {
316 |
317 | // send the notification HUD will appear
318 | NotificationCenter.default.post(name: .ZVProgressHUDWillAppear, object: self, userInfo: nil)
319 |
320 | let animationBlock = {
321 | self.alpha = 1.0
322 | self.baseView.alpha = 1.0
323 | self.indicatorView.alpha = 1.0
324 | self.titleLabel.alpha = 1.0
325 | }
326 |
327 | let completionBlock = {
328 |
329 | guard self.alpha == 1.0 else { return }
330 |
331 | self.fadeInDeleyTimer = nil
332 |
333 | // register keyboard notification and orientation notification
334 | self.registerNotifications()
335 |
336 | // send the notification HUD did appear
337 | NotificationCenter.default.post(name: .ZVProgressHUDDidAppear, object: self, userInfo: nil)
338 |
339 | if displayTimeInterval > 0 {
340 | self.fadeOutTimer = Timer.scheduledTimer(
341 | timeInterval: displayTimeInterval,
342 | target: self,
343 | selector: #selector(self.fadeOutTimerAction(_:)),
344 | userInfo: nil,
345 | repeats: false
346 | )
347 | RunLoop.main.add(self.fadeOutTimer!, forMode: RunLoop.Mode.common)
348 | } else {
349 | if displayType.indicatorType.progressValueChecker.0 &&
350 | displayType.indicatorType.progressValueChecker.1 >= 1.0 {
351 | self.internalDismiss()
352 | }
353 | }
354 | }
355 |
356 | if fadeInAnimationTimeInterval > 0 {
357 | UIView.animate(
358 | withDuration: fadeInAnimationTimeInterval,
359 | delay: 0,
360 | options: [.allowUserInteraction, .curveEaseOut, .beginFromCurrentState],
361 | animations: {
362 | animationBlock()
363 | }, completion: { _ in
364 | completionBlock()
365 | }
366 | )
367 | } else {
368 | animationBlock()
369 | completionBlock()
370 | }
371 | } else {
372 |
373 | if displayTimeInterval > 0 {
374 | fadeOutTimer = Timer.scheduledTimer(
375 | timeInterval: displayTimeInterval,
376 | target: self,
377 | selector: #selector(self.fadeOutTimerAction(_:)),
378 | userInfo: nil,
379 | repeats: false
380 | )
381 | RunLoop.main.add(fadeOutTimer!, forMode: RunLoop.Mode.common)
382 | } else {
383 | if displayType.indicatorType.progressValueChecker.0 &&
384 | displayType.indicatorType.progressValueChecker.1 >= 1.0 {
385 | fadeOut()
386 | }
387 | }
388 | }
389 | }
390 |
391 | @objc private func fadeOutTimerAction(_ timer: Timer?) {
392 |
393 | let completion = timer?.userInfo as? CompletionHandler
394 | fadeOut(with: completion)
395 | }
396 |
397 | @objc private func fadeOut(with completion: CompletionHandler? = nil) {
398 |
399 | OperationQueue.main.addOperation { [weak self] in
400 |
401 | guard let `self` = self else { return }
402 |
403 | // send the notification HUD will disAppear
404 | NotificationCenter.default.post(name: .ZVProgressHUDWillDisappear, object: self, userInfo: nil)
405 |
406 | let animationBlock = {
407 | self.alpha = 0
408 | self.baseView.alpha = 0
409 | self.baseView.backgroundColor = .clear
410 | self.indicatorView.alpha = 0
411 | self.titleLabel.alpha = 0
412 | }
413 |
414 | let completionBlock = {
415 |
416 | guard self.alpha == 0 else { return }
417 |
418 | self.fadeOutTimer = nil
419 | self.fadeOutDelayTimer = nil
420 |
421 | // update view hierarchy
422 | self.indicatorView.removeFromSuperview()
423 | self.titleLabel.removeFromSuperview()
424 | self.baseView.removeFromSuperview()
425 | self.logoView.removeFromSuperview()
426 | self.removeFromSuperview()
427 |
428 | self._containerView = nil
429 |
430 | // remove notifications from self
431 | NotificationCenter.default.removeObserver(self)
432 |
433 | // send the notification HUD did disAppear
434 | NotificationCenter.default.post(name: .ZVProgressHUDDidDisappear, object: self, userInfo: nil)
435 |
436 | // execute completion handler
437 | completion?()
438 |
439 | self._tempConfiguration = nil
440 | }
441 |
442 | if self.fadeOutAnimationTImeInterval > 0 {
443 | UIView.animate(
444 | withDuration: self.fadeOutAnimationTImeInterval,
445 | delay: 0,
446 | options: [.allowUserInteraction, .curveEaseOut, .beginFromCurrentState],
447 | animations: {
448 | animationBlock()
449 | }, completion: { _ in
450 | completionBlock()
451 | }
452 | )
453 | } else {
454 | animationBlock()
455 | completionBlock()
456 | }
457 |
458 | self.setNeedsDisplay()
459 | }
460 | }
461 | }
462 |
463 | // MARK: - Update Subviews
464 |
465 | private extension ZVProgressHUD {
466 |
467 | func updateViewHierarchy() {
468 |
469 | guard let displayType = _displayType else { return }
470 |
471 | self.isUserInteractionEnabled = self.maskType.isUserInteractionEnabled
472 |
473 | if superview == nil {
474 | _containerView?.addSubview(self)
475 | } else {
476 | _containerView?.bringSubviewToFront(self)
477 | }
478 |
479 | if maskLayer.superlayer == nil {
480 | layer.addSublayer(maskLayer)
481 | }
482 |
483 | self.maskLayer.backgroundColor = self.maskType.backgroundColor
484 |
485 | if baseView.superview == nil {
486 | addSubview(baseView)
487 | } else {
488 | bringSubviewToFront(baseView)
489 | }
490 |
491 | baseView.layer.cornerRadius = cornerRadius
492 | baseView.backgroundColor = displayStyle.backgroundColor
493 |
494 | switch displayType {
495 | case let .indicator(title, indicatorType):
496 | updateIndicatorHierarchy(with: indicatorType)
497 | updateLabelHierarchy(with: title)
498 | case let .text(title):
499 | updateLabelHierarchy(with: title)
500 | case let .customeView(view):
501 | _tempCustomView = view
502 | baseView.addSubview(view)
503 | }
504 | }
505 |
506 | /// 更新 指示视图视图层级
507 | func updateIndicatorHierarchy(with indicatorType: ZVIndicatorView.IndicatorType) {
508 |
509 | if indicatorType.showLogo && logo != nil && logoView.superview == nil {
510 | baseView.addSubview(logoView)
511 | } else {
512 | baseView.bringSubviewToFront(logoView)
513 | }
514 | logoView.image = logo
515 | logoView.tintColor = displayStyle.foregroundColor
516 |
517 | /// 添加指示视图
518 | if indicatorView.superview == nil {
519 | baseView.addSubview(indicatorView)
520 | } else {
521 | baseView.bringSubviewToFront(indicatorView)
522 | }
523 |
524 | indicatorView.indcatorType = indicatorType
525 | }
526 |
527 | /// 更新描述标题视图层级
528 | func updateLabelHierarchy(with text: String?) {
529 |
530 | if titleLabel.superview == nil {
531 | baseView.addSubview(titleLabel)
532 | } else {
533 | baseView.bringSubviewToFront(titleLabel)
534 | }
535 |
536 | titleLabel.text = text
537 | titleLabel.isHidden = false
538 | titleLabel.font = titleLabelFont
539 | titleLabel.textColor = titleLabelColor
540 | }
541 |
542 | func updateSubviews() {
543 |
544 | guard let containerView = _containerView, let displayType = _displayType else { return }
545 |
546 | frame = CGRect(origin: .zero, size: containerView.frame.size)
547 | maskLayer.frame = CGRect(origin: .zero, size: containerView.frame.size)
548 |
549 | switch displayType {
550 | case .indicator, .text:
551 |
552 | if !indicatorView.isHidden {
553 | indicatorView.frame = CGRect(origin: .zero, size: indicatorSize)
554 | }
555 |
556 | if let displayType = _displayType, displayType.indicatorType.showLogo, logo != nil {
557 | logoView.frame = CGRect(origin: .zero, size: logoSize)
558 | }
559 |
560 | var labelSize: CGSize = .zero
561 | if !titleLabel.isHidden, let title = titleLabel.text as NSString?, title.length > 0 {
562 | let attributes: [NSAttributedString.Key: Any] = [.font: titleLabelFont]
563 | let options: NSStringDrawingOptions = [
564 | .usesFontLeading,
565 | .truncatesLastVisibleLine,
566 | .usesLineFragmentOrigin
567 | ]
568 | labelSize = title.boundingRect(
569 | with: maximumContentSize,
570 | options: options,
571 | attributes: attributes,
572 | context: nil
573 | ).size
574 | titleLabel.frame = CGRect(origin: .zero, size: labelSize)
575 | }
576 |
577 | let labelHeight = titleLabel.isHidden ? 0 : labelSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom
578 | let indicatorHeight = indicatorView.isHidden ?
579 | 0 :
580 | indicatorSize.height + indicatorEdgeInsets.top + indicatorEdgeInsets.bottom
581 |
582 | let contentHeight = labelHeight + indicatorHeight + contentInsets.top + contentInsets.bottom
583 | let maxWidth = max(labelSize.width + titleEdgeInsets.left + titleEdgeInsets.right,
584 | indicatorSize.width + indicatorEdgeInsets.left + indicatorEdgeInsets.right)
585 | let contetnWidth = maxWidth + contentInsets.left + contentInsets.right
586 |
587 | let contentSize = CGSize(width: contetnWidth, height: contentHeight)
588 | let origin = self.baseView.frame.origin
589 | baseView.frame = CGRect(origin: origin, size: contentSize)
590 |
591 | CATransaction.begin()
592 | CATransaction.setDisableActions(true)
593 |
594 | let centerX: CGFloat = contetnWidth / 2.0
595 | var centerY: CGFloat = contentHeight / 2.0
596 |
597 | // Indicator
598 | if labelHeight > 0 && !indicatorView.isHidden {
599 | centerY = contentInsets.top + indicatorEdgeInsets.top + indicatorSize.height / 2.0
600 | }
601 | indicatorView.center = CGPoint(x: centerX, y: centerY)
602 | logoView.center = CGPoint(x: centerX, y: centerY)
603 |
604 | // Label
605 | if indicatorHeight > 0 && !titleLabel.isHidden {
606 | centerY = contentInsets.top + indicatorHeight + titleEdgeInsets.top + labelSize.height / 2.0
607 | }
608 | titleLabel.center = CGPoint(x: centerX, y: centerY)
609 |
610 | CATransaction.commit()
611 |
612 | case let .customeView(view):
613 | let origin = self.baseView.frame.origin
614 | baseView.frame = CGRect(origin: origin, size: view.frame.size)
615 | }
616 | }
617 |
618 | @objc func placeSubviews(_ keybordHeight: CGFloat = 0, animationDuration: TimeInterval = 0) {
619 |
620 | guard let containerView = _containerView else { return }
621 |
622 | frame = CGRect(origin: .zero, size: containerView.frame.size)
623 | maskLayer.frame = CGRect(origin: .zero, size: containerView.frame.size)
624 |
625 | let keyWindow = getKeyWindow()
626 | let orenitationFrame = frame
627 | var statusBarFrame: CGRect = .zero
628 | if containerView == keyWindow {
629 | statusBarFrame = UIApplication.shared.statusBarFrame
630 | }
631 |
632 | // safe area bottom height
633 | let bottomInset: CGFloat
634 | if #available(iOS 11.0, *) {
635 | bottomInset = keyWindow?.safeAreaInsets.bottom ?? 0.0
636 | } else {
637 | bottomInset = 0
638 | }
639 |
640 | // if tabBar is hidden, bottom instantce is 24.0 + 12.0
641 | // otherwise, if keyboard is show, ignore tabBar height.
642 | let defaultBottomInset: CGFloat
643 | if keybordHeight > 0 {
644 | defaultBottomInset = 0
645 | } else {
646 | let tabBarHeight = keyWindow?.rootViewController?.tabBarController?.tabBar.frame.height ?? 24.0
647 | defaultBottomInset = tabBarHeight + bottomInset
648 | }
649 |
650 | // if navigationBar is hidden, top instantce is 24.0
651 | let defaultTopInset: CGFloat
652 | if let navigationController = keyWindow?.rootViewController?.navigationController {
653 | defaultTopInset = navigationController.navigationBar.frame.height
654 | } else {
655 | defaultTopInset = 24.0
656 | }
657 |
658 | var activeHeight = orenitationFrame.height
659 |
660 | if keybordHeight > 0 {
661 | activeHeight += statusBarFrame.height * 2
662 | }
663 |
664 | activeHeight -= keybordHeight
665 |
666 | let distanceOfNavigationBarOrTabBar: CGFloat = 12
667 |
668 | // swiftlint:disable line_length
669 | let posY: CGFloat
670 | switch position {
671 | case .top:
672 | posY = defaultTopInset + statusBarFrame.height + distanceOfNavigationBarOrTabBar + baseView.frame.height * 0.5 + offset.vertical
673 | case .center:
674 | posY = activeHeight * 0.45 + offset.vertical
675 | case .bottom:
676 | posY = activeHeight - defaultBottomInset - distanceOfNavigationBarOrTabBar - baseView.frame.height * 0.5 + offset.vertical
677 | }
678 | // swiftlint:enable line_length
679 |
680 | let posX = orenitationFrame.width / 2.0 + offset.horizontal
681 |
682 | let center = CGPoint(x: posX, y: posY)
683 |
684 | if animationDuration == 0 {
685 | baseView.center = center
686 | } else {
687 | UIView.animate(
688 | withDuration: animationDuration,
689 | delay: 0,
690 | options: [.allowUserInteraction, .beginFromCurrentState],
691 | animations: {
692 | self.baseView.center = center
693 | self.baseView.setNeedsDisplay()
694 | })
695 | }
696 | }
697 | }
698 |
699 | // MARK: - Event Handler
700 |
701 | private extension ZVProgressHUD {
702 |
703 | @objc func overlayRecievedTouchUpInsideEvent(_ sender: UIControl) {
704 | NotificationCenter.default.post(name: .ZVProgressHUDReceivedTouchUpInsideEvent, object: self, userInfo: nil)
705 | }
706 | }
707 |
708 | // MARK: - Notifications
709 |
710 | private extension ZVProgressHUD {
711 |
712 | private func registerNotifications() {
713 |
714 | NotificationCenter.default.addObserver(self,
715 | selector: #selector(handleKeyboardNotification(_:)),
716 | name: UIApplication.didChangeStatusBarOrientationNotification,
717 | object: nil)
718 |
719 | NotificationCenter.default.addObserver(self,
720 | selector: #selector(handleKeyboardNotification(_:)),
721 | name: UIApplication.didBecomeActiveNotification,
722 | object: nil)
723 |
724 | NotificationCenter.default.addObserver(self,
725 | selector: #selector(handleKeyboardNotification(_:)),
726 | name: UIResponder.keyboardWillShowNotification,
727 | object: nil)
728 |
729 | NotificationCenter.default.addObserver(self,
730 | selector: #selector(handleKeyboardNotification(_:)),
731 | name: UIResponder.keyboardWillHideNotification,
732 | object: nil)
733 |
734 | NotificationCenter.default.addObserver(self,
735 | selector: #selector(handleKeyboardNotification(_:)),
736 | name: UIResponder.keyboardDidShowNotification,
737 | object: nil)
738 |
739 | NotificationCenter.default.addObserver(self,
740 | selector: #selector(handleKeyboardNotification(_:)),
741 | name: UIResponder.keyboardDidHideNotification,
742 | object: nil)
743 | }
744 |
745 | @objc func handleKeyboardNotification(_ notification: Notification?) {
746 |
747 | let orientation = UIApplication.shared.statusBarOrientation
748 |
749 | var keybordHeight: CGFloat = 0
750 | var animationDuration: TimeInterval = 0
751 |
752 | if let notification = notification, let keyboardInfo = notification.userInfo {
753 | let keyboardFrame = keyboardInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
754 | animationDuration = keyboardInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval ?? 0
755 | if notification.name == UIResponder.keyboardWillShowNotification ||
756 | notification.name == UIResponder.keyboardDidShowNotification {
757 | if orientation == .portrait {
758 | keybordHeight = keyboardFrame?.height ?? 0
759 | }
760 | }
761 | } else {
762 | keybordHeight = getVisibleKeyboardHeight()
763 | }
764 |
765 | placeSubviews(keybordHeight, animationDuration: animationDuration)
766 | }
767 | }
768 |
769 | // MARK: - KeyWindow & Keyboard
770 |
771 | private extension ZVProgressHUD {
772 |
773 | func getKeyWindow() -> UIWindow? {
774 |
775 | var keyWindow: UIWindow?
776 | UIApplication.shared.windows.forEach { window in
777 | if window.screen == UIScreen.main,
778 | window.isHidden == false,
779 | window.alpha > 0,
780 | window.windowLevel >= UIWindow.Level.normal,
781 | window.windowLevel <= maxSupportedWindowLevel {
782 | keyWindow = window
783 | return
784 | }
785 | }
786 | return keyWindow
787 | }
788 |
789 | func getVisibleKeyboardHeight() -> CGFloat {
790 |
791 | var visibleKeyboardHeight: CGFloat = 0.0
792 | var keyboardWindow: UIWindow?
793 | UIApplication.shared.windows.reversed().forEach { window in
794 | let windowName = NSStringFromClass(window.classForCoder)
795 | if #available(iOS 9.0, *) {
796 | if windowName == "UIRemoteKeyboardWindow" {
797 | keyboardWindow = window
798 | return
799 | }
800 | } else {
801 | if windowName == "UITextEffectsWindow" {
802 | keyboardWindow = window
803 | return
804 | }
805 | }
806 | }
807 |
808 | var possibleKeyboard: UIView?
809 | keyboardWindow?.subviews.forEach({ subview in
810 | let viewClassName = NSStringFromClass(subview.classForCoder)
811 | if viewClassName.hasPrefix("UI") && viewClassName.hasSuffix("InputSetContainerView") {
812 | possibleKeyboard = subview
813 | return
814 | }
815 | })
816 |
817 | possibleKeyboard?.subviews.forEach({ subview in
818 | let viewClassName = NSStringFromClass(subview.classForCoder)
819 | if viewClassName.hasPrefix("UI") && viewClassName.hasSuffix("InputSetHostView") {
820 | let convertedRect = possibleKeyboard?.convert(subview.frame, to: self)
821 | let intersectedRect = convertedRect?.intersection(self.bounds)
822 | visibleKeyboardHeight = intersectedRect?.height ?? 0.0
823 | return
824 | }
825 | })
826 |
827 | return visibleKeyboardHeight
828 | }
829 | }
830 |
831 | // MARK: - Timers
832 |
833 | private extension ZVProgressHUD {
834 |
835 | var fadeOutTimer: Timer? {
836 | get {
837 | return _fadeOutTimer
838 | }
839 | set {
840 | if _fadeOutTimer != nil {
841 | _fadeOutTimer?.invalidate()
842 | _fadeOutTimer = nil
843 | }
844 | _fadeOutTimer = newValue
845 | }
846 | }
847 |
848 | var fadeInDeleyTimer: Timer? {
849 | get {
850 | return _fadeInDeleyTimer
851 | }
852 | set {
853 | if _fadeInDeleyTimer != nil {
854 | _fadeInDeleyTimer?.invalidate()
855 | _fadeInDeleyTimer = nil
856 | }
857 | _fadeInDeleyTimer = newValue
858 | }
859 | }
860 |
861 | var fadeOutDelayTimer: Timer? {
862 | get {
863 | return _fadeOutDelayTimer
864 | }
865 | set {
866 | if _fadeOutDelayTimer != nil {
867 | _fadeOutDelayTimer?.invalidate()
868 | _fadeOutDelayTimer = nil
869 | }
870 | _fadeOutDelayTimer = newValue
871 | }
872 | }
873 | }
874 |
875 | // MARK: - Props
876 |
877 | private extension ZVProgressHUD {
878 |
879 | var actualConfiguration: Configuration {
880 | if let configuration = _tempConfiguration {
881 | return configuration
882 | }
883 | return configuration
884 | }
885 |
886 | var displayStyle: DisplayStyle {
887 | return actualConfiguration.displayStyle
888 | }
889 |
890 | var maskType: MaskType {
891 | return actualConfiguration.maskType
892 | }
893 |
894 | var position: Position {
895 | return actualConfiguration.position
896 | }
897 |
898 | var cornerRadius: CGFloat {
899 | return actualConfiguration.cornerRadius
900 | }
901 |
902 | var offset: UIOffset {
903 | return actualConfiguration.offset
904 | }
905 |
906 | var titleLabelFont: UIFont {
907 | return actualConfiguration.titleLabelFont
908 | }
909 |
910 | var titleLabelColor: UIColor {
911 | if let color = _tempConfiguration?.titleLabelColor {
912 | return color
913 | }
914 | if let color = configuration.titleLabelColor {
915 | return color
916 | }
917 | return actualConfiguration.displayStyle.foregroundColor
918 | }
919 |
920 | var progressForegroundColor: UIColor {
921 | if let color = _tempConfiguration?.progressForegroundColor {
922 | return color
923 | }
924 | if let color = configuration.progressForegroundColor {
925 | return color
926 | }
927 | return actualConfiguration.displayStyle.foregroundColor
928 | }
929 |
930 | var progressBackgroundColor: UIColor {
931 | if let color = _tempConfiguration?.progressBackgroundColor {
932 | return color
933 | }
934 | if let color = configuration.progressBackgroundColor {
935 | return color
936 | }
937 | return actualConfiguration.displayStyle.foregroundColor.withAlphaComponent(0.5)
938 | }
939 |
940 | var progressLabelFont: UIFont {
941 | return actualConfiguration.progressLabelFont
942 | }
943 |
944 | var progressLabelColor: UIColor {
945 | if let color = _tempConfiguration?.progressLabelColor {
946 | return color
947 | }
948 | if let color = configuration.progressLabelColor {
949 | return color
950 | }
951 | return actualConfiguration.displayStyle.foregroundColor
952 | }
953 |
954 | var isProgressLabelHidden: Bool {
955 | return actualConfiguration.isProgressLabelHidden
956 | }
957 |
958 | var strokeWidth: CGFloat {
959 | return actualConfiguration.strokeWidth
960 | }
961 |
962 | var animationType: ZVIndicatorView.AnimationType {
963 | return actualConfiguration.animationType
964 | }
965 |
966 | var contentInsets: UIEdgeInsets {
967 | return actualConfiguration.contentInsets
968 | }
969 | var titleEdgeInsets: UIEdgeInsets {
970 | return actualConfiguration.titleEdgeInsets
971 | }
972 |
973 | var indicatorEdgeInsets: UIEdgeInsets {
974 | return actualConfiguration.indicatorEdgeInsets
975 | }
976 |
977 | var indicatorSize: CGSize {
978 | return actualConfiguration.indicatorSize
979 | }
980 |
981 | var logo: UIImage? {
982 | return actualConfiguration.logo
983 | }
984 |
985 | var logoSize: CGSize {
986 | return actualConfiguration.logoSize
987 | }
988 |
989 | }
990 |
991 | // MARK: - ZVProgressHUD.DisplayType
992 |
993 | extension ZVProgressHUD.DisplayType {
994 |
995 | var dismissAtomically: Bool {
996 | switch self {
997 | case .text:
998 | return true
999 | case .indicator(_, let type):
1000 | switch type {
1001 | case .success, .error, .warning:
1002 | return true
1003 | case .image(_, let dismissAtomically):
1004 | return dismissAtomically
1005 | default:
1006 | return false
1007 | }
1008 | case .customeView:
1009 | return false
1010 | }
1011 | }
1012 |
1013 | var title: String {
1014 | switch self {
1015 | case .text(let value): return value
1016 | case .indicator(let title, _): return title ?? ""
1017 | case .customeView:
1018 | return ""
1019 | }
1020 | }
1021 |
1022 | var indicatorType: ZVIndicatorView.IndicatorType {
1023 | switch self {
1024 | case .text: return .none
1025 | case .indicator(_, let type): return type
1026 | case .customeView: return .none
1027 | }
1028 | }
1029 |
1030 | func getDisplayTimeInterval(
1031 | _ minimumDismissTimeInterval: TimeInterval,
1032 | _ maximumDismissTimeInterval: TimeInterval
1033 | ) -> TimeInterval {
1034 |
1035 | var displayTimeInterval: TimeInterval = dismissAtomically ? 3.0 : 0
1036 |
1037 | guard displayTimeInterval > 0 else { return 0 }
1038 |
1039 | displayTimeInterval = max(Double(title.count) * 0.06 + 0.5, minimumDismissTimeInterval)
1040 | displayTimeInterval = min(displayTimeInterval, maximumDismissTimeInterval)
1041 |
1042 | return displayTimeInterval
1043 | }
1044 |
1045 | var customView: UIView? {
1046 | switch self {
1047 | case let .customeView(view):
1048 | return view
1049 | default:
1050 | return nil
1051 | }
1052 | }
1053 | }
1054 |
1055 | // MARK: - ZVProgressHUD.DisplayStyle
1056 |
1057 | extension ZVProgressHUD.DisplayStyle {
1058 | var foregroundColor: UIColor {
1059 | switch self {
1060 | case .dark: return .white
1061 | case .light: return UIColor(white: 0.2, alpha: 1)
1062 | case .custom(let (foregroundColor, _)): return foregroundColor
1063 | }
1064 | }
1065 |
1066 | var backgroundColor: UIColor {
1067 | switch self {
1068 | case .dark: return UIColor(white: 0, alpha: 0.75)
1069 | case .light: return .white
1070 | case .custom(let (_, backgroundColor)): return backgroundColor
1071 | }
1072 | }
1073 | }
1074 |
1075 | // MARK: - ZVProgressHUD.MaskType
1076 |
1077 | extension ZVProgressHUD.MaskType {
1078 |
1079 | var backgroundColor: CGColor {
1080 | switch self {
1081 | case .none, .clear: return UIColor.clear.cgColor
1082 | case .black: return UIColor.init(white: 0, alpha: 0.3).cgColor
1083 | case .custom(let color): return color.cgColor
1084 | }
1085 | }
1086 |
1087 | var isUserInteractionEnabled: Bool {
1088 | switch self {
1089 | case .none: return false
1090 | default: return true
1091 | }
1092 | }
1093 | }
1094 |
1095 | // MARK: - ZVIndicatorView.IndicatorType
1096 |
1097 | extension ZVIndicatorView.IndicatorType {
1098 |
1099 | var resource: String {
1100 | switch self {
1101 | case .error:
1102 | return "error"
1103 | case .success:
1104 | return "success"
1105 | case .warning:
1106 | return "warning"
1107 | default:
1108 | return ""
1109 | }
1110 | }
1111 |
1112 | var shouldHidden: Bool {
1113 | switch self {
1114 | case .none:
1115 | return true
1116 | default:
1117 | return false
1118 | }
1119 | }
1120 |
1121 | var progressValueChecker: (Bool, Float) {
1122 | switch self {
1123 | case .progress(let value):
1124 | return (true, value)
1125 | default:
1126 | return (false, 0.0)
1127 | }
1128 | }
1129 |
1130 | var showLogo: Bool {
1131 | switch self {
1132 | case .indicator(let animationType):
1133 | return animationType == .flat
1134 | default:
1135 | return false
1136 | }
1137 | }
1138 | }
1139 |
1140 | #endif
1141 |
--------------------------------------------------------------------------------