Commit 45560982 authored by Nature's avatar Nature

init

parents
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
打开在线页面的WebView插件,支持在线页面中调用cordova插件,支持android和ios平台
使用方法:
(1)打开在线页面:
WebViewPlugin.loadWebView(function (data) {
//成功打开在线页面,回调函数返回的data值为0,关闭在线页面返回值为1,仅ios平台有效
if (ionic.Platform.isIOS() && data === 1) {
//to do ....
}
}, function () {
console.log("WebViewPlugin.loadWebView failed");
}, url);
注意:对应android平台,关闭在线页面时回调函数不会返回值,如果想在关闭在线页面时做一些处理,
可以在app.js中监听resume事件,例如:
$ionicPlatform.ready(function () {
//关闭在线页面时,android平台会触发resume事件
if (ionic.Platform.isAndroid()) {
$ionicPlatform.on("pause", function (event) {
//to do ...
});
$ionicPlatform.on("resume", function (event) {
//to do ....
});
}
});
(2)关闭在线页面:
WebViewPlugin.dismissWebView(function () {
console.log("WebViewPlugin.dismissWebView success");
}, function () {
console.log("WebViewPlugin.dismissWebView error");
}, '');
\ No newline at end of file
{
"_args": [
[
{
"raw": "D:\\cordova-plugin-hand-webview",
"scope": null,
"escapedName": null,
"name": null,
"rawSpec": "D:\\cordova-plugin-hand-webview",
"spec": "D:\\cordova-plugin-hand-webview",
"type": "directory"
},
"D:\\Project\\jianXinRenShou\\jxrs-app"
]
],
"_from": "..\\..\\..\\cordova-plugin-hand-webview",
"_id": "cordova-plugin-hand-webview@1.0.4",
"_inBundle": false,
"_inCache": true,
"_integrity": "sha512-HiOuakLrf5c64LwjO14KbbJw6aEIXJsreXARRRQFF6uCjJz1y8sw3VxljEF50gkT+9VMo58uV3AyjNe9yfMqUA==",
"_location": "/cordova-plugin-hand-webview",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "cordova-plugin-hand-webview",
"name": "cordova-plugin-hand-webview",
"escapedName": "cordova-plugin-hand-webview",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER"
],
"_resolved": "file:..\\..\\..\\cordova-plugin-hand-webview",
"_shasum": "1edd7e7fbb373e4376dbeab13e84efd65163074d",
"_shrinkwrap": null,
"_spec": "cordova-plugin-hand-webview",
"_where": "D:\\develop\\mobile\\app\\jxrs-app",
"author": {
"name": "hand plugin"
},
"bugs": {
"url": "https://github.com/liuzong/cordova-plugin-hand-webview/issues"
},
"bundleDependencies": false,
"cordova": {
"id": "cordova-plugin-hand-webview",
"platforms": [
"android",
"ios"
]
},
"dependencies": {},
"deprecated": false,
"description": "open the H5 page",
"devDependencies": {},
"homepage": "https://github.com/liuzong/cordova-plugin-hand-webview#readme",
"keywords": [
"cordova",
"cordova-webview",
"webview"
],
"license": "Apache 2.0",
"name": "cordova-plugin-hand-webview",
"optionalDependencies": {},
"readme": "打开在线页面的WebView插件,支持在线页面中调用cordova插件,支持android和ios平台\r\n\r\n使用方法:\r\n(1)打开在线页面:\r\n WebViewPlugin.loadWebView(function (data) {\r\n //成功打开在线页面,回调函数返回的data值为0,关闭在线页面返回值为1,仅ios平台有效\r\n if (ionic.Platform.isIOS() && data === 1) {\r\n //to do ....\r\n }\r\n }, function () {\r\n console.log(\"WebViewPlugin.loadWebView failed\");\r\n }, url);\r\n 注意:对应android平台,关闭在线页面时回调函数不会返回值,如果想在关闭在线页面时做一些处理,\r\n 可以在app.js中监听resume事件,例如:\r\n $ionicPlatform.ready(function () {\r\n //关闭在线页面时,android平台会触发resume事件\r\n if (ionic.Platform.isAndroid()) {\r\n $ionicPlatform.on(\"pause\", function (event) {\r\n //to do ...\r\n });\r\n $ionicPlatform.on(\"resume\", function (event) {\r\n //to do ....\r\n });\r\n }\r\n });\r\n(2)关闭在线页面:\r\n WebViewPlugin.dismissWebView(function () {\r\n console.log(\"WebViewPlugin.dismissWebView success\");\r\n }, function () {\r\n console.log(\"WebViewPlugin.dismissWebView error\");\r\n }, '');",
"readmeFilename": "README.md",
"repository": {
"type": "git",
"url": "git+https://github.com/liuzong/cordova-plugin-hand-webview.git"
},
"version": "1.0.4"
}
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
id="cordova-plugin-hand-webview" version="1.0.4">
<name>WebViewPlugin</name>
<author>hand</author>
<description>hand plugin.</description>
<keywords>cordova,avtive</keywords>
<license>Apache 2.0</license>
<js-module charset="utf-8" name="WebViewPlugin" src="www/WebViewPlugin.js">
<clobbers target="WebViewPlugin"/>
</js-module>
<platform name="android">
<config-file parent="/*" target="res/xml/config.xml">
<feature name="WebViewPlugin">
<param name="android-package" value="com.hand.webview.WebViewPlugin"/>
</feature>
</config-file>
<source-file src="src/android/src/com/hand/webview/Util.java" target-dir="src/com/hand/webview"/>
<source-file src="src/android/src/com/hand/webview/WebViewActivity.java" target-dir="src/com/hand/webview"/>
<source-file src="src/android/src/com/hand/webview/WebViewActivityManager.java" target-dir="src/com/hand/webview"/>
<source-file src="src/android/src/com/hand/webview/WebViewPlugin.java" target-dir="src/com/hand/webview"/>
<source-file src="src/android/src/com/hand/webview/DialogLoad.java" target-dir="src/com/hand/webview"/>
<source-file src="src/android/layout/activity_webview.xml" target-dir="res/layout"/>
<source-file src="src/android/drawable/anim_loading.xml" target-dir="res/drawable"/>
<source-file src="src/android/layout/dialog_loading.xml" target-dir="res/layout"/>
<source-file src="src/android/values/web_style.xml" target-dir="res/values"/>
<source-file src="src/android/drawable-hdpi/load1.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load2.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load3.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load4.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load5.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load6.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load7.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load8.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load9.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load10.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load11.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load12.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load13.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load14.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load15.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load16.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load17.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load18.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load19.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load20.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load21.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load22.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load23.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load24.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load25.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load26.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load27.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load28.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load29.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load30.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load31.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load32.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load33.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load34.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load35.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load36.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load37.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load38.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load39.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load40.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load41.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load42.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load43.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load44.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load45.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load46.png" target-dir="res/drawable-hdpi"/>
<source-file src="src/android/drawable-hdpi/load47.png" target-dir="res/drawable-hdpi"/>
<config-file target="AndroidManifest.xml" parent="/manifest/application">
<activity android:screenOrientation="portrait" android:name="com.hand.webview.WebViewActivity"></activity>
</config-file>
<config-file parent="/manifest" target="AndroidManifest.xml">
<uses-permission android:name="android.permission.INTERNET" />
</config-file>
</platform>
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="WebViewPlugin">
<param name="ios-package" value="CDVWebViewPlugin"/>
</feature>
</config-file>
<header-file src="src/ios/plugins/CDVWebViewPlugin.h" />
<source-file src="src/ios/plugins/CDVWebViewPlugin.m" />
<header-file src="src/ios/plugins/WebPluginController.h" />
<source-file src="src/ios/plugins/WebPluginController.m" />
<header-file src="src/ios/plugins/MBProgressHUD.h" />
<source-file src="src/ios/plugins/MBProgressHUD.m" />
<header-file src="src/ios/plugins/MBProgressHUD+XW.h" />
<source-file src="src/ios/plugins/MBProgressHUD+XW.m" />
<header-file src="src/ios/plugins/DRPLoadingSpinner.h" />
<source-file src="src/ios/plugins/DRPLoadingSpinner.m" />
<header-file src="src/ios/plugins/DRPLoadingSpinnerTimingFunction.h" />
<source-file src="src/ios/plugins/DRPLoadingSpinnerTimingFunction.m" />
</platform>
</plugin>
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@drawable/load2"
android:duration="10" />
<item
android:drawable="@drawable/load3"
android:duration="10" />
<item
android:drawable="@drawable/load4"
android:duration="10" />
<item
android:drawable="@drawable/load5"
android:duration="10" />
<item
android:drawable="@drawable/load6"
android:duration="10"/>
<item
android:drawable="@drawable/load7"
android:duration="10" />
<item
android:drawable="@drawable/load8"
android:duration="10" />
<item
android:drawable="@drawable/load9"
android:duration="10" />
<item
android:drawable="@drawable/load10"
android:duration="10" />
<item
android:drawable="@drawable/load11"
android:duration="10" />
<item
android:drawable="@drawable/load12"
android:duration="10" />
<item
android:drawable="@drawable/load13"
android:duration="10" />
<item
android:drawable="@drawable/load14"
android:duration="10" />
<item
android:drawable="@drawable/load15"
android:duration="10" />
<item
android:drawable="@drawable/load16"
android:duration="10" />
<item
android:drawable="@drawable/load17"
android:duration="10" />
<item
android:drawable="@drawable/load18"
android:duration="10" />
<item
android:drawable="@drawable/load19"
android:duration="10" />
<item
android:drawable="@drawable/load20"
android:duration="10" />
<item
android:drawable="@drawable/load21"
android:duration="10" />
<item
android:drawable="@drawable/load22"
android:duration="10" />
<item
android:drawable="@drawable/load23"
android:duration="10" />
<item
android:drawable="@drawable/load24"
android:duration="10" />
<item
android:drawable="@drawable/load25"
android:duration="10" />
<item
android:drawable="@drawable/load26"
android:duration="10" />
<item
android:drawable="@drawable/load27"
android:duration="10" />
<item
android:drawable="@drawable/load28"
android:duration="10" />
<item
android:drawable="@drawable/load29"
android:duration="10" />
<item
android:drawable="@drawable/load30"
android:duration="10" />
<item
android:drawable="@drawable/load31"
android:duration="10" />
<item
android:drawable="@drawable/load32"
android:duration="10" />
<item
android:drawable="@drawable/load33"
android:duration="10" />
<item
android:drawable="@drawable/load34"
android:duration="10" />
<item
android:drawable="@drawable/load35"
android:duration="10" />
<item
android:drawable="@drawable/load36"
android:duration="10" />
<item
android:drawable="@drawable/load37"
android:duration="10" />
<item
android:drawable="@drawable/load38"
android:duration="10" />
<item
android:drawable="@drawable/load39"
android:duration="10" />
<item
android:drawable="@drawable/load40"
android:duration="10" />
<item
android:drawable="@drawable/load41"
android:duration="10" />
<item
android:drawable="@drawable/load42"
android:duration="10" />
<item
android:drawable="@drawable/load43"
android:duration="10" />
<item
android:drawable="@drawable/load44"
android:duration="10" />
<item
android:drawable="@drawable/load45"
android:duration="10" />
<item
android:drawable="@drawable/load46"
android:duration="10" />
<item
android:drawable="@drawable/load47"
android:duration="10" />
</animation-list>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical">
<org.apache.cordova.engine.SystemWebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"></org.apache.cordova.engine.SystemWebView>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical">
<ImageView
android:id = "@+id/img_load"
android:layout_width="30dp"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:src="@drawable/load1"
/>
</LinearLayout>
package com.hand.webview;
import android.app.Dialog;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
/**
* Created by panx on 2017/3/30.
*/
public class DialogLoad extends Dialog {
private ImageView imgLoad;
public DialogLoad(Context context) {
super(context,Util.getRS("Dialog_No_Border","style",context));
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(Util.getRS("dialog_loading","layout",context),null);
this.setContentView(view);
imgLoad = (ImageView) view.findViewById(Util.getRS("img_load","id",context));
WindowManager.LayoutParams lp = this.getWindow().getAttributes();
// 设置背景层透明度
lp.dimAmount = 0.0f;
this.getWindow().setAttributes(lp);
this.setCancelable(false);
}
@Override
public void show() {
if(this.isShowing()){
return;
}
super.show();
imgLoad.setImageResource(Util.getRS("anim_loading","drawable",getContext()));
AnimationDrawable animationDrawable = (AnimationDrawable) imgLoad.getDrawable();
animationDrawable.start();
}
@Override
public void dismiss() {
try {
AnimationDrawable animationDrawable = (AnimationDrawable) imgLoad.getDrawable();
animationDrawable.stop();
imgLoad.setImageResource(Util.getRS("load1","drawable",getContext()));
}catch (Exception e){
}
if(getWindow()!=null){
super.dismiss();
}
}
}
package com.hand.webview;
import android.content.Context;
/**
* Created by panx on 2017/2/7.
*/
public class Util {
public static int getRS(String name, String type, Context context){
int resID=0;
resID = context.getResources().getIdentifier(name, type, context.getPackageName());
return resID;
}
}
package com.hand.webview;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.widget.ProgressBar;
import org.apache.cordova.CordovaActivity;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaWebViewImpl;
import org.apache.cordova.engine.SystemWebChromeClient;
import org.apache.cordova.engine.SystemWebView;
import org.apache.cordova.engine.SystemWebViewClient;
import org.apache.cordova.engine.SystemWebViewEngine;
/**
* Created by panx on 2017/2/22.
*/
public class WebViewActivity extends CordovaActivity {
public static final String URL = "url";
private SystemWebView webView;
private String url;
private DialogLoad dialogLoad;
private boolean isFirstLoad = true;
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
WebViewActivityManager.OnCreateActivity(this);
setContentView(Util.getRS("activity_webview", "layout", this));
readIntent();
initView();
loadUrl(url);
}
private void readIntent() {
url = getIntent().getStringExtra(URL);
}
private void initView() {
webView = (SystemWebView) findViewById(Util.getRS("webview", "id", this));
dialogLoad = new DialogLoad(this);
}
@Override
protected CordovaWebView makeWebView() {
webView.getSettings().setJavaScriptEnabled(true);
webView.clearCache(true);
webView.clearHistory();
SystemWebViewEngine webViewEngine = new SystemWebViewEngine(webView);
webView.setWebViewClient(new SystemWebViewClient(webViewEngine) {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if(isFirstLoad) {
dialogLoad.show();
isFirstLoad = false;
}
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if(dialogLoad.isShowing())
new Handler(getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
dialogLoad.dismiss();
}
},2000);
}
});
return new CordovaWebViewImpl(webViewEngine);
}
@Override
public void finish() {
Log.e("WebViewActivity", "finish");
super.finish();
}
@Override
public void onDestroy() {
super.onDestroy();
WebViewActivityManager.OnDestroyActivity(this);
}
@Override
protected void createViews() {
appView.getView().requestFocusFromTouch();
}
}
package com.hand.webview;
import android.app.Activity;
import java.util.ArrayList;
import java.util.List;
/**
* Created by panx on 2017/2/22.
*/
public class WebViewActivityManager {
private static List<Activity> list = new ArrayList<Activity>();
public static void OnCreateActivity(Activity activity) {
for (Activity a : list) {
if (a.equals(list)) {
return;
}
}
list.add(activity);
}
public static void OnDestroyActivity(Activity activity) {
list.remove(activity);
}
public static List<Activity> GetActivityList() {
return list;
}
}
package com.hand.webview;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import java.util.List;
/**
* Created by panx on 2017/2/22.
*/
public class WebViewPlugin extends CordovaPlugin {
private final static String LOAD_WEBVIEW = "loadWebView";
private final static String DISMISS_WEBVIEW = "dismissWebView";
private CallbackContext callbackContext;
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
this.callbackContext = callbackContext;
if(LOAD_WEBVIEW.equals(action)){
loadWebview(args);
return true;
}else if(DISMISS_WEBVIEW.equals(action)){
disMissWebView();
return true;
}
return false;
}
private void loadWebview(JSONArray args){
try {
String url = args.getString(0);
Intent intent = new Intent(cordova.getActivity(),WebViewActivity.class);
intent.putExtra(WebViewActivity.URL,url);
cordova.setActivityResultCallback(this);
cordova.startActivityForResult(this, intent, 1);
} catch (JSONException e) {
callbackContext.error("Wrong arguments");
e.printStackTrace();
}
}
private void disMissWebView(){
Log.e("WebViewPlugin","dismisswebView");
/* if(WebViewActivity.instance!=null) {
WebViewActivity.instance.finish();
}*/
List<Activity> activities = WebViewActivityManager.GetActivityList();
if(activities!=null&&activities.size()>0){
activities.get(activities.size()-1).finish();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Dialog_No_Border" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
//
// CDVWebViewPlugin.h
// HelloCordova
//
// Created by Mr.xiao on 17/2/16.
//
//
#import <Cordova/CDVPlugin.h>
@interface CDVWebViewPlugin : CDVPlugin
- (void)loadWebView:(CDVInvokedUrlCommand *)command;
- (void)dismissWebView:(CDVInvokedUrlCommand *)command;
@end
//
// CDVWebViewPlugin.m
// HelloCordova
//
// Created by Mr.xiao on 17/2/16.
//
//
#import "CDVWebViewPlugin.h"
#import "WebPluginController.h"
@interface CDVWebViewPlugin ()<WebPluginProtocol>
@property (nonatomic ,strong) WebPluginController *webPluginCtrl;
@property (nonatomic, strong) NSString *callId;
@end
@implementation CDVWebViewPlugin
- (void)loadWebView:(CDVInvokedUrlCommand *)command{
NSString *result = [[command arguments] firstObject];
self.webPluginCtrl = [[WebPluginController alloc] init];
self.callId = command.callbackId;
[[NSUserDefaults standardUserDefaults] setObject:self.callId forKey:@"WebViewPluginid"];
self.webPluginCtrl.startPage = result;
self.webPluginCtrl.delegate = self;
self.webPluginCtrl.openDelegate = self.commandDelegate;
__weak CDVWebViewPlugin *weakSelf = self;
[self.commandDelegate runInBackground:^{
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.webPluginCtrl.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[weakSelf.viewController presentViewController:weakSelf.webPluginCtrl animated:YES completion:nil];
});
}];
}
- (void)dismissWebView:(CDVInvokedUrlCommand *)command{
__weak CDVWebViewPlugin *weakSelf = self;
NSString* callBackId = [[NSUserDefaults standardUserDefaults] objectForKey:@"WebViewPluginid"];
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:1];
WebPluginController* ctl = (WebPluginController*)self.viewController;
[ctl.openDelegate sendPluginResult:result callbackId:callBackId];
[self.commandDelegate runInBackground:^{
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.viewController dismissViewControllerAnimated:YES completion:nil];
//CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
});
}];
[self.commandDelegate sendPluginResult:result callbackId:callBackId];
}
- (void)webViewDidSuccessLoad{
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:0];
// [self.commandDelegate sendPluginResult:result callbackId:self.callId];
}
- (void)webViewDidFailedLoad{
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
// [self.commandDelegate sendPluginResult:result callbackId:self.callId];
}
@end
//
// DRPLoadingSpinner.h
// DRPLoadingSpinner
//
// Created by Justin Hill on 11/11/14.
// Copyright (c) 2014 Justin Hill. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "DRPLoadingSpinnerTimingFunction.h"
/**
* @brief The set of directions that DRPLoadingSpinner can spin
*/
typedef NS_ENUM(NSInteger, DRPRotationDirection) {
DRPRotationDirectionClockwise,
DRPRotationDirectionCounterClockwise
};
@interface DRPLoadingSpinner : UIView
/**
* @brief Which direction the spinner should spin. Defaults to clockwise.
*/
@property (nonatomic, assign) DRPRotationDirection rotationDirection;
/**
* @brief When the spinner is not animating, the length of the arc to be drawn. This can
* be used to implement things like pull-to-refresh as seen in DRPRefreshControl.
*/
@property (nonatomic, assign) CGFloat staticArcLength;
/**
@brief When the arc is shrinking, how small it should get at a minimum in radians.
*/
@property (assign) CGFloat minimumArcLength;
/**
* @brief When the arc is growing, how large it should get at a maximum in radians
*/
@property (assign) CGFloat maximumArcLength;
/**
* @brief The width of the arc's line.
*/
@property (nonatomic) CGFloat lineWidth;
/**
@brief How long in seconds it should take for the drawing to rotate 360 degrees.
No easing function is applied to this duration, i.e. it is linear.
*/
@property (assign) CFTimeInterval rotationCycleDuration;
/**
@brief How long in seconds it should take for a complete circle to be drawn
or erased. An in-out easing function is applied to this duration.
*/
@property (assign) CFTimeInterval drawCycleDuration;
/**
@brief The timing function that should be used for drawing the rail.
*/
@property (strong) CAMediaTimingFunction *drawTimingFunction;
/**
@brief An array of UIColors that defines the colors the spinner will draw in
and their order. The colors will loop back to the beginning when the
cycle for the last color has been completed.
*/
@property (strong) NSArray<UIColor *> *colorSequence UI_APPEARANCE_SELECTOR;
/**
@brief The color of the rail behind the spinner. Defaults to clear.
*/
@property (nonatomic) UIColor *backgroundRailColor;
/**
@return YES if the spinner is animating, otherwise NO
*/
@property (readonly) BOOL isAnimating;
/**
@brief Start animating.
*/
- (void)startAnimating;
/**
@brief Stop animating and clear the drawing context.
*/
- (void)stopAnimating;
@end
//
// DRPLoadingSpinner.m
// DRPLoadingSpinner
//
// Created by Justin Hill on 11/11/14.
// Copyright (c) 2014 Justin Hill. All rights reserved.
//
#import "DRPLoadingSpinner.h"
#define kInvalidatedTimestamp -1
@interface DRPLoadingSpinner () <CAAnimationDelegate>
@property BOOL isAnimating;
@property NSUInteger colorIndex;
@property CAShapeLayer *foregroundRailLayer;
@property CAShapeLayer *backgroundRailLayer;
@property BOOL isFirstCycle;
@end
@implementation DRPLoadingSpinner
#pragma mark - Life cycle
- (instancetype)init {
if (self = [super initWithFrame:CGRectMake(0, 0, 22, 22)]) {
[self setup];
}
return self;
}
- (void)didMoveToWindow {
[super didMoveToWindow];
if (self.window && self.isAnimating) {
[self startAnimating];
}
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setup];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[self setup];
}
return self;
}
- (void)setup {
self.foregroundRailLayer = [[CAShapeLayer alloc] init];
self.backgroundRailLayer = [[CAShapeLayer alloc] init];
self.rotationDirection = DRPRotationDirectionClockwise;
self.drawCycleDuration = 0.75;
self.rotationCycleDuration = 1.5;
self.staticArcLength = 0;
self.maximumArcLength = (2 * M_PI) - M_PI_4;
self.minimumArcLength = 0.1;
self.lineWidth = 2.;
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];
self.drawTimingFunction = [DRPLoadingSpinnerTimingFunction easeInOut];
self.colorSequence = @[
[UIColor redColor],
[UIColor orangeColor],
[UIColor purpleColor],
[UIColor blueColor]
];
self.backgroundRailLayer.fillColor = [UIColor clearColor].CGColor;
self.backgroundRailLayer.strokeColor = [UIColor clearColor].CGColor;
self.backgroundRailLayer.hidden = YES;
self.foregroundRailLayer.fillColor = [UIColor clearColor].CGColor;
self.foregroundRailLayer.anchorPoint = CGPointMake(.5, .5);
self.foregroundRailLayer.strokeColor = self.colorSequence.firstObject.CGColor;
self.foregroundRailLayer.hidden = YES;
self.backgroundRailLayer.actions = @{
@"lineWidth": [NSNull null],
@"strokeEnd": [NSNull null],
@"strokeStart": [NSNull null],
@"transform": [NSNull null],
@"hidden": [NSNull null]
};
self.foregroundRailLayer.actions = @{
@"lineWidth": [NSNull null],
@"strokeEnd": [NSNull null],
@"strokeStart": [NSNull null],
@"transform": [NSNull null],
@"hidden": [NSNull null]
};
// If we have an apperance specified, then use it to override the defaults.
if(nil != [DRPLoadingSpinner appearance].colorSequence)
{
self.colorSequence = [DRPLoadingSpinner appearance].colorSequence;
}
[self refreshCircleFrame];
}
#pragma mark - Accessors
- (void)setFrame:(CGRect)frame {
[super setFrame:frame];
[self refreshCircleFrame];
// [self insertPlane:self.foregroundRailLayer];
}
- (void)setRotationDirection:(DRPRotationDirection)rotationDirection {
_rotationDirection = rotationDirection;
switch (rotationDirection) {
case DRPRotationDirectionCounterClockwise:
self.layer.affineTransform = CGAffineTransformScale(CGAffineTransformIdentity, -1, 1);
break;
case DRPRotationDirectionClockwise:
default:
self.layer.affineTransform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 1);
break;
}
}
- (void)setStaticArcLength:(CGFloat)staticArcLength {
_staticArcLength = staticArcLength;
if (!self.isAnimating) {
self.foregroundRailLayer.hidden = NO;
self.backgroundRailLayer.hidden = NO;
self.foregroundRailLayer.strokeColor = self.colorSequence.firstObject.CGColor;
self.foregroundRailLayer.strokeStart = 0;
self.foregroundRailLayer.strokeEnd = [self proportionFromArcLengthRadians:staticArcLength];
self.foregroundRailLayer.transform = CATransform3DRotate(CATransform3DIdentity, -M_PI_2, 0, 0, 1);
}
}
- (void)setLineWidth:(CGFloat)lineWidth {
self.foregroundRailLayer.lineWidth = lineWidth;
self.backgroundRailLayer.lineWidth = lineWidth;
}
- (CGFloat)lineWidth {
return self.foregroundRailLayer.lineWidth;
}
- (void)setBackgroundRailColor:(UIColor *)backgroundRailColor {
self.backgroundRailLayer.strokeColor = backgroundRailColor.CGColor;
}
- (UIColor *)backgroundRailColor {
return [UIColor colorWithCGColor:self.backgroundRailLayer.strokeColor];
}
#pragma mark - Layout
//- (void)insertPlane:(CALayer *)layer {
// [layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
//
// CALayer *top = [[CALayer alloc] init];
// top.backgroundColor = UIColor.cyanColor.CGColor;
// top.frame = CGRectMake(layer.frame.size.width/2, 0, 1, layer.frame.size.height/2);
// [layer addSublayer:top];
//
// CALayer *bottom = [[CALayer alloc] init];
// bottom.backgroundColor = UIColor.magentaColor.CGColor;
// bottom.frame = CGRectMake(layer.frame.size.width/2, layer.frame.size.height/2, 1, layer.frame.size.height/2);
// [layer addSublayer:bottom];
//
// CALayer *left = [[CALayer alloc] init];
// left.backgroundColor = UIColor.yellowColor.CGColor;
// left.frame = CGRectMake(0, layer.frame.size.height/2, layer.frame.size.width/2, 1);
// [layer addSublayer:left];
//
// CALayer *right = [[CALayer alloc] init];
// right.backgroundColor = UIColor.blackColor.CGColor;
// right.frame = CGRectMake(layer.frame.size.width/2, layer.frame.size.height/2, layer.frame.size.width/2, 1);
// [layer addSublayer:right];
//}
- (void)refreshCircleFrame {
CGFloat sideLen = MIN(self.layer.frame.size.width, self.layer.frame.size.height) - (2 * self.lineWidth);
CGFloat xOffset = ceilf((self.frame.size.width - sideLen) / 2.0);
CGFloat yOffset = ceilf((self.frame.size.height - sideLen) / 2.0);
self.foregroundRailLayer.frame = CGRectMake(xOffset, yOffset, sideLen, sideLen);
self.foregroundRailLayer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, sideLen, sideLen)].CGPath;
self.backgroundRailLayer.frame = CGRectMake(xOffset, yOffset, sideLen, sideLen);
self.backgroundRailLayer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, sideLen, sideLen)].CGPath;
}
- (void)layoutSublayersOfLayer:(CALayer *)layer {
[super layoutSublayersOfLayer:layer];
if (!self.backgroundRailLayer.superlayer) {
[self.layer addSublayer:self.backgroundRailLayer];
}
if (!self.foregroundRailLayer.superlayer) {
[self.layer addSublayer:self.foregroundRailLayer];
}
}
#pragma mark - Animation control
- (void)startAnimating {
[self stopAnimating];
self.foregroundRailLayer.hidden = NO;
self.backgroundRailLayer.hidden = NO;
self.isAnimating = YES;
self.isFirstCycle = YES;
self.foregroundRailLayer.strokeEnd = [self proportionFromArcLengthRadians:self.minimumArcLength];
self.colorIndex = 0;
self.foregroundRailLayer.strokeColor = [self.colorSequence[self.colorIndex] CGColor];
[self addAnimationsToLayer:self.foregroundRailLayer reverse:NO rotationOffset:-M_PI_2];
}
- (void)stopAnimating {
self.isAnimating = NO;
self.foregroundRailLayer.hidden = YES;
self.backgroundRailLayer.hidden = YES;
[self.foregroundRailLayer removeAllAnimations];
}
#pragma mark - Auto Layout
- (CGSize)intrinsicContentSize {
return CGSizeMake(40, 40);
}
#pragma mark
- (void)addAnimationsToLayer:(CAShapeLayer *)layer reverse:(BOOL)reverse rotationOffset:(CGFloat)rotationOffset {
CABasicAnimation *strokeAnimation;
CGFloat strokeDuration = self.drawCycleDuration;
CGFloat currentDistanceToStrokeStart = 2 * M_PI * layer.strokeStart;
if (reverse) {
[CATransaction begin];
strokeAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
CGFloat newStrokeStart = self.maximumArcLength - self.minimumArcLength;
layer.strokeEnd = [self proportionFromArcLengthRadians:self.maximumArcLength];
layer.strokeStart = [self proportionFromArcLengthRadians:newStrokeStart];
strokeAnimation.fromValue = @(0);
strokeAnimation.toValue = @([self proportionFromArcLengthRadians:newStrokeStart]);
} else {
CGFloat strokeFromValue = self.minimumArcLength;
CGFloat rotationStartRadians = rotationOffset;
if (self.isFirstCycle) {
if (self.staticArcLength > 0) {
if (self.staticArcLength > self.maximumArcLength) {
NSLog(@"DRPLoadingSpinner: staticArcLength is set to a value greater than maximumArcLength. You probably didn't mean to do this.");
}
strokeFromValue = self.staticArcLength;
strokeDuration *= (self.staticArcLength / self.maximumArcLength);
}
self.isFirstCycle = NO;
} else {
rotationStartRadians += currentDistanceToStrokeStart;
}
CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.fromValue = @(rotationStartRadians);
rotationAnimation.toValue = @(rotationStartRadians + (2 * M_PI));
rotationAnimation.timingFunction = [DRPLoadingSpinnerTimingFunction linear];
rotationAnimation.duration = self.rotationCycleDuration;
rotationAnimation.repeatCount = HUGE_VALF;
rotationAnimation.fillMode = kCAFillModeForwards;
[layer removeAnimationForKey:@"rotation"];
[layer addAnimation:rotationAnimation forKey:@"rotation"];
[CATransaction begin];
strokeAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
strokeAnimation.fromValue = @([self proportionFromArcLengthRadians:strokeFromValue]);
strokeAnimation.toValue = @([self proportionFromArcLengthRadians:self.maximumArcLength]);
layer.strokeStart = 0;
layer.strokeEnd = [strokeAnimation.toValue doubleValue];
}
strokeAnimation.delegate = self;
strokeAnimation.fillMode = kCAFillModeForwards;
strokeAnimation.timingFunction = self.drawTimingFunction;
[CATransaction setAnimationDuration:strokeDuration];
[layer removeAnimationForKey:@"stroke"];
[layer addAnimation:strokeAnimation forKey:@"stroke"];
[CATransaction commit];
}
- (void)advanceColorSequence {
self.colorIndex = (self.colorIndex + 1) % self.colorSequence.count;
self.foregroundRailLayer.strokeColor = [self.colorSequence[self.colorIndex] CGColor];
}
- (CGFloat)proportionFromArcLengthRadians:(CGFloat)radians {
return ((fmodf(radians, 2 * M_PI)) / (2 * M_PI));
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)finished {
if (finished && [anim isKindOfClass:[CABasicAnimation class]]) {
CABasicAnimation *basicAnim = (CABasicAnimation *)anim;
BOOL isStrokeStart = [basicAnim.keyPath isEqualToString:@"strokeStart"];
BOOL isStrokeEnd = [basicAnim.keyPath isEqualToString:@"strokeEnd"];
CGFloat rotationOffset = fmodf([[self.foregroundRailLayer.presentationLayer valueForKeyPath:@"transform.rotation.z"] floatValue], 2 * M_PI);
[self addAnimationsToLayer:self.foregroundRailLayer reverse:isStrokeEnd rotationOffset:rotationOffset];
if (isStrokeStart) {
[self advanceColorSequence];
}
}
}
@end
//
// DRPLoadingSpinnerTimingFunction.h
// DRPLoadingSpinner
//
// Created by Justin Hill on 3/21/17.
// Copyright © 2017 Justin Hill. All rights reserved.
//
@import UIKit;
@interface DRPLoadingSpinnerTimingFunction : NSObject
+ (CAMediaTimingFunction *)linear;
+ (CAMediaTimingFunction *)easeIn;
+ (CAMediaTimingFunction *)easeOut;
+ (CAMediaTimingFunction *)easeInOut;
+ (CAMediaTimingFunction *)sharpEaseInOut;
@end
//
// DRPLoadingSpinnerTimingFunction.m
// DRPLoadingSpinner
//
// Created by Justin Hill on 3/21/17.
// Copyright © 2017 Justin Hill. All rights reserved.
//
#import "DRPLoadingSpinnerTimingFunction.h"
@implementation DRPLoadingSpinnerTimingFunction
+ (CAMediaTimingFunction *)linear {
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
}
+ (CAMediaTimingFunction *)easeIn {
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
}
+ (CAMediaTimingFunction *)easeOut {
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
}
+ (CAMediaTimingFunction *)easeInOut {
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
}
+ (CAMediaTimingFunction *)sharpEaseInOut {
return [CAMediaTimingFunction functionWithControlPoints:0.62 :0.0 :0.38 :1.0];
}
@end
//
// MBProgressHUD+XW.h
// handehrms
//
// Created by xiaowei on 16/9/20.
// Copyright © 2016年 xiaowei. All rights reserved.
//
#import "MBProgressHUD.h"
@interface MBProgressHUD (XW)
+ (void)showSuccess:(NSString *)success view:(UIView *)view;
+ (void)showError:(NSString *)error view:(UIView *)view;
+ (void)showError:(NSString *)error;
+ (void)showSuccess:(NSString *)success;
+ (void)showRequestLoad:(NSString *)text toView:(UIView *)toview;
+ (void)hideRequestLoad:(UIView *)view;
+ (void)showInterminateWithView:(UIView *)view;
+ (void)showNoOffset:(NSString *)text toView:(UIView *)toview;
+ (void)customShowLoading:(UIView *)view;
@end
//
// MBProgressHUD+XW.m
// handehrms
//
// Created by xiaowei on 16/9/20.
// Copyright © 2016年 xiaowei. All rights reserved.
//
#import "MBProgressHUD+XW.h"
#import "DRPLoadingSpinner.h"
@implementation MBProgressHUD (XW)
+ (void)show:(NSString *)text image:(NSString *)img toView:(UIView *)toView{
if(toView == nil){
toView = [[[UIApplication sharedApplication] windows] lastObject];
}
dispatch_async(dispatch_get_main_queue(), ^{
MBProgressHUD *hub = [MBProgressHUD showHUDAddedTo:toView animated:YES];
//配置
hub.label.text = text;
hub.customView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:img]];
hub.mode = MBProgressHUDModeCustomView;
hub.animationType = MBProgressHUDAnimationZoomOut;
hub.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
hub.bezelView.backgroundColor = [UIColor colorWithWhite:.1 alpha:.9];
hub.label.textColor = [UIColor whiteColor];
hub.removeFromSuperViewOnHide = YES;
//设置蒙版效果
// hub.dimBackground = YES;
//设置隐藏的时间
[hub hideAnimated:YES afterDelay:1.2];
});
}
+ (void)showSuccess:(NSString *)success{
[self show:success image:@"progress_success" toView:nil];
}
+ (void)showError:(NSString *)error{
[self show:error image:@"progress_error" toView:nil];
}
+ (void)showSuccess:(NSString *)success view:(UIView *)view{
[self show:success image:@"progress_success" toView:view];
}
+ (void)showError:(NSString *)error view:(UIView *)view{
[self show:error image:@"progress_error" toView:view];
}
+ (void)showRequestLoad:(NSString *)text toView:(UIView *)toview{
if(toview == nil){
UIViewController *ctrl = [self getTopViewControllerWithCtrl:nil];
if(ctrl){
toview = ctrl.presentedViewController ? ctrl.presentedViewController.view : ctrl.view;
}else{
NSArray *list = [[UIApplication sharedApplication] windows];
if(![NSStringFromClass([[list lastObject] class]) isEqualToString:@"UITextEffectsWindow"]){
for (UIView *v in list) {
if([NSStringFromClass([v class]) isEqualToString:@"UITextEffectsWindow"]){
toview = v;
}
}
if(toview == nil){
toview = [list lastObject];
}
}else{
toview = [list lastObject];
}
}
}
dispatch_async(dispatch_get_main_queue(), ^{
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:toview animated:YES];
// Set the custom view mode to show any view.
hud.mode = MBProgressHUDModeCustomView;
DRPLoadingSpinner *loadingView = [[DRPLoadingSpinner alloc] init];
loadingView.colorSequence = @[[UIColor colorWithRed:210/255.0 green:210/255.0 blue:210/255.0 alpha:1]];
[loadingView startAnimating];
hud.customView = loadingView;
// hud.offset = CGPointMake(0, -64);
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
hud.bezelView.backgroundColor = [UIColor clearColor];
if(text){
hud.backgroundColor = [UIColor clearColor];
}else{
hud.backgroundColor = [UIColor whiteColor];
}
hud.animationType = MBProgressHUDAnimationZoom;
[hud setRemoveFromSuperViewOnHide:YES];
});
}
//获取当前显示的控制器
+ (UIViewController *)getTopViewControllerWithCtrl:(UIViewController *)vc{
UIViewController *current;
if(vc == nil){
vc = [UIApplication sharedApplication].keyWindow.rootViewController;
}
if([vc isKindOfClass:[UITabBarController class]]){
return [self getTopViewControllerWithCtrl:[(UITabBarController *)vc selectedViewController]];
}else if ([vc isKindOfClass:[UINavigationController class]]){
return [self getTopViewControllerWithCtrl:[(UINavigationController *)vc visibleViewController]];
}else{
current = vc;
}
return current;
}
+ (void)showNoOffset:(NSString *)text toView:(UIView *)toview{
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:toview animated:YES];
// Set the custom view mode to show any view.
hud.mode = MBProgressHUDModeCustomView;
NSMutableArray *animationList = [NSMutableArray array];
for (NSInteger i=0; i<47; i++) {
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"custom_000%02ld",i+1]];
[animationList addObject:image];
}
UIImageView *imgView = [[UIImageView alloc] init];
imgView.animationImages = animationList;
imgView.animationDuration = 0.8;
[imgView startAnimating];
hud.customView = imgView;
// hud.customView.layer.cornerRadius = 25;
// hud.customView.layer.masksToBounds = YES;
hud.offset = CGPointMake(0, -64);
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
hud.bezelView.backgroundColor = [UIColor clearColor];
hud.backgroundColor = [UIColor whiteColor];
hud.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
hud.animationType = MBProgressHUDAnimationZoomIn;
// [hud hideAnimated:YES afterDelay:5.f];
[hud setRemoveFromSuperViewOnHide:YES];
}
+ (void)showInterminateWithView:(UIView *)view{
if(view == nil){
view = [[[UIApplication sharedApplication]windows] lastObject];
}
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
hud.bezelView.backgroundColor = [UIColor clearColor];
}
+ (void)hideRequestLoad:(UIView *)view{
if(view == nil){
UIViewController *ctrl = [self getTopViewControllerWithCtrl:nil];
if(ctrl){
view = ctrl.presentedViewController ? ctrl.presentedViewController.view : ctrl.view;
}else{
NSArray *list = [[UIApplication sharedApplication] windows];
if(![NSStringFromClass([[list lastObject] class]) isEqualToString:@"UITextEffectsWindow"]){
for (UIView *v in list) {
if([NSStringFromClass([v class]) isEqualToString:@"UITextEffectsWindow"]){
view = v;
}
}
if(view == nil){
view = [list lastObject];
}
}else{
view = [list lastObject];
}
}
}
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:view animated:YES];
});
}
+ (void)customShowLoading:(UIView *)view {
if(view == nil){
UIViewController *ctrl = [self getTopViewControllerWithCtrl:nil];
if(ctrl){
view = ctrl.presentedViewController ? ctrl.presentedViewController.view : ctrl.view;
}else{
NSArray *list = [[UIApplication sharedApplication] windows];
if(![NSStringFromClass([[list lastObject] class]) isEqualToString:@"UITextEffectsWindow"]){
for (UIView *v in list) {
if([NSStringFromClass([v class]) isEqualToString:@"UITextEffectsWindow"]){
view = v;
}
}
if(view == nil){
view = [list lastObject];
}
}else{
view = [list lastObject];
}
}
}
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
// Set the custom view mode to show any view.
hud.mode = MBProgressHUDModeCustomView;
NSMutableArray *animationList = [NSMutableArray array];
for (NSInteger i=0; i<47; i++) {
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"custom_000%02ld",i+1]];
[animationList addObject:image];
}
UIImageView *imgView = [[UIImageView alloc] init];
imgView.animationImages = animationList;
imgView.animationDuration = 0.8;
[imgView startAnimating];
hud.customView = imgView;
hud.offset = CGPointMake(0, -64);
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
hud.bezelView.backgroundColor = [UIColor clearColor];
hud.backgroundColor = [UIColor whiteColor];
hud.animationType = MBProgressHUDAnimationZoom;
[hud setRemoveFromSuperViewOnHide:YES];
}
@end
//
// MBProgressHUD.h
// Version 1.0.0
// Created by Matej Bukovinski on 2.4.09.
//
// This code is distributed under the terms and conditions of the MIT license.
// Copyright © 2009-2016 Matej Bukovinski
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <CoreGraphics/CoreGraphics.h>
@class MBBackgroundView;
@protocol MBProgressHUDDelegate;
extern CGFloat const MBProgressMaxOffset;
typedef NS_ENUM(NSInteger, MBProgressHUDMode) {
/// UIActivityIndicatorView.
MBProgressHUDModeIndeterminate,
/// A round, pie-chart like, progress view.
MBProgressHUDModeDeterminate,
/// Horizontal progress bar.
MBProgressHUDModeDeterminateHorizontalBar,
/// Ring-shaped progress view.
MBProgressHUDModeAnnularDeterminate,
/// Shows a custom view.
MBProgressHUDModeCustomView,
/// Shows only labels.
MBProgressHUDModeText
};
typedef NS_ENUM(NSInteger, MBProgressHUDAnimation) {
/// Opacity animation
MBProgressHUDAnimationFade,
/// Opacity + scale animation (zoom in when appearing zoom out when disappearing)
MBProgressHUDAnimationZoom,
/// Opacity + scale animation (zoom out style)
MBProgressHUDAnimationZoomOut,
/// Opacity + scale animation (zoom in style)
MBProgressHUDAnimationZoomIn
};
typedef NS_ENUM(NSInteger, MBProgressHUDBackgroundStyle) {
/// Solid color background
MBProgressHUDBackgroundStyleSolidColor,
/// UIVisualEffectView or UIToolbar.layer background view
MBProgressHUDBackgroundStyleBlur
};
typedef void (^MBProgressHUDCompletionBlock)();
NS_ASSUME_NONNULL_BEGIN
/**
* Displays a simple HUD window containing a progress indicator and two optional labels for short messages.
*
* This is a simple drop-in class for displaying a progress HUD view similar to Apple's private UIProgressHUD class.
* The MBProgressHUD window spans over the entire space given to it by the initWithFrame: constructor and catches all
* user input on this region, thereby preventing the user operations on components below the view.
*
* @note To still allow touches to pass through the HUD, you can set hud.userInteractionEnabled = NO.
* @attention MBProgressHUD is a UI class and should therefore only be accessed on the main thread.
*/
@interface MBProgressHUD : UIView
/**
* Creates a new HUD, adds it to provided view and shows it. The counterpart to this method is hideHUDForView:animated:.
*
* @note This method sets removeFromSuperViewOnHide. The HUD will automatically be removed from the view hierarchy when hidden.
*
* @param view The view that the HUD will be added to
* @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use
* animations while appearing.
* @return A reference to the created HUD.
*
* @see hideHUDForView:animated:
* @see animationType
*/
+ (instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated;
/// @name Showing and hiding
/**
* Finds the top-most HUD subview and hides it. The counterpart to this method is showHUDAddedTo:animated:.
*
* @note This method sets removeFromSuperViewOnHide. The HUD will automatically be removed from the view hierarchy when hidden.
*
* @param view The view that is going to be searched for a HUD subview.
* @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
* animations while disappearing.
* @return YES if a HUD was found and removed, NO otherwise.
*
* @see showHUDAddedTo:animated:
* @see animationType
*/
+ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated;
/**
* Finds the top-most HUD subview and returns it.
*
* @param view The view that is going to be searched.
* @return A reference to the last HUD subview discovered.
*/
+ (nullable MBProgressHUD *)HUDForView:(UIView *)view;
/**
* A convenience constructor that initializes the HUD with the view's bounds. Calls the designated constructor with
* view.bounds as the parameter.
*
* @param view The view instance that will provide the bounds for the HUD. Should be the same instance as
* the HUD's superview (i.e., the view that the HUD will be added to).
*/
- (instancetype)initWithView:(UIView *)view;
/**
* Displays the HUD.
*
* @note You need to make sure that the main thread completes its run loop soon after this method call so that
* the user interface can be updated. Call this method when your task is already set up to be executed in a new thread
* (e.g., when using something like NSOperation or making an asynchronous call like NSURLRequest).
*
* @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use
* animations while appearing.
*
* @see animationType
*/
- (void)showAnimated:(BOOL)animated;
/**
* Hides the HUD. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to
* hide the HUD when your task completes.
*
* @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
* animations while disappearing.
*
* @see animationType
*/
- (void)hideAnimated:(BOOL)animated;
/**
* Hides the HUD after a delay. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to
* hide the HUD when your task completes.
*
* @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
* animations while disappearing.
* @param delay Delay in seconds until the HUD is hidden.
*
* @see animationType
*/
- (void)hideAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay;
/**
* The HUD delegate object. Receives HUD state notifications.
*/
@property (weak, nonatomic) id<MBProgressHUDDelegate> delegate;
/**
* Called after the HUD is hiden.
*/
@property (copy, nullable) MBProgressHUDCompletionBlock completionBlock;
/*
* Grace period is the time (in seconds) that the invoked method may be run without
* showing the HUD. If the task finishes before the grace time runs out, the HUD will
* not be shown at all.
* This may be used to prevent HUD display for very short tasks.
* Defaults to 0 (no grace time).
*/
@property (assign, nonatomic) NSTimeInterval graceTime;
/**
* The minimum time (in seconds) that the HUD is shown.
* This avoids the problem of the HUD being shown and than instantly hidden.
* Defaults to 0 (no minimum show time).
*/
@property (assign, nonatomic) NSTimeInterval minShowTime;
/**
* Removes the HUD from its parent view when hidden.
* Defaults to NO.
*/
@property (assign, nonatomic) BOOL removeFromSuperViewOnHide;
/// @name Appearance
/**
* MBProgressHUD operation mode. The default is MBProgressHUDModeIndeterminate.
*/
@property (assign, nonatomic) MBProgressHUDMode mode;
/**
* A color that gets forwarded to all labels and supported indicators. Also sets the tintColor
* for custom views on iOS 7+. Set to nil to manage color individually.
* Defaults to semi-translucent black on iOS 7 and later and white on earlier iOS versions.
*/
@property (strong, nonatomic, nullable) UIColor *contentColor UI_APPEARANCE_SELECTOR;
/**
* The animation type that should be used when the HUD is shown and hidden.
*/
@property (assign, nonatomic) MBProgressHUDAnimation animationType UI_APPEARANCE_SELECTOR;
/**
* The bezel offset relative to the center of the view. You can use MBProgressMaxOffset
* and -MBProgressMaxOffset to move the HUD all the way to the screen edge in each direction.
* E.g., CGPointMake(0.f, MBProgressMaxOffset) would position the HUD centered on the bottom edge.
*/
@property (assign, nonatomic) CGPoint offset UI_APPEARANCE_SELECTOR;
/**
* The amount of space between the HUD edge and the HUD elements (labels, indicators or custom views).
* This also represents the minimum bezel distance to the edge of the HUD view.
* Defaults to 20.f
*/
@property (assign, nonatomic) CGFloat margin UI_APPEARANCE_SELECTOR;
/**
* The minimum size of the HUD bezel. Defaults to CGSizeZero (no minimum size).
*/
@property (assign, nonatomic) CGSize minSize UI_APPEARANCE_SELECTOR;
/**
* Force the HUD dimensions to be equal if possible.
*/
@property (assign, nonatomic, getter = isSquare) BOOL square UI_APPEARANCE_SELECTOR;
/**
* When enabled, the bezel center gets slightly affected by the device accelerometer data.
* Has no effect on iOS < 7.0. Defaults to YES.
*/
@property (assign, nonatomic, getter=areDefaultMotionEffectsEnabled) BOOL defaultMotionEffectsEnabled UI_APPEARANCE_SELECTOR;
/// @name Progress
/**
* The progress of the progress indicator, from 0.0 to 1.0. Defaults to 0.0.
*/
@property (assign, nonatomic) float progress;
/// @name ProgressObject
/**
* The NSProgress object feeding the progress information to the progress indicator.
*/
@property (strong, nonatomic, nullable) NSProgress *progressObject;
/// @name Views
/**
* The view containing the labels and indicator (or customView).
*/
@property (strong, nonatomic, readonly) MBBackgroundView *bezelView;
/**
* View covering the entire HUD area, placed behind bezelView.
*/
@property (strong, nonatomic, readonly) MBBackgroundView *backgroundView;
/**
* The UIView (e.g., a UIImageView) to be shown when the HUD is in MBProgressHUDModeCustomView.
* The view should implement intrinsicContentSize for proper sizing. For best results use approximately 37 by 37 pixels.
*/
@property (strong, nonatomic, nullable) UIView *customView;
/**
* A label that holds an optional short message to be displayed below the activity indicator. The HUD is automatically resized to fit
* the entire text.
*/
@property (strong, nonatomic, readonly) UILabel *label;
/**
* A label that holds an optional details message displayed below the labelText message. The details text can span multiple lines.
*/
@property (strong, nonatomic, readonly) UILabel *detailsLabel;
/**
* A button that is placed below the labels. Visible only if a target / action is added.
*/
@property (strong, nonatomic, readonly) UIButton *button;
@end
@protocol MBProgressHUDDelegate <NSObject>
@optional
/**
* Called after the HUD was fully hidden from the screen.
*/
- (void)hudWasHidden:(MBProgressHUD *)hud;
@end
/**
* A progress view for showing definite progress by filling up a circle (pie chart).
*/
@interface MBRoundProgressView : UIView
/**
* Progress (0.0 to 1.0)
*/
@property (nonatomic, assign) float progress;
/**
* Indicator progress color.
* Defaults to white [UIColor whiteColor].
*/
@property (nonatomic, strong) UIColor *progressTintColor;
/**
* Indicator background (non-progress) color.
* Only applicable on iOS versions older than iOS 7.
* Defaults to translucent white (alpha 0.1).
*/
@property (nonatomic, strong) UIColor *backgroundTintColor;
/*
* Display mode - NO = round or YES = annular. Defaults to round.
*/
@property (nonatomic, assign, getter = isAnnular) BOOL annular;
@end
/**
* A flat bar progress view.
*/
@interface MBBarProgressView : UIView
/**
* Progress (0.0 to 1.0)
*/
@property (nonatomic, assign) float progress;
/**
* Bar border line color.
* Defaults to white [UIColor whiteColor].
*/
@property (nonatomic, strong) UIColor *lineColor;
/**
* Bar background color.
* Defaults to clear [UIColor clearColor];
*/
@property (nonatomic, strong) UIColor *progressRemainingColor;
/**
* Bar progress color.
* Defaults to white [UIColor whiteColor].
*/
@property (nonatomic, strong) UIColor *progressColor;
@end
@interface MBBackgroundView : UIView
/**
* The background style.
* Defaults to MBProgressHUDBackgroundStyleBlur on iOS 7 or later and MBProgressHUDBackgroundStyleSolidColor otherwise.
* @note Due to iOS 7 not supporting UIVisualEffectView, the blur effect differs slightly between iOS 7 and later versions.
*/
@property (nonatomic) MBProgressHUDBackgroundStyle style;
/**
* The background color or the blur tint color.
* @note Due to iOS 7 not supporting UIVisualEffectView, the blur effect differs slightly between iOS 7 and later versions.
*/
@property (nonatomic, strong) UIColor *color;
@end
@interface MBProgressHUD (Deprecated)
+ (NSArray *)allHUDsForView:(UIView *)view __attribute__((deprecated("Store references when using more than one HUD per view.")));
+ (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated __attribute__((deprecated("Store references when using more than one HUD per view.")));
- (id)initWithWindow:(UIWindow *)window __attribute__((deprecated("Use initWithView: instead.")));
- (void)show:(BOOL)animated __attribute__((deprecated("Use showAnimated: instead.")));
- (void)hide:(BOOL)animated __attribute__((deprecated("Use hideAnimated: instead.")));
- (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay __attribute__((deprecated("Use hideAnimated:afterDelay: instead.")));
- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated __attribute__((deprecated("Use GCD directly.")));
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block __attribute__((deprecated("Use GCD directly.")));
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(nullable MBProgressHUDCompletionBlock)completion __attribute__((deprecated("Use GCD directly.")));
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue __attribute__((deprecated("Use GCD directly.")));
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue
completionBlock:(nullable MBProgressHUDCompletionBlock)completion __attribute__((deprecated("Use GCD directly.")));
@property (assign) BOOL taskInProgress __attribute__((deprecated("No longer needed.")));
@property (nonatomic, copy) NSString *labelText __attribute__((deprecated("Use label.text instead.")));
@property (nonatomic, strong) UIFont *labelFont __attribute__((deprecated("Use label.font instead.")));
@property (nonatomic, strong) UIColor *labelColor __attribute__((deprecated("Use label.textColor instead.")));
@property (nonatomic, copy) NSString *detailsLabelText __attribute__((deprecated("Use detailsLabel.text instead.")));
@property (nonatomic, strong) UIFont *detailsLabelFont __attribute__((deprecated("Use detailsLabel.font instead.")));
@property (nonatomic, strong) UIColor *detailsLabelColor __attribute__((deprecated("Use detailsLabel.textColor instead.")));
@property (assign, nonatomic) CGFloat opacity __attribute__((deprecated("Customize bezelView properties instead.")));
@property (strong, nonatomic) UIColor *color __attribute__((deprecated("Customize the bezelView color instead.")));
@property (assign, nonatomic) CGFloat xOffset __attribute__((deprecated("Set offset.x instead.")));
@property (assign, nonatomic) CGFloat yOffset __attribute__((deprecated("Set offset.y instead.")));
@property (assign, nonatomic) CGFloat cornerRadius __attribute__((deprecated("Set bezelView.layer.cornerRadius instead.")));
@property (assign, nonatomic) BOOL dimBackground __attribute__((deprecated("Customize HUD background properties instead.")));
@property (strong, nonatomic) UIColor *activityIndicatorColor __attribute__((deprecated("Use UIAppearance to customize UIActivityIndicatorView. E.g.: [UIActivityIndicatorView appearanceWhenContainedIn:[MBProgressHUD class], nil].color = [UIColor redColor];")));
@property (atomic, assign, readonly) CGSize size __attribute__((deprecated("Get the bezelView.frame.size instead.")));
@end
NS_ASSUME_NONNULL_END
//
// MBProgressHUD.m
// Version 1.0.0
// Created by Matej Bukovinski on 2.4.09.
//
#import "MBProgressHUD.h"
#import <tgmath.h>
#ifndef kCFCoreFoundationVersionNumber_iOS_7_0
#define kCFCoreFoundationVersionNumber_iOS_7_0 847.20
#endif
#ifndef kCFCoreFoundationVersionNumber_iOS_8_0
#define kCFCoreFoundationVersionNumber_iOS_8_0 1129.15
#endif
#define MBMainThreadAssert() NSAssert([NSThread isMainThread], @"MBProgressHUD needs to be accessed on the main thread.");
CGFloat const MBProgressMaxOffset = 1000000.f;
static const CGFloat MBDefaultPadding = 4.f;
static const CGFloat MBDefaultLabelFontSize = 16.f;
static const CGFloat MBDefaultDetailsLabelFontSize = 12.f;
@interface MBProgressHUD () {
// Deprecated
UIColor *_activityIndicatorColor;
CGFloat _opacity;
}
@property (nonatomic, assign) BOOL useAnimation;
@property (nonatomic, assign, getter=hasFinished) BOOL finished;
@property (nonatomic, strong) UIView *indicator;
@property (nonatomic, strong) NSDate *showStarted;
@property (nonatomic, strong) NSArray *paddingConstraints;
@property (nonatomic, strong) NSArray *bezelConstraints;
@property (nonatomic, strong) UIView *topSpacer;
@property (nonatomic, strong) UIView *bottomSpacer;
@property (nonatomic, weak) NSTimer *graceTimer;
@property (nonatomic, weak) NSTimer *minShowTimer;
@property (nonatomic, weak) NSTimer *hideDelayTimer;
@property (nonatomic, weak) CADisplayLink *progressObjectDisplayLink;
// Deprecated
@property (assign) BOOL taskInProgress;
@end
@interface MBProgressHUDRoundedButton : UIButton
@end
@implementation MBProgressHUD
#pragma mark - Class methods
+ (instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated {
MBProgressHUD *hud = [[self alloc] initWithView:view];
hud.removeFromSuperViewOnHide = YES;
[view addSubview:hud];
[hud showAnimated:animated];
return hud;
}
+ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated {
MBProgressHUD *hud = [self HUDForView:view];
if (hud != nil) {
hud.removeFromSuperViewOnHide = YES;
[hud hideAnimated:animated];
return YES;
}
return NO;
}
+ (MBProgressHUD *)HUDForView:(UIView *)view {
NSEnumerator *subviewsEnum = [view.subviews reverseObjectEnumerator];
for (UIView *subview in subviewsEnum) {
if ([subview isKindOfClass:self]) {
return (MBProgressHUD *)subview;
}
}
return nil;
}
#pragma mark - Lifecycle
- (void)commonInit {
// Set default values for properties
_animationType = MBProgressHUDAnimationFade;
_mode = MBProgressHUDModeIndeterminate;
_margin = 20.0f;
_opacity = 1.f;
_defaultMotionEffectsEnabled = YES;
// Default color, depending on the current iOS version
BOOL isLegacy = kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0;
_contentColor = isLegacy ? [UIColor whiteColor] : [UIColor colorWithWhite:0.f alpha:0.7f];
// Transparent background
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];
// Make it invisible for now
self.alpha = 0.0f;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.layer.allowsGroupOpacity = NO;
[self setupViews];
[self updateIndicators];
[self registerForNotifications];
}
- (instancetype)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
[self commonInit];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
[self commonInit];
}
return self;
}
- (id)initWithView:(UIView *)view {
NSAssert(view, @"View must not be nil.");
return [self initWithFrame:view.bounds];
}
- (void)dealloc {
[self unregisterFromNotifications];
}
#pragma mark - Show & hide
- (void)showAnimated:(BOOL)animated {
MBMainThreadAssert();
[self.minShowTimer invalidate];
self.useAnimation = animated;
self.finished = NO;
// If the grace time is set, postpone the HUD display
if (self.graceTime > 0.0) {
NSTimer *timer = [NSTimer timerWithTimeInterval:self.graceTime target:self selector:@selector(handleGraceTimer:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
self.graceTimer = timer;
}
// ... otherwise show the HUD immediately
else {
[self showUsingAnimation:self.useAnimation];
}
}
- (void)hideAnimated:(BOOL)animated {
MBMainThreadAssert();
[self.graceTimer invalidate];
self.useAnimation = animated;
self.finished = YES;
// If the minShow time is set, calculate how long the HUD was shown,
// and postpone the hiding operation if necessary
if (self.minShowTime > 0.0 && self.showStarted) {
NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:self.showStarted];
if (interv < self.minShowTime) {
NSTimer *timer = [NSTimer timerWithTimeInterval:(self.minShowTime - interv) target:self selector:@selector(handleMinShowTimer:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
self.minShowTimer = timer;
return;
}
}
// ... otherwise hide the HUD immediately
[self hideUsingAnimation:self.useAnimation];
}
- (void)hideAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay {
NSTimer *timer = [NSTimer timerWithTimeInterval:delay target:self selector:@selector(handleHideTimer:) userInfo:@(animated) repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
self.hideDelayTimer = timer;
}
#pragma mark - Timer callbacks
- (void)handleGraceTimer:(NSTimer *)theTimer {
// Show the HUD only if the task is still running
if (!self.hasFinished) {
[self showUsingAnimation:self.useAnimation];
}
}
- (void)handleMinShowTimer:(NSTimer *)theTimer {
[self hideUsingAnimation:self.useAnimation];
}
- (void)handleHideTimer:(NSTimer *)timer {
[self hideAnimated:[timer.userInfo boolValue]];
}
#pragma mark - View Hierrarchy
- (void)didMoveToSuperview {
[self updateForCurrentOrientationAnimated:NO];
}
#pragma mark - Internal show & hide operations
- (void)showUsingAnimation:(BOOL)animated {
// Cancel any previous animations
[self.bezelView.layer removeAllAnimations];
[self.backgroundView.layer removeAllAnimations];
// Cancel any scheduled hideDelayed: calls
[self.hideDelayTimer invalidate];
self.showStarted = [NSDate date];
self.alpha = 1.f;
// Needed in case we hide and re-show with the same NSProgress object attached.
[self setNSProgressDisplayLinkEnabled:YES];
if (animated) {
[self animateIn:YES withType:self.animationType completion:NULL];
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
self.bezelView.alpha = self.opacity;
#pragma clang diagnostic pop
self.backgroundView.alpha = 1.f;
}
}
- (void)hideUsingAnimation:(BOOL)animated {
if (animated && self.showStarted) {
self.showStarted = nil;
[self animateIn:NO withType:self.animationType completion:^(BOOL finished) {
[self done];
}];
} else {
self.showStarted = nil;
self.bezelView.alpha = 0.f;
self.backgroundView.alpha = 1.f;
[self done];
}
}
- (void)animateIn:(BOOL)animatingIn withType:(MBProgressHUDAnimation)type completion:(void(^)(BOOL finished))completion {
// Automatically determine the correct zoom animation type
if (type == MBProgressHUDAnimationZoom) {
type = animatingIn ? MBProgressHUDAnimationZoomIn : MBProgressHUDAnimationZoomOut;
}
CGAffineTransform small = CGAffineTransformMakeScale(0.5f, 0.5f);
CGAffineTransform large = CGAffineTransformMakeScale(1.5f, 1.5f);
// Set starting state
UIView *bezelView = self.bezelView;
if (animatingIn && bezelView.alpha == 0.f && type == MBProgressHUDAnimationZoomIn) {
bezelView.transform = small;
} else if (animatingIn && bezelView.alpha == 0.f && type == MBProgressHUDAnimationZoomOut) {
bezelView.transform = large;
}
// Perform animations
dispatch_block_t animations = ^{
if (animatingIn) {
bezelView.transform = CGAffineTransformIdentity;
} else if (!animatingIn && type == MBProgressHUDAnimationZoomIn) {
bezelView.transform = large;
} else if (!animatingIn && type == MBProgressHUDAnimationZoomOut) {
bezelView.transform = small;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
bezelView.alpha = animatingIn ? self.opacity : 0.f;
#pragma clang diagnostic pop
self.backgroundView.alpha = animatingIn ? 1.f : 0.f;
};
// Spring animations are nicer, but only available on iOS 7+
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 || TARGET_OS_TV
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0) {
[UIView animateWithDuration:0.3 delay:0. usingSpringWithDamping:1.f initialSpringVelocity:0.f options:UIViewAnimationOptionBeginFromCurrentState animations:animations completion:completion];
return;
}
#endif
[UIView animateWithDuration:0.3 delay:0. options:UIViewAnimationOptionBeginFromCurrentState animations:animations completion:completion];
}
- (void)done {
// Cancel any scheduled hideDelayed: calls
[self.hideDelayTimer invalidate];
[self setNSProgressDisplayLinkEnabled:NO];
if (self.hasFinished) {
self.alpha = 0.0f;
if (self.removeFromSuperViewOnHide) {
[self removeFromSuperview];
}
}
MBProgressHUDCompletionBlock completionBlock = self.completionBlock;
if (completionBlock) {
completionBlock();
}
id<MBProgressHUDDelegate> delegate = self.delegate;
if ([delegate respondsToSelector:@selector(hudWasHidden:)]) {
[delegate performSelector:@selector(hudWasHidden:) withObject:self];
}
}
#pragma mark - UI
- (void)setupViews {
UIColor *defaultColor = self.contentColor;
MBBackgroundView *backgroundView = [[MBBackgroundView alloc] initWithFrame:self.bounds];
backgroundView.style = MBProgressHUDBackgroundStyleSolidColor;
backgroundView.backgroundColor = [UIColor clearColor];
backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
backgroundView.alpha = 0.f;
[self addSubview:backgroundView];
_backgroundView = backgroundView;
MBBackgroundView *bezelView = [MBBackgroundView new];
bezelView.translatesAutoresizingMaskIntoConstraints = NO;
bezelView.layer.cornerRadius = 5.f;
bezelView.alpha = 0.f;
[self addSubview:bezelView];
_bezelView = bezelView;
[self updateBezelMotionEffects];
UILabel *label = [UILabel new];
label.adjustsFontSizeToFitWidth = NO;
label.textAlignment = NSTextAlignmentCenter;
label.textColor = defaultColor;
label.font = [UIFont boldSystemFontOfSize:MBDefaultLabelFontSize];
label.opaque = NO;
label.backgroundColor = [UIColor clearColor];
_label = label;
UILabel *detailsLabel = [UILabel new];
detailsLabel.adjustsFontSizeToFitWidth = NO;
detailsLabel.textAlignment = NSTextAlignmentCenter;
detailsLabel.textColor = defaultColor;
detailsLabel.numberOfLines = 0;
detailsLabel.font = [UIFont boldSystemFontOfSize:MBDefaultDetailsLabelFontSize];
detailsLabel.opaque = NO;
detailsLabel.backgroundColor = [UIColor clearColor];
_detailsLabel = detailsLabel;
UIButton *button = [MBProgressHUDRoundedButton buttonWithType:UIButtonTypeCustom];
button.titleLabel.textAlignment = NSTextAlignmentCenter;
button.titleLabel.font = [UIFont boldSystemFontOfSize:MBDefaultDetailsLabelFontSize];
[button setTitleColor:defaultColor forState:UIControlStateNormal];
_button = button;
for (UIView *view in @[label, detailsLabel, button]) {
view.translatesAutoresizingMaskIntoConstraints = NO;
[view setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisHorizontal];
[view setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisVertical];
[bezelView addSubview:view];
}
UIView *topSpacer = [UIView new];
topSpacer.translatesAutoresizingMaskIntoConstraints = NO;
topSpacer.hidden = YES;
[bezelView addSubview:topSpacer];
_topSpacer = topSpacer;
UIView *bottomSpacer = [UIView new];
bottomSpacer.translatesAutoresizingMaskIntoConstraints = NO;
bottomSpacer.hidden = YES;
[bezelView addSubview:bottomSpacer];
_bottomSpacer = bottomSpacer;
}
- (void)updateIndicators {
UIView *indicator = self.indicator;
BOOL isActivityIndicator = [indicator isKindOfClass:[UIActivityIndicatorView class]];
BOOL isRoundIndicator = [indicator isKindOfClass:[MBRoundProgressView class]];
MBProgressHUDMode mode = self.mode;
if (mode == MBProgressHUDModeIndeterminate) {
if (!isActivityIndicator) {
// Update to indeterminate indicator
[indicator removeFromSuperview];
indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[(UIActivityIndicatorView *)indicator startAnimating];
[self.bezelView addSubview:indicator];
}
}
else if (mode == MBProgressHUDModeDeterminateHorizontalBar) {
// Update to bar determinate indicator
[indicator removeFromSuperview];
indicator = [[MBBarProgressView alloc] init];
[self.bezelView addSubview:indicator];
}
else if (mode == MBProgressHUDModeDeterminate || mode == MBProgressHUDModeAnnularDeterminate) {
if (!isRoundIndicator) {
// Update to determinante indicator
[indicator removeFromSuperview];
indicator = [[MBRoundProgressView alloc] init];
[self.bezelView addSubview:indicator];
}
if (mode == MBProgressHUDModeAnnularDeterminate) {
[(MBRoundProgressView *)indicator setAnnular:YES];
}
}
else if (mode == MBProgressHUDModeCustomView && self.customView != indicator) {
// Update custom view indicator
[indicator removeFromSuperview];
indicator = self.customView;
[self.bezelView addSubview:indicator];
}
else if (mode == MBProgressHUDModeText) {
[indicator removeFromSuperview];
indicator = nil;
}
indicator.translatesAutoresizingMaskIntoConstraints = NO;
self.indicator = indicator;
if ([indicator respondsToSelector:@selector(setProgress:)]) {
[(id)indicator setValue:@(self.progress) forKey:@"progress"];
}
[indicator setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisHorizontal];
[indicator setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisVertical];
[self updateViewsForColor:self.contentColor];
[self setNeedsUpdateConstraints];
}
- (void)updateViewsForColor:(UIColor *)color {
if (!color) return;
self.label.textColor = color;
self.detailsLabel.textColor = color;
[self.button setTitleColor:color forState:UIControlStateNormal];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if (self.activityIndicatorColor) {
color = self.activityIndicatorColor;
}
#pragma clang diagnostic pop
// UIAppearance settings are prioritized. If they are preset the set color is ignored.
UIView *indicator = self.indicator;
if ([indicator isKindOfClass:[UIActivityIndicatorView class]]) {
UIActivityIndicatorView *appearance = nil;
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000
appearance = [UIActivityIndicatorView appearanceWhenContainedIn:[MBProgressHUD class], nil];
#else
// For iOS 9+
appearance = [UIActivityIndicatorView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]];
#endif
if (appearance.color == nil) {
((UIActivityIndicatorView *)indicator).color = color;
}
} else if ([indicator isKindOfClass:[MBRoundProgressView class]]) {
MBRoundProgressView *appearance = nil;
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000
appearance = [MBRoundProgressView appearanceWhenContainedIn:[MBProgressHUD class], nil];
#else
appearance = [MBRoundProgressView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]];
#endif
if (appearance.progressTintColor == nil) {
((MBRoundProgressView *)indicator).progressTintColor = color;
}
if (appearance.backgroundTintColor == nil) {
((MBRoundProgressView *)indicator).backgroundTintColor = [color colorWithAlphaComponent:0.1];
}
} else if ([indicator isKindOfClass:[MBBarProgressView class]]) {
MBBarProgressView *appearance = nil;
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000
appearance = [MBBarProgressView appearanceWhenContainedIn:[MBProgressHUD class], nil];
#else
appearance = [MBBarProgressView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]];
#endif
if (appearance.progressColor == nil) {
((MBBarProgressView *)indicator).progressColor = color;
}
if (appearance.lineColor == nil) {
((MBBarProgressView *)indicator).lineColor = color;
}
} else {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 || TARGET_OS_TV
if ([indicator respondsToSelector:@selector(setTintColor:)]) {
[indicator setTintColor:color];
}
#endif
}
}
- (void)updateBezelMotionEffects {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 || TARGET_OS_TV
MBBackgroundView *bezelView = self.bezelView;
if (![bezelView respondsToSelector:@selector(addMotionEffect:)]) return;
if (self.defaultMotionEffectsEnabled) {
CGFloat effectOffset = 10.f;
UIInterpolatingMotionEffect *effectX = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
effectX.maximumRelativeValue = @(effectOffset);
effectX.minimumRelativeValue = @(-effectOffset);
UIInterpolatingMotionEffect *effectY = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
effectY.maximumRelativeValue = @(effectOffset);
effectY.minimumRelativeValue = @(-effectOffset);
UIMotionEffectGroup *group = [[UIMotionEffectGroup alloc] init];
group.motionEffects = @[effectX, effectY];
[bezelView addMotionEffect:group];
} else {
NSArray *effects = [bezelView motionEffects];
for (UIMotionEffect *effect in effects) {
[bezelView removeMotionEffect:effect];
}
}
#endif
}
#pragma mark - Layout
- (void)updateConstraints {
UIView *bezel = self.bezelView;
UIView *topSpacer = self.topSpacer;
UIView *bottomSpacer = self.bottomSpacer;
CGFloat margin = self.margin;
NSMutableArray *bezelConstraints = [NSMutableArray array];
NSDictionary *metrics = @{@"margin": @(margin)};
NSMutableArray *subviews = [NSMutableArray arrayWithObjects:self.topSpacer, self.label, self.detailsLabel, self.button, self.bottomSpacer, nil];
if (self.indicator) [subviews insertObject:self.indicator atIndex:1];
// Remove existing constraints
[self removeConstraints:self.constraints];
[topSpacer removeConstraints:topSpacer.constraints];
[bottomSpacer removeConstraints:bottomSpacer.constraints];
if (self.bezelConstraints) {
[bezel removeConstraints:self.bezelConstraints];
self.bezelConstraints = nil;
}
// Center bezel in container (self), applying the offset if set
CGPoint offset = self.offset;
NSMutableArray *centeringConstraints = [NSMutableArray array];
[centeringConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.f constant:offset.x]];
[centeringConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.f constant:offset.y]];
[self applyPriority:998.f toConstraints:centeringConstraints];
[self addConstraints:centeringConstraints];
// Ensure minimum side margin is kept
NSMutableArray *sideConstraints = [NSMutableArray array];
[sideConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>=margin)-[bezel]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(bezel)]];
[sideConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=margin)-[bezel]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(bezel)]];
[self applyPriority:999.f toConstraints:sideConstraints];
[self addConstraints:sideConstraints];
// Minimum bezel size, if set
CGSize minimumSize = self.minSize;
if (!CGSizeEqualToSize(minimumSize, CGSizeZero)) {
NSMutableArray *minSizeConstraints = [NSMutableArray array];
[minSizeConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:minimumSize.width]];
[minSizeConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:minimumSize.height]];
[self applyPriority:997.f toConstraints:minSizeConstraints];
[bezelConstraints addObjectsFromArray:minSizeConstraints];
}
// Square aspect ratio, if set
if (self.square) {
NSLayoutConstraint *square = [NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeWidth multiplier:1.f constant:0];
square.priority = 997.f;
[bezelConstraints addObject:square];
}
// Top and bottom spacing
[topSpacer addConstraint:[NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:margin]];
[bottomSpacer addConstraint:[NSLayoutConstraint constraintWithItem:bottomSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:margin]];
// Top and bottom spaces should be equal
[bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bottomSpacer attribute:NSLayoutAttributeHeight multiplier:1.f constant:0.f]];
// Layout subviews in bezel
NSMutableArray *paddingConstraints = [NSMutableArray new];
[subviews enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) {
// Center in bezel
[bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeCenterX multiplier:1.f constant:0.f]];
// Ensure the minimum edge margin is kept
[bezelConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>=margin)-[view]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(view)]];
// Element spacing
if (idx == 0) {
// First, ensure spacing to bezel edge
[bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeTop multiplier:1.f constant:0.f]];
} else if (idx == subviews.count - 1) {
// Last, ensure spacing to bezel edge
[bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]];
}
if (idx > 0) {
// Has previous
NSLayoutConstraint *padding = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:subviews[idx - 1] attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f];
[bezelConstraints addObject:padding];
[paddingConstraints addObject:padding];
}
}];
[bezel addConstraints:bezelConstraints];
self.bezelConstraints = bezelConstraints;
self.paddingConstraints = [paddingConstraints copy];
[self updatePaddingConstraints];
[super updateConstraints];
}
- (void)layoutSubviews {
// There is no need to update constraints if they are going to
// be recreated in [super layoutSubviews] due to needsUpdateConstraints being set.
// This also avoids an issue on iOS 8, where updatePaddingConstraints
// would trigger a zombie object access.
if (!self.needsUpdateConstraints) {
[self updatePaddingConstraints];
}
[super layoutSubviews];
}
- (void)updatePaddingConstraints {
// Set padding dynamically, depending on whether the view is visible or not
__block BOOL hasVisibleAncestors = NO;
[self.paddingConstraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *padding, NSUInteger idx, BOOL *stop) {
UIView *firstView = (UIView *)padding.firstItem;
UIView *secondView = (UIView *)padding.secondItem;
BOOL firstVisible = !firstView.hidden && !CGSizeEqualToSize(firstView.intrinsicContentSize, CGSizeZero);
BOOL secondVisible = !secondView.hidden && !CGSizeEqualToSize(secondView.intrinsicContentSize, CGSizeZero);
// Set if both views are visible or if there's a visible view on top that doesn't have padding
// added relative to the current view yet
padding.constant = (firstVisible && (secondVisible || hasVisibleAncestors)) ? MBDefaultPadding : 0.f;
hasVisibleAncestors |= secondVisible;
}];
}
- (void)applyPriority:(UILayoutPriority)priority toConstraints:(NSArray *)constraints {
for (NSLayoutConstraint *constraint in constraints) {
constraint.priority = priority;
}
}
#pragma mark - Properties
- (void)setMode:(MBProgressHUDMode)mode {
if (mode != _mode) {
_mode = mode;
[self updateIndicators];
}
}
- (void)setCustomView:(UIView *)customView {
if (customView != _customView) {
_customView = customView;
if (self.mode == MBProgressHUDModeCustomView) {
[self updateIndicators];
}
}
}
- (void)setOffset:(CGPoint)offset {
if (!CGPointEqualToPoint(offset, _offset)) {
_offset = offset;
[self setNeedsUpdateConstraints];
}
}
- (void)setMargin:(CGFloat)margin {
if (margin != _margin) {
_margin = margin;
[self setNeedsUpdateConstraints];
}
}
- (void)setMinSize:(CGSize)minSize {
if (!CGSizeEqualToSize(minSize, _minSize)) {
_minSize = minSize;
[self setNeedsUpdateConstraints];
}
}
- (void)setSquare:(BOOL)square {
if (square != _square) {
_square = square;
[self setNeedsUpdateConstraints];
}
}
- (void)setProgressObjectDisplayLink:(CADisplayLink *)progressObjectDisplayLink {
if (progressObjectDisplayLink != _progressObjectDisplayLink) {
[_progressObjectDisplayLink invalidate];
_progressObjectDisplayLink = progressObjectDisplayLink;
[_progressObjectDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
}
- (void)setProgressObject:(NSProgress *)progressObject {
if (progressObject != _progressObject) {
_progressObject = progressObject;
[self setNSProgressDisplayLinkEnabled:YES];
}
}
- (void)setProgress:(float)progress {
if (progress != _progress) {
_progress = progress;
UIView *indicator = self.indicator;
if ([indicator respondsToSelector:@selector(setProgress:)]) {
[(id)indicator setValue:@(self.progress) forKey:@"progress"];
}
}
}
- (void)setContentColor:(UIColor *)contentColor {
if (contentColor != _contentColor && ![contentColor isEqual:_contentColor]) {
_contentColor = contentColor;
[self updateViewsForColor:contentColor];
}
}
- (void)setDefaultMotionEffectsEnabled:(BOOL)defaultMotionEffectsEnabled {
if (defaultMotionEffectsEnabled != _defaultMotionEffectsEnabled) {
_defaultMotionEffectsEnabled = defaultMotionEffectsEnabled;
[self updateBezelMotionEffects];
}
}
#pragma mark - NSProgress
- (void)setNSProgressDisplayLinkEnabled:(BOOL)enabled {
// We're using CADisplayLink, because NSProgress can change very quickly and observing it may starve the main thread,
// so we're refreshing the progress only every frame draw
if (enabled && self.progressObject) {
// Only create if not already active.
if (!self.progressObjectDisplayLink) {
self.progressObjectDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateProgressFromProgressObject)];
}
} else {
self.progressObjectDisplayLink = nil;
}
}
- (void)updateProgressFromProgressObject {
self.progress = self.progressObject.fractionCompleted;
}
#pragma mark - Notifications
- (void)registerForNotifications {
#if !TARGET_OS_TV
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(statusBarOrientationDidChange:)
name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
#endif
}
- (void)unregisterFromNotifications {
#if !TARGET_OS_TV
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
#endif
}
#if !TARGET_OS_TV
- (void)statusBarOrientationDidChange:(NSNotification *)notification {
UIView *superview = self.superview;
if (!superview) {
return;
} else {
[self updateForCurrentOrientationAnimated:YES];
}
}
#endif
- (void)updateForCurrentOrientationAnimated:(BOOL)animated {
// Stay in sync with the superview in any case
if (self.superview) {
self.frame = self.superview.bounds;
}
// Not needed on iOS 8+, compile out when the deployment target allows,
// to avoid sharedApplication problems on extension targets
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
// Only needed pre iOS 8 when added to a window
BOOL iOS8OrLater = kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0;
if (iOS8OrLater || ![self.superview isKindOfClass:[UIWindow class]]) return;
// Make extension friendly. Will not get called on extensions (iOS 8+) due to the above check.
// This just ensures we don't get a warning about extension-unsafe API.
Class UIApplicationClass = NSClassFromString(@"UIApplication");
if (!UIApplicationClass || ![UIApplicationClass respondsToSelector:@selector(sharedApplication)]) return;
UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)];
UIInterfaceOrientation orientation = application.statusBarOrientation;
CGFloat radians = 0;
if (UIInterfaceOrientationIsLandscape(orientation)) {
radians = orientation == UIInterfaceOrientationLandscapeLeft ? -(CGFloat)M_PI_2 : (CGFloat)M_PI_2;
// Window coordinates differ!
self.bounds = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.width);
} else {
radians = orientation == UIInterfaceOrientationPortraitUpsideDown ? (CGFloat)M_PI : 0.f;
}
if (animated) {
[UIView animateWithDuration:0.3 animations:^{
self.transform = CGAffineTransformMakeRotation(radians);
}];
} else {
self.transform = CGAffineTransformMakeRotation(radians);
}
#endif
}
@end
@implementation MBRoundProgressView
#pragma mark - Lifecycle
- (id)init {
return [self initWithFrame:CGRectMake(0.f, 0.f, 37.f, 37.f)];
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.opaque = NO;
_progress = 0.f;
_annular = NO;
_progressTintColor = [[UIColor alloc] initWithWhite:1.f alpha:1.f];
_backgroundTintColor = [[UIColor alloc] initWithWhite:1.f alpha:.1f];
}
return self;
}
#pragma mark - Layout
- (CGSize)intrinsicContentSize {
return CGSizeMake(37.f, 37.f);
}
#pragma mark - Properties
- (void)setProgress:(float)progress {
if (progress != _progress) {
_progress = progress;
[self setNeedsDisplay];
}
}
- (void)setProgressTintColor:(UIColor *)progressTintColor {
NSAssert(progressTintColor, @"The color should not be nil.");
if (progressTintColor != _progressTintColor && ![progressTintColor isEqual:_progressTintColor]) {
_progressTintColor = progressTintColor;
[self setNeedsDisplay];
}
}
- (void)setBackgroundTintColor:(UIColor *)backgroundTintColor {
NSAssert(backgroundTintColor, @"The color should not be nil.");
if (backgroundTintColor != _backgroundTintColor && ![backgroundTintColor isEqual:_backgroundTintColor]) {
_backgroundTintColor = backgroundTintColor;
[self setNeedsDisplay];
}
}
#pragma mark - Drawing
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
BOOL isPreiOS7 = kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0;
if (_annular) {
// Draw background
CGFloat lineWidth = isPreiOS7 ? 5.f : 2.f;
UIBezierPath *processBackgroundPath = [UIBezierPath bezierPath];
processBackgroundPath.lineWidth = lineWidth;
processBackgroundPath.lineCapStyle = kCGLineCapButt;
CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
CGFloat radius = (self.bounds.size.width - lineWidth)/2;
CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees
CGFloat endAngle = (2 * (float)M_PI) + startAngle;
[processBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
[_backgroundTintColor set];
[processBackgroundPath stroke];
// Draw progress
UIBezierPath *processPath = [UIBezierPath bezierPath];
processPath.lineCapStyle = isPreiOS7 ? kCGLineCapRound : kCGLineCapSquare;
processPath.lineWidth = lineWidth;
endAngle = (self.progress * 2 * (float)M_PI) + startAngle;
[processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
[_progressTintColor set];
[processPath stroke];
} else {
// Draw background
CGFloat lineWidth = 2.f;
CGRect allRect = self.bounds;
CGRect circleRect = CGRectInset(allRect, lineWidth/2.f, lineWidth/2.f);
CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
[_progressTintColor setStroke];
[_backgroundTintColor setFill];
CGContextSetLineWidth(context, lineWidth);
if (isPreiOS7) {
CGContextFillEllipseInRect(context, circleRect);
}
CGContextStrokeEllipseInRect(context, circleRect);
// 90 degrees
CGFloat startAngle = - ((float)M_PI / 2.f);
// Draw progress
if (isPreiOS7) {
CGFloat radius = (CGRectGetWidth(self.bounds) / 2.f) - lineWidth;
CGFloat endAngle = (self.progress * 2.f * (float)M_PI) + startAngle;
[_progressTintColor setFill];
CGContextMoveToPoint(context, center.x, center.y);
CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);
CGContextClosePath(context);
CGContextFillPath(context);
} else {
UIBezierPath *processPath = [UIBezierPath bezierPath];
processPath.lineCapStyle = kCGLineCapButt;
processPath.lineWidth = lineWidth * 2.f;
CGFloat radius = (CGRectGetWidth(self.bounds) / 2.f) - (processPath.lineWidth / 2.f);
CGFloat endAngle = (self.progress * 2.f * (float)M_PI) + startAngle;
[processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
// Ensure that we don't get color overlaping when _progressTintColor alpha < 1.f.
CGContextSetBlendMode(context, kCGBlendModeCopy);
[_progressTintColor set];
[processPath stroke];
}
}
}
@end
@implementation MBBarProgressView
#pragma mark - Lifecycle
- (id)init {
return [self initWithFrame:CGRectMake(.0f, .0f, 120.0f, 20.0f)];
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_progress = 0.f;
_lineColor = [UIColor whiteColor];
_progressColor = [UIColor whiteColor];
_progressRemainingColor = [UIColor clearColor];
self.backgroundColor = [UIColor clearColor];
self.opaque = NO;
}
return self;
}
#pragma mark - Layout
- (CGSize)intrinsicContentSize {
BOOL isPreiOS7 = kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0;
return CGSizeMake(120.f, isPreiOS7 ? 20.f : 10.f);
}
#pragma mark - Properties
- (void)setProgress:(float)progress {
if (progress != _progress) {
_progress = progress;
[self setNeedsDisplay];
}
}
- (void)setProgressColor:(UIColor *)progressColor {
NSAssert(progressColor, @"The color should not be nil.");
if (progressColor != _progressColor && ![progressColor isEqual:_progressColor]) {
_progressColor = progressColor;
[self setNeedsDisplay];
}
}
- (void)setProgressRemainingColor:(UIColor *)progressRemainingColor {
NSAssert(progressRemainingColor, @"The color should not be nil.");
if (progressRemainingColor != _progressRemainingColor && ![progressRemainingColor isEqual:_progressRemainingColor]) {
_progressRemainingColor = progressRemainingColor;
[self setNeedsDisplay];
}
}
#pragma mark - Drawing
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2);
CGContextSetStrokeColorWithColor(context,[_lineColor CGColor]);
CGContextSetFillColorWithColor(context, [_progressRemainingColor CGColor]);
// Draw background
CGFloat radius = (rect.size.height / 2) - 2;
CGContextMoveToPoint(context, 2, rect.size.height/2);
CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius);
CGContextAddLineToPoint(context, rect.size.width - radius - 2, 2);
CGContextAddArcToPoint(context, rect.size.width - 2, 2, rect.size.width - 2, rect.size.height / 2, radius);
CGContextAddArcToPoint(context, rect.size.width - 2, rect.size.height - 2, rect.size.width - radius - 2, rect.size.height - 2, radius);
CGContextAddLineToPoint(context, radius + 2, rect.size.height - 2);
CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius);
CGContextFillPath(context);
// Draw border
CGContextMoveToPoint(context, 2, rect.size.height/2);
CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius);
CGContextAddLineToPoint(context, rect.size.width - radius - 2, 2);
CGContextAddArcToPoint(context, rect.size.width - 2, 2, rect.size.width - 2, rect.size.height / 2, radius);
CGContextAddArcToPoint(context, rect.size.width - 2, rect.size.height - 2, rect.size.width - radius - 2, rect.size.height - 2, radius);
CGContextAddLineToPoint(context, radius + 2, rect.size.height - 2);
CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius);
CGContextStrokePath(context);
CGContextSetFillColorWithColor(context, [_progressColor CGColor]);
radius = radius - 2;
CGFloat amount = self.progress * rect.size.width;
// Progress in the middle area
if (amount >= radius + 4 && amount <= (rect.size.width - radius - 4)) {
CGContextMoveToPoint(context, 4, rect.size.height/2);
CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);
CGContextAddLineToPoint(context, amount, 4);
CGContextAddLineToPoint(context, amount, radius + 4);
CGContextMoveToPoint(context, 4, rect.size.height/2);
CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);
CGContextAddLineToPoint(context, amount, rect.size.height - 4);
CGContextAddLineToPoint(context, amount, radius + 4);
CGContextFillPath(context);
}
// Progress in the right arc
else if (amount > radius + 4) {
CGFloat x = amount - (rect.size.width - radius - 4);
CGContextMoveToPoint(context, 4, rect.size.height/2);
CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);
CGContextAddLineToPoint(context, rect.size.width - radius - 4, 4);
CGFloat angle = -acos(x/radius);
if (isnan(angle)) angle = 0;
CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, M_PI, angle, 0);
CGContextAddLineToPoint(context, amount, rect.size.height/2);
CGContextMoveToPoint(context, 4, rect.size.height/2);
CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);
CGContextAddLineToPoint(context, rect.size.width - radius - 4, rect.size.height - 4);
angle = acos(x/radius);
if (isnan(angle)) angle = 0;
CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, -M_PI, angle, 1);
CGContextAddLineToPoint(context, amount, rect.size.height/2);
CGContextFillPath(context);
}
// Progress is in the left arc
else if (amount < radius + 4 && amount > 0) {
CGContextMoveToPoint(context, 4, rect.size.height/2);
CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);
CGContextAddLineToPoint(context, radius + 4, rect.size.height/2);
CGContextMoveToPoint(context, 4, rect.size.height/2);
CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);
CGContextAddLineToPoint(context, radius + 4, rect.size.height/2);
CGContextFillPath(context);
}
}
@end
@interface MBBackgroundView ()
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV
@property UIVisualEffectView *effectView;
#endif
#if !TARGET_OS_TV
@property UIToolbar *toolbar;
#endif
@end
@implementation MBBackgroundView
#pragma mark - Lifecycle
- (instancetype)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0) {
_style = MBProgressHUDBackgroundStyleBlur;
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {
_color = [UIColor colorWithWhite:0.8f alpha:0.6f];
} else {
_color = [UIColor colorWithWhite:0.95f alpha:0.6f];
}
} else {
_style = MBProgressHUDBackgroundStyleSolidColor;
_color = [[UIColor blackColor] colorWithAlphaComponent:0.8];
}
self.clipsToBounds = YES;
[self updateForBackgroundStyle];
}
return self;
}
#pragma mark - Layout
- (CGSize)intrinsicContentSize {
// Smallest size possible. Content pushes against this.
return CGSizeZero;
}
#pragma mark - Appearance
- (void)setStyle:(MBProgressHUDBackgroundStyle)style {
if (style == MBProgressHUDBackgroundStyleBlur && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0) {
style = MBProgressHUDBackgroundStyleSolidColor;
}
if (_style != style) {
_style = style;
[self updateForBackgroundStyle];
}
}
- (void)setColor:(UIColor *)color {
NSAssert(color, @"The color should not be nil.");
if (color != _color && ![color isEqual:_color]) {
_color = color;
[self updateViewsForColor:color];
}
}
///////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - Views
- (void)updateForBackgroundStyle {
MBProgressHUDBackgroundStyle style = self.style;
if (style == MBProgressHUDBackgroundStyleBlur) {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
[self addSubview:effectView];
effectView.frame = self.bounds;
effectView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.backgroundColor = self.color;
self.layer.allowsGroupOpacity = NO;
self.effectView = effectView;
} else {
#endif
#if !TARGET_OS_TV
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectInset(self.bounds, -100.f, -100.f)];
toolbar.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
toolbar.barTintColor = self.color;
toolbar.translucent = YES;
[self addSubview:toolbar];
self.toolbar = toolbar;
#endif
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV
}
#endif
} else {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {
[self.effectView removeFromSuperview];
self.effectView = nil;
} else {
#endif
#if !TARGET_OS_TV
[self.toolbar removeFromSuperview];
self.toolbar = nil;
#endif
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV
}
#endif
self.backgroundColor = self.color;
}
}
- (void)updateViewsForColor:(UIColor *)color {
if (self.style == MBProgressHUDBackgroundStyleBlur) {
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {
self.backgroundColor = self.color;
} else {
#if !TARGET_OS_TV
self.toolbar.barTintColor = color;
#endif
}
} else {
self.backgroundColor = self.color;
}
}
@end
@implementation MBProgressHUD (Deprecated)
#pragma mark - Class
+ (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated {
NSArray *huds = [MBProgressHUD allHUDsForView:view];
for (MBProgressHUD *hud in huds) {
hud.removeFromSuperViewOnHide = YES;
[hud hideAnimated:animated];
}
return [huds count];
}
+ (NSArray *)allHUDsForView:(UIView *)view {
NSMutableArray *huds = [NSMutableArray array];
NSArray *subviews = view.subviews;
for (UIView *aView in subviews) {
if ([aView isKindOfClass:self]) {
[huds addObject:aView];
}
}
return [NSArray arrayWithArray:huds];
}
#pragma mark - Lifecycle
- (id)initWithWindow:(UIWindow *)window {
return [self initWithView:window];
}
#pragma mark - Show & hide
- (void)show:(BOOL)animated {
[self showAnimated:animated];
}
- (void)hide:(BOOL)animated {
[self hideAnimated:animated];
}
- (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay {
[self hideAnimated:animated afterDelay:delay];
}
#pragma mark - Threading
- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated {
[self showAnimated:animated whileExecutingBlock:^{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
// Start executing the requested task
[target performSelector:method withObject:object];
#pragma clang diagnostic pop
}];
}
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
[self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:NULL];
}
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(void (^)())completion {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
[self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:completion];
}
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue {
[self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:NULL];
}
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue completionBlock:(nullable MBProgressHUDCompletionBlock)completion {
self.taskInProgress = YES;
self.completionBlock = completion;
dispatch_async(queue, ^(void) {
block();
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self cleanUp];
});
});
[self showAnimated:animated];
}
- (void)cleanUp {
self.taskInProgress = NO;
[self hideAnimated:self.useAnimation];
}
#pragma mark - Labels
- (NSString *)labelText {
return self.label.text;
}
- (void)setLabelText:(NSString *)labelText {
MBMainThreadAssert();
self.label.text = labelText;
}
- (UIFont *)labelFont {
return self.label.font;
}
- (void)setLabelFont:(UIFont *)labelFont {
MBMainThreadAssert();
self.label.font = labelFont;
}
- (UIColor *)labelColor {
return self.label.textColor;
}
- (void)setLabelColor:(UIColor *)labelColor {
MBMainThreadAssert();
self.label.textColor = labelColor;
}
- (NSString *)detailsLabelText {
return self.detailsLabel.text;
}
- (void)setDetailsLabelText:(NSString *)detailsLabelText {
MBMainThreadAssert();
self.detailsLabel.text = detailsLabelText;
}
- (UIFont *)detailsLabelFont {
return self.detailsLabel.font;
}
- (void)setDetailsLabelFont:(UIFont *)detailsLabelFont {
MBMainThreadAssert();
self.detailsLabel.font = detailsLabelFont;
}
- (UIColor *)detailsLabelColor {
return self.detailsLabel.textColor;
}
- (void)setDetailsLabelColor:(UIColor *)detailsLabelColor {
MBMainThreadAssert();
self.detailsLabel.textColor = detailsLabelColor;
}
- (CGFloat)opacity {
return _opacity;
}
- (void)setOpacity:(CGFloat)opacity {
MBMainThreadAssert();
_opacity = opacity;
}
- (UIColor *)color {
return self.bezelView.color;
}
- (void)setColor:(UIColor *)color {
MBMainThreadAssert();
self.bezelView.color = color;
}
- (CGFloat)yOffset {
return self.offset.y;
}
- (void)setYOffset:(CGFloat)yOffset {
MBMainThreadAssert();
self.offset = CGPointMake(self.offset.x, yOffset);
}
- (CGFloat)xOffset {
return self.offset.x;
}
- (void)setXOffset:(CGFloat)xOffset {
MBMainThreadAssert();
self.offset = CGPointMake(xOffset, self.offset.y);
}
- (CGFloat)cornerRadius {
return self.bezelView.layer.cornerRadius;
}
- (void)setCornerRadius:(CGFloat)cornerRadius {
MBMainThreadAssert();
self.bezelView.layer.cornerRadius = cornerRadius;
}
- (BOOL)dimBackground {
MBBackgroundView *backgroundView = self.backgroundView;
UIColor *dimmedColor = [UIColor colorWithWhite:0.f alpha:.2f];
return backgroundView.style == MBProgressHUDBackgroundStyleSolidColor && [backgroundView.color isEqual:dimmedColor];
}
- (void)setDimBackground:(BOOL)dimBackground {
MBMainThreadAssert();
self.backgroundView.style = MBProgressHUDBackgroundStyleSolidColor;
self.backgroundView.color = dimBackground ? [UIColor colorWithWhite:0.f alpha:.2f] : [UIColor clearColor];
}
- (CGSize)size {
return self.bezelView.frame.size;
}
- (UIColor *)activityIndicatorColor {
return _activityIndicatorColor;
}
- (void)setActivityIndicatorColor:(UIColor *)activityIndicatorColor {
if (activityIndicatorColor != _activityIndicatorColor) {
_activityIndicatorColor = activityIndicatorColor;
UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)self.indicator;
if ([indicator isKindOfClass:[UIActivityIndicatorView class]]) {
[indicator setColor:activityIndicatorColor];
}
}
}
@end
@implementation MBProgressHUDRoundedButton
#pragma mark - Lifecycle
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
CALayer *layer = self.layer;
layer.borderWidth = 1.f;
}
return self;
}
#pragma mark - Layout
- (void)layoutSubviews {
[super layoutSubviews];
// Fully rounded corners
CGFloat height = CGRectGetHeight(self.bounds);
self.layer.cornerRadius = ceil(height / 2.f);
}
- (CGSize)intrinsicContentSize {
// Only show if we have associated control events
if (self.allControlEvents == 0) return CGSizeZero;
CGSize size = [super intrinsicContentSize];
// Add some side padding
size.width += 20.f;
return size;
}
#pragma mark - Color
- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state {
[super setTitleColor:color forState:state];
// Update related colors
[self setHighlighted:self.highlighted];
self.layer.borderColor = color.CGColor;
}
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
UIColor *baseColor = [self titleColorForState:UIControlStateSelected];
self.backgroundColor = highlighted ? [baseColor colorWithAlphaComponent:0.1f] : [UIColor clearColor];
}
@end
//
// DetailController.h
// CordBradge-OC
//
// Created by Mr.xiao on 17/2/14.
// Copyright © 2017年 keepJion. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <Cordova/CDVViewController.h>
@protocol WebPluginProtocol<NSObject>
- (void)webViewDidSuccessLoad;
- (void)webViewDidFailedLoad;
@end
@interface WebPluginController : CDVViewController
@property (nonatomic ,copy) NSString *fileUrl;
@property (nonatomic, weak) id<WebPluginProtocol> delegate;
@property (nonatomic, strong) id <CDVCommandDelegate> openDelegate;
@end
//
// DetailController.m
// CordBradge-OC
//
// Created by Mr.xiao on 17/2/14.
// Copyright © 2017年 keepJion. All rights reserved.
//
#import "WebPluginController.h"
#import "CDVSplashScreen.h"
#import "MBProgressHUD+XW.h"
@interface WebPluginController ()<UIGestureRecognizerDelegate>
@property (nonatomic,strong) UILabel *titleLalel;
@property (nonatomic,strong) UIWebView *baseView;
@end
@implementation WebPluginController
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didLunch:) name:CDVPageDidLoadNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didStart:) name:CDVPluginResetNotification object:nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
[MBProgressHUD showRequestLoad:nil toView:self.view];
self.view.backgroundColor = [UIColor whiteColor];
// Do any additional setup after loading the view.
self.webView.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame) );
self.webView.backgroundColor = [UIColor whiteColor];
if(@available(iOS 11.0,*)){
self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
}
//MARK: ACTION
- (void)didLunch:(NSNotification *)not{
[MBProgressHUD hideRequestLoad:self.view];
if([self.delegate respondsToSelector:@selector(webViewDidSuccessLoad)]){
[self.delegate webViewDidSuccessLoad];
}
}
- (void)didStart:(NSNotification *)not{
}
/*
重写CDVViewController方法,这样就可以根据自己的需要加载插件了
这里是不加载 CDVSplashScreen 这个插件
*/
- (void)registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className
{
if([className isEqualToString:@"CDVSplashScreen"]){
return;
}
[super registerPlugin:plugin withClassName:className];
}
- (UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleDefault;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
var exec = require('cordova/exec');
var WebViewPlugin = {
loadWebView: function (successCallback, errorCallback, options) {
if (errorCallback == null) {
errorCallback = function () {
}
}
if (typeof errorCallback != "function") {
return
}
if (typeof successCallback != "function") {
return
}
exec(successCallback, errorCallback, "WebViewPlugin", "loadWebView", [options]);
},
//dismissWebView
dismissWebView: function (successCallback, errorCallback, options) {
if (errorCallback == null) {
errorCallback = function () {
}
}
if (typeof errorCallback != "function") {
return
}
if (typeof successCallback != "function") {
return
}
exec(successCallback, errorCallback, "WebViewPlugin", "dismissWebView", [options]);
}
};
if (typeof module !== 'undefined' && module.exports) {
module.exports = WebViewPlugin;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment