appjam 0.1.8.8 → 0.1.8.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. data/README.md +22 -62
  2. data/lib/appjam/generators/gist.yml +1 -1
  3. data/lib/appjam/generators/templates/blank/EiffelApplication.xcodeproj/project.pbxproj +1166 -482
  4. data/lib/appjam/generators/templates/blank/EiffelApplication.xcodeproj/project.xcworkspace/xcuserdata/eiffel.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  5. data/lib/appjam/generators/templates/blank/EiffelApplication/EiffelApplication-Prefix.pch.tt +26 -0
  6. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenu.h +52 -0
  7. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenu.m +412 -0
  8. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenuItem.h +44 -0
  9. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/AwesomeMenuItem.m +97 -0
  10. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton-highlighted.png +0 -0
  11. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton-highlighted@2x.png +0 -0
  12. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton.png +0 -0
  13. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-addbutton@2x.png +0 -0
  14. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem-highlighted.png +0 -0
  15. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem-highlighted@2x.png +0 -0
  16. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem.png +0 -0
  17. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/bg-menuitem@2x.png +0 -0
  18. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus-highlighted.png +0 -0
  19. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus-highlighted@2x.png +0 -0
  20. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus.png +0 -0
  21. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-plus@2x.png +0 -0
  22. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-star.png +0 -0
  23. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/AwesomeMenu/Images/icon-star@2x.png +0 -0
  24. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/CMPopTipView/CMPopTipView.h +167 -0
  25. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/CMPopTipView/CMPopTipView.m +639 -0
  26. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/FXLabel/FXLabel.h +97 -0
  27. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/FXLabel/FXLabel.m +1080 -0
  28. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MBProgressHUD/MBProgressHUD.h +451 -0
  29. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/MBProgressHUD/MBProgressHUD.m +865 -0
  30. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FacingView.h +42 -0
  31. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FacingView.m +56 -0
  32. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FoldView.h +90 -0
  33. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/FoldView.m +316 -0
  34. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/MultiFoldView.h +104 -0
  35. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/MultiFoldView.m +516 -0
  36. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldConstants.h +49 -0
  37. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldNavigationController.h +18 -0
  38. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldNavigationController.m +88 -0
  39. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_left.png +0 -0
  40. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_left@2x.png +0 -0
  41. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_right.png +0 -0
  42. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldResources.bundle/swipe_guide_right@2x.png +0 -0
  43. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldSwipeHintView.h +25 -0
  44. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldSwipeHintView.m +76 -0
  45. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldView.h +131 -0
  46. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/PaperFoldView.m +941 -0
  47. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/Resources/swipe_guide.psd +0 -0
  48. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/Resources/swipe_guide2.psd +0 -0
  49. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/ShadowView.h +46 -0
  50. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/ShadowView.m +82 -0
  51. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/TouchThroughUIView.h +39 -0
  52. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/TouchThroughUIView.m +72 -0
  53. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/UIView+Screenshot.h +42 -0
  54. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/PaperFold/UIView+Screenshot.m +100 -0
  55. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/NSBubbleData.h +34 -0
  56. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/NSBubbleData.m +140 -0
  57. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleHeaderTableViewCell.h +17 -0
  58. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleHeaderTableViewCell.m +57 -0
  59. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableView.h +30 -0
  60. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableView.m +233 -0
  61. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableViewCell.h +19 -0
  62. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableViewCell.m +122 -0
  63. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTableViewDataSource.h +24 -0
  64. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTypingTableViewCell.h +20 -0
  65. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/UIBubbleTypingTableViewCell.m +56 -0
  66. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleMine.png +0 -0
  67. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleMine@2x.png +0 -0
  68. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleSomeone.png +0 -0
  69. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/bubbleSomeone@2x.png +0 -0
  70. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/missingAvatar.png +0 -0
  71. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/missingAvatar@2x.png +0 -0
  72. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingMine.png +0 -0
  73. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingMine@2x.png +0 -0
  74. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingSomeone.png +0 -0
  75. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIBubbleTableView/images/typingSomeone@2x.png +0 -0
  76. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIGlossyButton.h +124 -0
  77. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIGlossyButton.m +545 -0
  78. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIView+LayerEffects.h +22 -0
  79. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/components/UIGlossyButton/UIView+LayerEffects.m +32 -0
  80. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFIncrementalStore.h +344 -0
  81. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFIncrementalStore.m +848 -0
  82. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFRESTClient.h +135 -0
  83. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/AFIncrementalStore/AFRESTClient.m +441 -0
  84. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/NSString+InflectorKit.h +40 -0
  85. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/NSString+InflectorKit.m +36 -0
  86. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/TTTStringInflector.h +76 -0
  87. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/InflectorKit/TTTStringInflector.m +270 -0
  88. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/MKAnnotationView+WebCache.h +95 -0
  89. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/MKAnnotationView+WebCache.m +78 -0
  90. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDImageCache.h +144 -0
  91. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDImageCache.m +311 -0
  92. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageCompat.h +40 -0
  93. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageCompat.m +54 -0
  94. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDecoder.h +18 -0
  95. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDecoder.m +70 -0
  96. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloader.h +102 -0
  97. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloader.m +226 -0
  98. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloaderOperation.h +25 -0
  99. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageDownloaderOperation.m +339 -0
  100. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageManager.h +167 -0
  101. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageManager.m +244 -0
  102. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImageOperation.h +15 -0
  103. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImagePrefetcher.h +58 -0
  104. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/SDWebImagePrefetcher.m +127 -0
  105. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIButton+WebCache.h +173 -0
  106. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIButton+WebCache.m +129 -0
  107. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIImageView+WebCache.h +140 -0
  108. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/frameworks/SDWebImage/UIImageView+WebCache.m +84 -0
  109. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/CPAnimationProgram.h +28 -0
  110. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/CPAnimationSequence.h +28 -0
  111. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/CPAnimationStep.h +49 -0
  112. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/private/CPAnimationProgram.m +100 -0
  113. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/private/CPAnimationSequence.m +85 -0
  114. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CPAnimationSequence/private/CPAnimationStep.m +122 -0
  115. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaAsyncSocket/GCDAsyncSocket.h +1074 -0
  116. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaAsyncSocket/GCDAsyncSocket.m +7430 -0
  117. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDData.h +14 -0
  118. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDData.m +158 -0
  119. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDNumber.h +12 -0
  120. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDNumber.m +88 -0
  121. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDRange.h +56 -0
  122. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Categories/DDRange.m +104 -0
  123. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPAuthenticationRequest.h +45 -0
  124. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPAuthenticationRequest.m +195 -0
  125. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPConnection.h +119 -0
  126. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPConnection.m +2708 -0
  127. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPLogging.h +136 -0
  128. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPMessage.h +48 -0
  129. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPMessage.m +113 -0
  130. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPResponse.h +149 -0
  131. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPServer.h +205 -0
  132. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/HTTPServer.m +772 -0
  133. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartFormDataParser.h +65 -0
  134. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartFormDataParser.m +529 -0
  135. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeader.h +33 -0
  136. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeader.m +86 -0
  137. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeaderField.h +23 -0
  138. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Mime/MultipartMessageHeaderField.m +211 -0
  139. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPAsyncFileResponse.h +75 -0
  140. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPAsyncFileResponse.m +405 -0
  141. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDataResponse.h +13 -0
  142. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDataResponse.m +79 -0
  143. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDynamicFileResponse.h +52 -0
  144. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPDynamicFileResponse.m +292 -0
  145. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPErrorResponse.h +9 -0
  146. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPErrorResponse.m +38 -0
  147. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPFileResponse.h +25 -0
  148. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPFileResponse.m +237 -0
  149. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPRedirectResponse.h +12 -0
  150. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/Responses/HTTPRedirectResponse.m +73 -0
  151. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/WebSocket.h +105 -0
  152. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Core/WebSocket.m +791 -0
  153. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVConnection.h +7 -0
  154. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVConnection.m +160 -0
  155. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVResponse.h +11 -0
  156. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DAVResponse.m +372 -0
  157. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DELETEResponse.h +7 -0
  158. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/DELETEResponse.m +49 -0
  159. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/PUTResponse.h +8 -0
  160. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/CocoaHTTPServer/Extensions/WebDAV/PUTResponse.m +69 -0
  161. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHpple.h +54 -0
  162. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHpple.m +102 -0
  163. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHppleElement.h +103 -0
  164. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/TFHppleElement.m +200 -0
  165. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/XPathQuery.h +10 -0
  166. data/lib/appjam/generators/templates/blank/EiffelApplication/libs/toolkit/hpple/XPathQuery.m +197 -0
  167. data/lib/appjam/version.rb +1 -1
  168. metadata +164 -3
@@ -0,0 +1,451 @@
1
+ //
2
+ // MBProgressHUD.h
3
+ // Version 0.6
4
+ // Created by Matej Bukovinski on 2.4.09.
5
+ //
6
+
7
+ // This code is distributed under the terms and conditions of the MIT license.
8
+
9
+ // Copyright (c) 2013 Matej Bukovinski
10
+ //
11
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ // of this software and associated documentation files (the "Software"), to deal
13
+ // in the Software without restriction, including without limitation the rights
14
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ // copies of the Software, and to permit persons to whom the Software is
16
+ // furnished to do so, subject to the following conditions:
17
+ //
18
+ // The above copyright notice and this permission notice shall be included in
19
+ // all copies or substantial portions of the Software.
20
+ //
21
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
+ // THE SOFTWARE.
28
+
29
+ #import <Foundation/Foundation.h>
30
+ #import <UIKit/UIKit.h>
31
+ #import <CoreGraphics/CoreGraphics.h>
32
+
33
+ @protocol MBProgressHUDDelegate;
34
+
35
+
36
+ typedef enum {
37
+ /** Progress is shown using an UIActivityIndicatorView. This is the default. */
38
+ MBProgressHUDModeIndeterminate,
39
+ /** Progress is shown using a round, pie-chart like, progress view. */
40
+ MBProgressHUDModeDeterminate,
41
+ /** Progress is shown using a ring-shaped progress view. */
42
+ MBProgressHUDModeAnnularDeterminate,
43
+ /** Shows a custom view */
44
+ MBProgressHUDModeCustomView,
45
+ /** Shows only labels */
46
+ MBProgressHUDModeText
47
+ } MBProgressHUDMode;
48
+
49
+ typedef enum {
50
+ /** Opacity animation */
51
+ MBProgressHUDAnimationFade,
52
+ /** Opacity + scale animation */
53
+ MBProgressHUDAnimationZoom,
54
+ MBProgressHUDAnimationZoomOut = MBProgressHUDAnimationZoom,
55
+ MBProgressHUDAnimationZoomIn
56
+ } MBProgressHUDAnimation;
57
+
58
+
59
+ #ifndef MB_INSTANCETYPE
60
+ #if __has_feature(objc_instancetype)
61
+ #define MB_INSTANCETYPE instancetype
62
+ #else
63
+ #define MB_INSTANCETYPE id
64
+ #endif
65
+ #endif
66
+
67
+ #ifndef MB_STRONG
68
+ #if __has_feature(objc_arc)
69
+ #define MB_STRONG strong
70
+ #else
71
+ #define MB_STRONG retain
72
+ #endif
73
+ #endif
74
+
75
+ #ifndef MB_WEAK
76
+ #if __has_feature(objc_arc_weak)
77
+ #define MB_WEAK weak
78
+ #elif __has_feature(objc_arc)
79
+ #define MB_WEAK unsafe_unretained
80
+ #else
81
+ #define MB_WEAK assign
82
+ #endif
83
+ #endif
84
+
85
+ #if NS_BLOCKS_AVAILABLE
86
+ typedef void (^MBProgressHUDCompletionBlock)();
87
+ #endif
88
+
89
+
90
+ /**
91
+ * Displays a simple HUD window containing a progress indicator and two optional labels for short messages.
92
+ *
93
+ * This is a simple drop-in class for displaying a progress HUD view similar to Apple's private UIProgressHUD class.
94
+ * The MBProgressHUD window spans over the entire space given to it by the initWithFrame constructor and catches all
95
+ * user input on this region, thereby preventing the user operations on components below the view. The HUD itself is
96
+ * drawn centered as a rounded semi-transparent view which resizes depending on the user specified content.
97
+ *
98
+ * This view supports four modes of operation:
99
+ * - MBProgressHUDModeIndeterminate - shows a UIActivityIndicatorView
100
+ * - MBProgressHUDModeDeterminate - shows a custom round progress indicator
101
+ * - MBProgressHUDModeAnnularDeterminate - shows a custom annular progress indicator
102
+ * - MBProgressHUDModeCustomView - shows an arbitrary, user specified view (@see customView)
103
+ *
104
+ * All three modes can have optional labels assigned:
105
+ * - If the labelText property is set and non-empty then a label containing the provided content is placed below the
106
+ * indicator view.
107
+ * - If also the detailsLabelText property is set then another label is placed below the first label.
108
+ */
109
+ @interface MBProgressHUD : UIView
110
+
111
+ /**
112
+ * Creates a new HUD, adds it to provided view and shows it. The counterpart to this method is hideHUDForView:animated:.
113
+ *
114
+ * @param view The view that the HUD will be added to
115
+ * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use
116
+ * animations while appearing.
117
+ * @return A reference to the created HUD.
118
+ *
119
+ * @see hideHUDForView:animated:
120
+ * @see animationType
121
+ */
122
+ + (MB_INSTANCETYPE)showHUDAddedTo:(UIView *)view animated:(BOOL)animated;
123
+
124
+ /**
125
+ * Finds the top-most HUD subview and hides it. The counterpart to this method is showHUDAddedTo:animated:.
126
+ *
127
+ * @param view The view that is going to be searched for a HUD subview.
128
+ * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
129
+ * animations while disappearing.
130
+ * @return YES if a HUD was found and removed, NO otherwise.
131
+ *
132
+ * @see showHUDAddedTo:animated:
133
+ * @see animationType
134
+ */
135
+ + (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated;
136
+
137
+ /**
138
+ * Finds all the HUD subviews and hides them.
139
+ *
140
+ * @param view The view that is going to be searched for HUD subviews.
141
+ * @param animated If set to YES the HUDs will disappear using the current animationType. If set to NO the HUDs will not use
142
+ * animations while disappearing.
143
+ * @return the number of HUDs found and removed.
144
+ *
145
+ * @see hideHUDForView:animated:
146
+ * @see animationType
147
+ */
148
+ + (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated;
149
+
150
+ /**
151
+ * Finds the top-most HUD subview and returns it.
152
+ *
153
+ * @param view The view that is going to be searched.
154
+ * @return A reference to the last HUD subview discovered.
155
+ */
156
+ + (MB_INSTANCETYPE)HUDForView:(UIView *)view;
157
+
158
+ /**
159
+ * Finds all HUD subviews and returns them.
160
+ *
161
+ * @param view The view that is going to be searched.
162
+ * @return All found HUD views (array of MBProgressHUD objects).
163
+ */
164
+ + (NSArray *)allHUDsForView:(UIView *)view;
165
+
166
+ /**
167
+ * A convenience constructor that initializes the HUD with the window's bounds. Calls the designated constructor with
168
+ * window.bounds as the parameter.
169
+ *
170
+ * @param window The window instance that will provide the bounds for the HUD. Should be the same instance as
171
+ * the HUD's superview (i.e., the window that the HUD will be added to).
172
+ */
173
+ - (id)initWithWindow:(UIWindow *)window;
174
+
175
+ /**
176
+ * A convenience constructor that initializes the HUD with the view's bounds. Calls the designated constructor with
177
+ * view.bounds as the parameter
178
+ *
179
+ * @param view The view instance that will provide the bounds for the HUD. Should be the same instance as
180
+ * the HUD's superview (i.e., the view that the HUD will be added to).
181
+ */
182
+ - (id)initWithView:(UIView *)view;
183
+
184
+ /**
185
+ * Display the HUD. You need to make sure that the main thread completes its run loop soon after this method call so
186
+ * the user interface can be updated. Call this method when your task is already set-up to be executed in a new thread
187
+ * (e.g., when using something like NSOperation or calling an asynchronous call like NSURLRequest).
188
+ *
189
+ * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use
190
+ * animations while appearing.
191
+ *
192
+ * @see animationType
193
+ */
194
+ - (void)show:(BOOL)animated;
195
+
196
+ /**
197
+ * Hide the HUD. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to
198
+ * hide the HUD when your task completes.
199
+ *
200
+ * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
201
+ * animations while disappearing.
202
+ *
203
+ * @see animationType
204
+ */
205
+ - (void)hide:(BOOL)animated;
206
+
207
+ /**
208
+ * Hide the HUD after a delay. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to
209
+ * hide the HUD when your task completes.
210
+ *
211
+ * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
212
+ * animations while disappearing.
213
+ * @param delay Delay in seconds until the HUD is hidden.
214
+ *
215
+ * @see animationType
216
+ */
217
+ - (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay;
218
+
219
+ /**
220
+ * Shows the HUD while a background task is executing in a new thread, then hides the HUD.
221
+ *
222
+ * This method also takes care of autorelease pools so your method does not have to be concerned with setting up a
223
+ * pool.
224
+ *
225
+ * @param method The method to be executed while the HUD is shown. This method will be executed in a new thread.
226
+ * @param target The object that the target method belongs to.
227
+ * @param object An optional object to be passed to the method.
228
+ * @param animated If set to YES the HUD will (dis)appear using the current animationType. If set to NO the HUD will not use
229
+ * animations while (dis)appearing.
230
+ */
231
+ - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated;
232
+
233
+ #if NS_BLOCKS_AVAILABLE
234
+
235
+ /**
236
+ * Shows the HUD while a block is executing on a background queue, then hides the HUD.
237
+ *
238
+ * @see showAnimated:whileExecutingBlock:onQueue:completionBlock:
239
+ */
240
+ - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block;
241
+
242
+ /**
243
+ * Shows the HUD while a block is executing on a background queue, then hides the HUD.
244
+ *
245
+ * @see showAnimated:whileExecutingBlock:onQueue:completionBlock:
246
+ */
247
+ - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(MBProgressHUDCompletionBlock)completion;
248
+
249
+ /**
250
+ * Shows the HUD while a block is executing on the specified dispatch queue, then hides the HUD.
251
+ *
252
+ * @see showAnimated:whileExecutingBlock:onQueue:completionBlock:
253
+ */
254
+ - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue;
255
+
256
+ /**
257
+ * Shows the HUD while a block is executing on the specified dispatch queue, executes completion block on the main queue, and then hides the HUD.
258
+ *
259
+ * @param animated If set to YES the HUD will (dis)appear using the current animationType. If set to NO the HUD will
260
+ * not use animations while (dis)appearing.
261
+ * @param block The block to be executed while the HUD is shown.
262
+ * @param queue The dispatch queue on which the block should be executed.
263
+ * @param completion The block to be executed on completion.
264
+ *
265
+ * @see completionBlock
266
+ */
267
+ - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue
268
+ completionBlock:(MBProgressHUDCompletionBlock)completion;
269
+
270
+ /**
271
+ * A block that gets called after the HUD was completely hidden.
272
+ */
273
+ @property (copy) MBProgressHUDCompletionBlock completionBlock;
274
+
275
+ #endif
276
+
277
+ /**
278
+ * MBProgressHUD operation mode. The default is MBProgressHUDModeIndeterminate.
279
+ *
280
+ * @see MBProgressHUDMode
281
+ */
282
+ @property (assign) MBProgressHUDMode mode;
283
+
284
+ /**
285
+ * The animation type that should be used when the HUD is shown and hidden.
286
+ *
287
+ * @see MBProgressHUDAnimation
288
+ */
289
+ @property (assign) MBProgressHUDAnimation animationType;
290
+
291
+ /**
292
+ * The UIView (e.g., a UIImageView) to be shown when the HUD is in MBProgressHUDModeCustomView.
293
+ * For best results use a 37 by 37 pixel view (so the bounds match the built in indicator bounds).
294
+ */
295
+ @property (MB_STRONG) UIView *customView;
296
+
297
+ /**
298
+ * The HUD delegate object.
299
+ *
300
+ * @see MBProgressHUDDelegate
301
+ */
302
+ @property (MB_WEAK) id<MBProgressHUDDelegate> delegate;
303
+
304
+ /**
305
+ * An optional short message to be displayed below the activity indicator. The HUD is automatically resized to fit
306
+ * the entire text. If the text is too long it will get clipped by displaying "..." at the end. If left unchanged or
307
+ * set to @"", then no message is displayed.
308
+ */
309
+ @property (copy) NSString *labelText;
310
+
311
+ /**
312
+ * An optional details message displayed below the labelText message. This message is displayed only if the labelText
313
+ * property is also set and is different from an empty string (@""). The details text can span multiple lines.
314
+ */
315
+ @property (copy) NSString *detailsLabelText;
316
+
317
+ /**
318
+ * The opacity of the HUD window. Defaults to 0.8 (80% opacity).
319
+ */
320
+ @property (assign) float opacity;
321
+
322
+ /**
323
+ * The color of the HUD window. Defaults to black. If this property is set, color is set using
324
+ * this UIColor and the opacity property is not used. using retain because performing copy on
325
+ * UIColor base colors (like [UIColor greenColor]) cause problems with the copyZone.
326
+ */
327
+ @property (MB_STRONG) UIColor *color;
328
+
329
+ /**
330
+ * The x-axis offset of the HUD relative to the centre of the superview.
331
+ */
332
+ @property (assign) float xOffset;
333
+
334
+ /**
335
+ * The y-axis offset of the HUD relative to the centre of the superview.
336
+ */
337
+ @property (assign) float yOffset;
338
+
339
+ /**
340
+ * The amount of space between the HUD edge and the HUD elements (labels, indicators or custom views).
341
+ * Defaults to 20.0
342
+ */
343
+ @property (assign) float margin;
344
+
345
+ /**
346
+ * Cover the HUD background view with a radial gradient.
347
+ */
348
+ @property (assign) BOOL dimBackground;
349
+
350
+ /*
351
+ * Grace period is the time (in seconds) that the invoked method may be run without
352
+ * showing the HUD. If the task finishes before the grace time runs out, the HUD will
353
+ * not be shown at all.
354
+ * This may be used to prevent HUD display for very short tasks.
355
+ * Defaults to 0 (no grace time).
356
+ * Grace time functionality is only supported when the task status is known!
357
+ * @see taskInProgress
358
+ */
359
+ @property (assign) float graceTime;
360
+
361
+ /**
362
+ * The minimum time (in seconds) that the HUD is shown.
363
+ * This avoids the problem of the HUD being shown and than instantly hidden.
364
+ * Defaults to 0 (no minimum show time).
365
+ */
366
+ @property (assign) float minShowTime;
367
+
368
+ /**
369
+ * Indicates that the executed operation is in progress. Needed for correct graceTime operation.
370
+ * If you don't set a graceTime (different than 0.0) this does nothing.
371
+ * This property is automatically set when using showWhileExecuting:onTarget:withObject:animated:.
372
+ * When threading is done outside of the HUD (i.e., when the show: and hide: methods are used directly),
373
+ * you need to set this property when your task starts and completes in order to have normal graceTime
374
+ * functionality.
375
+ */
376
+ @property (assign) BOOL taskInProgress;
377
+
378
+ /**
379
+ * Removes the HUD from its parent view when hidden.
380
+ * Defaults to NO.
381
+ */
382
+ @property (assign) BOOL removeFromSuperViewOnHide;
383
+
384
+ /**
385
+ * Font to be used for the main label. Set this property if the default is not adequate.
386
+ */
387
+ @property (MB_STRONG) UIFont* labelFont;
388
+
389
+ /**
390
+ * Font to be used for the details label. Set this property if the default is not adequate.
391
+ */
392
+ @property (MB_STRONG) UIFont* detailsLabelFont;
393
+
394
+ /**
395
+ * The progress of the progress indicator, from 0.0 to 1.0. Defaults to 0.0.
396
+ */
397
+ @property (assign) float progress;
398
+
399
+ /**
400
+ * The minimum size of the HUD bezel. Defaults to CGSizeZero (no minimum size).
401
+ */
402
+ @property (assign) CGSize minSize;
403
+
404
+ /**
405
+ * Force the HUD dimensions to be equal if possible.
406
+ */
407
+ @property (assign, getter = isSquare) BOOL square;
408
+
409
+ @end
410
+
411
+
412
+ @protocol MBProgressHUDDelegate <NSObject>
413
+
414
+ @optional
415
+
416
+ /**
417
+ * Called after the HUD was fully hidden from the screen.
418
+ */
419
+ - (void)hudWasHidden:(MBProgressHUD *)hud;
420
+
421
+ @end
422
+
423
+
424
+ /**
425
+ * A progress view for showing definite progress by filling up a circle (pie chart).
426
+ */
427
+ @interface MBRoundProgressView : UIView
428
+
429
+ /**
430
+ * Progress (0.0 to 1.0)
431
+ */
432
+ @property (nonatomic, assign) float progress;
433
+
434
+ /**
435
+ * Indicator progress color.
436
+ * Defaults to white [UIColor whiteColor]
437
+ */
438
+ @property (nonatomic, MB_STRONG) UIColor *progressTintColor;
439
+
440
+ /**
441
+ * Indicator background (non-progress) color.
442
+ * Defaults to translucent white (alpha 0.1)
443
+ */
444
+ @property (nonatomic, MB_STRONG) UIColor *backgroundTintColor;
445
+
446
+ /*
447
+ * Display mode - NO = round or YES = annular. Defaults to round.
448
+ */
449
+ @property (nonatomic, assign, getter = isAnnular) BOOL annular;
450
+
451
+ @end
@@ -0,0 +1,865 @@
1
+ //
2
+ // MBProgressHUD.m
3
+ // Version 0.6
4
+ // Created by Matej Bukovinski on 2.4.09.
5
+ //
6
+
7
+ #import "MBProgressHUD.h"
8
+
9
+
10
+ #if __has_feature(objc_arc)
11
+ #define MB_AUTORELEASE(exp) exp
12
+ #define MB_RELEASE(exp) exp
13
+ #define MB_RETAIN(exp) exp
14
+ #else
15
+ #define MB_AUTORELEASE(exp) [exp autorelease]
16
+ #define MB_RELEASE(exp) [exp release]
17
+ #define MB_RETAIN(exp) [exp retain]
18
+ #endif
19
+
20
+ #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000
21
+ #define MBLabelAlignmentCenter NSTextAlignmentCenter
22
+ #else
23
+ #define MBLabelAlignmentCenter UITextAlignmentCenter
24
+ #endif
25
+
26
+
27
+ static const CGFloat kPadding = 4.f;
28
+ static const CGFloat kLabelFontSize = 16.f;
29
+ static const CGFloat kDetailsLabelFontSize = 12.f;
30
+
31
+
32
+ @interface MBProgressHUD ()
33
+
34
+ - (void)setupLabels;
35
+ - (void)registerForKVO;
36
+ - (void)unregisterFromKVO;
37
+ - (NSArray *)observableKeypaths;
38
+ - (void)registerForNotifications;
39
+ - (void)unregisterFromNotifications;
40
+ - (void)updateUIForKeypath:(NSString *)keyPath;
41
+ - (void)hideUsingAnimation:(BOOL)animated;
42
+ - (void)showUsingAnimation:(BOOL)animated;
43
+ - (void)done;
44
+ - (void)updateIndicators;
45
+ - (void)handleGraceTimer:(NSTimer *)theTimer;
46
+ - (void)handleMinShowTimer:(NSTimer *)theTimer;
47
+ - (void)setTransformForCurrentOrientation:(BOOL)animated;
48
+ - (void)cleanUp;
49
+ - (void)launchExecution;
50
+ - (void)deviceOrientationDidChange:(NSNotification *)notification;
51
+ - (void)hideDelayed:(NSNumber *)animated;
52
+
53
+ @property (atomic, MB_STRONG) UIView *indicator;
54
+ @property (atomic, MB_STRONG) NSTimer *graceTimer;
55
+ @property (atomic, MB_STRONG) NSTimer *minShowTimer;
56
+ @property (atomic, MB_STRONG) NSDate *showStarted;
57
+ @property (atomic, assign) CGSize size;
58
+
59
+ @end
60
+
61
+
62
+ @implementation MBProgressHUD {
63
+ BOOL useAnimation;
64
+ SEL methodForExecution;
65
+ id targetForExecution;
66
+ id objectForExecution;
67
+ UILabel *label;
68
+ UILabel *detailsLabel;
69
+ BOOL isFinished;
70
+ CGAffineTransform rotationTransform;
71
+ }
72
+
73
+ #pragma mark - Properties
74
+
75
+ @synthesize animationType;
76
+ @synthesize delegate;
77
+ @synthesize opacity;
78
+ @synthesize color;
79
+ @synthesize labelFont;
80
+ @synthesize detailsLabelFont;
81
+ @synthesize indicator;
82
+ @synthesize xOffset;
83
+ @synthesize yOffset;
84
+ @synthesize minSize;
85
+ @synthesize square;
86
+ @synthesize margin;
87
+ @synthesize dimBackground;
88
+ @synthesize graceTime;
89
+ @synthesize minShowTime;
90
+ @synthesize graceTimer;
91
+ @synthesize minShowTimer;
92
+ @synthesize taskInProgress;
93
+ @synthesize removeFromSuperViewOnHide;
94
+ @synthesize customView;
95
+ @synthesize showStarted;
96
+ @synthesize mode;
97
+ @synthesize labelText;
98
+ @synthesize detailsLabelText;
99
+ @synthesize progress;
100
+ @synthesize size;
101
+ #if NS_BLOCKS_AVAILABLE
102
+ @synthesize completionBlock;
103
+ #endif
104
+
105
+ #pragma mark - Class methods
106
+
107
+ + (MB_INSTANCETYPE)showHUDAddedTo:(UIView *)view animated:(BOOL)animated {
108
+ MBProgressHUD *hud = [[self alloc] initWithView:view];
109
+ [view addSubview:hud];
110
+ [hud show:animated];
111
+ return MB_AUTORELEASE(hud);
112
+ }
113
+
114
+ + (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated {
115
+ MBProgressHUD *hud = [self HUDForView:view];
116
+ if (hud != nil) {
117
+ hud.removeFromSuperViewOnHide = YES;
118
+ [hud hide:animated];
119
+ return YES;
120
+ }
121
+ return NO;
122
+ }
123
+
124
+ + (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated {
125
+ NSArray *huds = [MBProgressHUD allHUDsForView:view];
126
+ for (MBProgressHUD *hud in huds) {
127
+ hud.removeFromSuperViewOnHide = YES;
128
+ [hud hide:animated];
129
+ }
130
+ return [huds count];
131
+ }
132
+
133
+ + (MB_INSTANCETYPE)HUDForView:(UIView *)view {
134
+ NSEnumerator *subviewsEnum = [view.subviews reverseObjectEnumerator];
135
+ for (UIView *subview in subviewsEnum) {
136
+ if ([subview isKindOfClass:self]) {
137
+ return (MBProgressHUD *)subview;
138
+ }
139
+ }
140
+ return nil;
141
+ }
142
+
143
+ + (NSArray *)allHUDsForView:(UIView *)view {
144
+ NSMutableArray *huds = [NSMutableArray array];
145
+ NSArray *subviews = view.subviews;
146
+ for (UIView *aView in subviews) {
147
+ if ([aView isKindOfClass:self]) {
148
+ [huds addObject:aView];
149
+ }
150
+ }
151
+ return [NSArray arrayWithArray:huds];
152
+ }
153
+
154
+ #pragma mark - Lifecycle
155
+
156
+ - (id)initWithFrame:(CGRect)frame {
157
+ self = [super initWithFrame:frame];
158
+ if (self) {
159
+ // Set default values for properties
160
+ self.animationType = MBProgressHUDAnimationFade;
161
+ self.mode = MBProgressHUDModeIndeterminate;
162
+ self.labelText = nil;
163
+ self.detailsLabelText = nil;
164
+ self.opacity = 0.8f;
165
+ self.color = nil;
166
+ self.labelFont = [UIFont boldSystemFontOfSize:kLabelFontSize];
167
+ self.detailsLabelFont = [UIFont boldSystemFontOfSize:kDetailsLabelFontSize];
168
+ self.xOffset = 0.0f;
169
+ self.yOffset = 0.0f;
170
+ self.dimBackground = NO;
171
+ self.margin = 20.0f;
172
+ self.graceTime = 0.0f;
173
+ self.minShowTime = 0.0f;
174
+ self.removeFromSuperViewOnHide = NO;
175
+ self.minSize = CGSizeZero;
176
+ self.square = NO;
177
+ self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin
178
+ | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
179
+
180
+ // Transparent background
181
+ self.opaque = NO;
182
+ self.backgroundColor = [UIColor clearColor];
183
+ // Make it invisible for now
184
+ self.alpha = 0.0f;
185
+
186
+ taskInProgress = NO;
187
+ rotationTransform = CGAffineTransformIdentity;
188
+
189
+ [self setupLabels];
190
+ [self updateIndicators];
191
+ [self registerForKVO];
192
+ [self registerForNotifications];
193
+ }
194
+ return self;
195
+ }
196
+
197
+ - (id)initWithView:(UIView *)view {
198
+ NSAssert(view, @"View must not be nil.");
199
+ return [self initWithFrame:view.bounds];
200
+ }
201
+
202
+ - (id)initWithWindow:(UIWindow *)window {
203
+ return [self initWithView:window];
204
+ }
205
+
206
+ - (void)dealloc {
207
+ [self unregisterFromNotifications];
208
+ [self unregisterFromKVO];
209
+ #if !__has_feature(objc_arc)
210
+ [color release];
211
+ [indicator release];
212
+ [label release];
213
+ [detailsLabel release];
214
+ [labelText release];
215
+ [detailsLabelText release];
216
+ [graceTimer release];
217
+ [minShowTimer release];
218
+ [showStarted release];
219
+ [customView release];
220
+ #if NS_BLOCKS_AVAILABLE
221
+ [completionBlock release];
222
+ #endif
223
+ [super dealloc];
224
+ #endif
225
+ }
226
+
227
+ #pragma mark - Show & hide
228
+
229
+ - (void)show:(BOOL)animated {
230
+ useAnimation = animated;
231
+ // If the grace time is set postpone the HUD display
232
+ if (self.graceTime > 0.0) {
233
+ self.graceTimer = [NSTimer scheduledTimerWithTimeInterval:self.graceTime target:self
234
+ selector:@selector(handleGraceTimer:) userInfo:nil repeats:NO];
235
+ }
236
+ // ... otherwise show the HUD imediately
237
+ else {
238
+ [self setNeedsDisplay];
239
+ [self showUsingAnimation:useAnimation];
240
+ }
241
+ }
242
+
243
+ - (void)hide:(BOOL)animated {
244
+ useAnimation = animated;
245
+ // If the minShow time is set, calculate how long the hud was shown,
246
+ // and pospone the hiding operation if necessary
247
+ if (self.minShowTime > 0.0 && showStarted) {
248
+ NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:showStarted];
249
+ if (interv < self.minShowTime) {
250
+ self.minShowTimer = [NSTimer scheduledTimerWithTimeInterval:(self.minShowTime - interv) target:self
251
+ selector:@selector(handleMinShowTimer:) userInfo:nil repeats:NO];
252
+ return;
253
+ }
254
+ }
255
+ // ... otherwise hide the HUD immediately
256
+ [self hideUsingAnimation:useAnimation];
257
+ }
258
+
259
+ - (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay {
260
+ [self performSelector:@selector(hideDelayed:) withObject:[NSNumber numberWithBool:animated] afterDelay:delay];
261
+ }
262
+
263
+ - (void)hideDelayed:(NSNumber *)animated {
264
+ [self hide:[animated boolValue]];
265
+ }
266
+
267
+ #pragma mark - Timer callbacks
268
+
269
+ - (void)handleGraceTimer:(NSTimer *)theTimer {
270
+ // Show the HUD only if the task is still running
271
+ if (taskInProgress) {
272
+ [self setNeedsDisplay];
273
+ [self showUsingAnimation:useAnimation];
274
+ }
275
+ }
276
+
277
+ - (void)handleMinShowTimer:(NSTimer *)theTimer {
278
+ [self hideUsingAnimation:useAnimation];
279
+ }
280
+
281
+ #pragma mark - View Hierrarchy
282
+
283
+ - (void)didMoveToSuperview {
284
+ // We need to take care of rotation ourselfs if we're adding the HUD to a window
285
+ if ([self.superview isKindOfClass:[UIWindow class]]) {
286
+ [self setTransformForCurrentOrientation:NO];
287
+ }
288
+ }
289
+
290
+ #pragma mark - Internal show & hide operations
291
+
292
+ - (void)showUsingAnimation:(BOOL)animated {
293
+ if (animated && animationType == MBProgressHUDAnimationZoomIn) {
294
+ self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(0.5f, 0.5f));
295
+ } else if (animated && animationType == MBProgressHUDAnimationZoomOut) {
296
+ self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(1.5f, 1.5f));
297
+ }
298
+ self.showStarted = [NSDate date];
299
+ // Fade in
300
+ if (animated) {
301
+ [UIView beginAnimations:nil context:NULL];
302
+ [UIView setAnimationDuration:0.30];
303
+ self.alpha = 1.0f;
304
+ if (animationType == MBProgressHUDAnimationZoomIn || animationType == MBProgressHUDAnimationZoomOut) {
305
+ self.transform = rotationTransform;
306
+ }
307
+ [UIView commitAnimations];
308
+ }
309
+ else {
310
+ self.alpha = 1.0f;
311
+ }
312
+ }
313
+
314
+ - (void)hideUsingAnimation:(BOOL)animated {
315
+ // Fade out
316
+ if (animated && showStarted) {
317
+ [UIView beginAnimations:nil context:NULL];
318
+ [UIView setAnimationDuration:0.30];
319
+ [UIView setAnimationDelegate:self];
320
+ [UIView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];
321
+ // 0.02 prevents the hud from passing through touches during the animation the hud will get completely hidden
322
+ // in the done method
323
+ if (animationType == MBProgressHUDAnimationZoomIn) {
324
+ self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(1.5f, 1.5f));
325
+ } else if (animationType == MBProgressHUDAnimationZoomOut) {
326
+ self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(0.5f, 0.5f));
327
+ }
328
+
329
+ self.alpha = 0.02f;
330
+ [UIView commitAnimations];
331
+ }
332
+ else {
333
+ self.alpha = 0.0f;
334
+ [self done];
335
+ }
336
+ self.showStarted = nil;
337
+ }
338
+
339
+ - (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void*)context {
340
+ [self done];
341
+ }
342
+
343
+ - (void)done {
344
+ isFinished = YES;
345
+ self.alpha = 0.0f;
346
+ if ([delegate respondsToSelector:@selector(hudWasHidden:)]) {
347
+ [delegate performSelector:@selector(hudWasHidden:) withObject:self];
348
+ }
349
+ #if NS_BLOCKS_AVAILABLE
350
+ if (self.completionBlock) {
351
+ self.completionBlock();
352
+ self.completionBlock = NULL;
353
+ }
354
+ #endif
355
+ if (removeFromSuperViewOnHide) {
356
+ [self removeFromSuperview];
357
+ }
358
+ }
359
+
360
+ #pragma mark - Threading
361
+
362
+ - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated {
363
+ methodForExecution = method;
364
+ targetForExecution = MB_RETAIN(target);
365
+ objectForExecution = MB_RETAIN(object);
366
+ // Launch execution in new thread
367
+ self.taskInProgress = YES;
368
+ [NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil];
369
+ // Show HUD view
370
+ [self show:animated];
371
+ }
372
+
373
+ #if NS_BLOCKS_AVAILABLE
374
+
375
+ - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block {
376
+ dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
377
+ [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:NULL];
378
+ }
379
+
380
+ - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(void (^)())completion {
381
+ dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
382
+ [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:completion];
383
+ }
384
+
385
+ - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue {
386
+ [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:NULL];
387
+ }
388
+
389
+ - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue
390
+ completionBlock:(MBProgressHUDCompletionBlock)completion {
391
+ self.taskInProgress = YES;
392
+ self.completionBlock = completion;
393
+ dispatch_async(queue, ^(void) {
394
+ block();
395
+ dispatch_async(dispatch_get_main_queue(), ^(void) {
396
+ [self cleanUp];
397
+ });
398
+ });
399
+ [self show:animated];
400
+ }
401
+
402
+ #endif
403
+
404
+ - (void)launchExecution {
405
+ @autoreleasepool {
406
+ #pragma clang diagnostic push
407
+ #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
408
+ // Start executing the requested task
409
+ [targetForExecution performSelector:methodForExecution withObject:objectForExecution];
410
+ #pragma clang diagnostic pop
411
+ // Task completed, update view in main thread (note: view operations should
412
+ // be done only in the main thread)
413
+ [self performSelectorOnMainThread:@selector(cleanUp) withObject:nil waitUntilDone:NO];
414
+ }
415
+ }
416
+
417
+ - (void)cleanUp {
418
+ taskInProgress = NO;
419
+ self.indicator = nil;
420
+ #if !__has_feature(objc_arc)
421
+ [targetForExecution release];
422
+ [objectForExecution release];
423
+ #else
424
+ targetForExecution = nil;
425
+ objectForExecution = nil;
426
+ #endif
427
+ [self hide:useAnimation];
428
+ }
429
+
430
+ #pragma mark - UI
431
+
432
+ - (void)setupLabels {
433
+ label = [[UILabel alloc] initWithFrame:self.bounds];
434
+ label.adjustsFontSizeToFitWidth = NO;
435
+ label.textAlignment = MBLabelAlignmentCenter;
436
+ label.opaque = NO;
437
+ label.backgroundColor = [UIColor clearColor];
438
+ label.textColor = [UIColor whiteColor];
439
+ label.font = self.labelFont;
440
+ label.text = self.labelText;
441
+ [self addSubview:label];
442
+
443
+ detailsLabel = [[UILabel alloc] initWithFrame:self.bounds];
444
+ detailsLabel.font = self.detailsLabelFont;
445
+ detailsLabel.adjustsFontSizeToFitWidth = NO;
446
+ detailsLabel.textAlignment = MBLabelAlignmentCenter;
447
+ detailsLabel.opaque = NO;
448
+ detailsLabel.backgroundColor = [UIColor clearColor];
449
+ detailsLabel.textColor = [UIColor whiteColor];
450
+ detailsLabel.numberOfLines = 0;
451
+ detailsLabel.font = self.detailsLabelFont;
452
+ detailsLabel.text = self.detailsLabelText;
453
+ [self addSubview:detailsLabel];
454
+ }
455
+
456
+ - (void)updateIndicators {
457
+
458
+ BOOL isActivityIndicator = [indicator isKindOfClass:[UIActivityIndicatorView class]];
459
+ BOOL isRoundIndicator = [indicator isKindOfClass:[MBRoundProgressView class]];
460
+
461
+ if (mode == MBProgressHUDModeIndeterminate && !isActivityIndicator) {
462
+ // Update to indeterminate indicator
463
+ [indicator removeFromSuperview];
464
+ self.indicator = MB_AUTORELEASE([[UIActivityIndicatorView alloc]
465
+ initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]);
466
+ [(UIActivityIndicatorView *)indicator startAnimating];
467
+ [self addSubview:indicator];
468
+ }
469
+ else if (mode == MBProgressHUDModeDeterminate || mode == MBProgressHUDModeAnnularDeterminate) {
470
+ if (!isRoundIndicator) {
471
+ // Update to determinante indicator
472
+ [indicator removeFromSuperview];
473
+ self.indicator = MB_AUTORELEASE([[MBRoundProgressView alloc] init]);
474
+ [self addSubview:indicator];
475
+ }
476
+ if (mode == MBProgressHUDModeAnnularDeterminate) {
477
+ [(MBRoundProgressView *)indicator setAnnular:YES];
478
+ }
479
+ }
480
+ else if (mode == MBProgressHUDModeCustomView && customView != indicator) {
481
+ // Update custom view indicator
482
+ [indicator removeFromSuperview];
483
+ self.indicator = customView;
484
+ [self addSubview:indicator];
485
+ } else if (mode == MBProgressHUDModeText) {
486
+ [indicator removeFromSuperview];
487
+ self.indicator = nil;
488
+ }
489
+ }
490
+
491
+ #pragma mark - Layout
492
+
493
+ - (void)layoutSubviews {
494
+
495
+ // Entirely cover the parent view
496
+ UIView *parent = self.superview;
497
+ if (parent) {
498
+ self.frame = parent.bounds;
499
+ }
500
+ CGRect bounds = self.bounds;
501
+
502
+ // Determine the total widt and height needed
503
+ CGFloat maxWidth = bounds.size.width - 4 * margin;
504
+ CGSize totalSize = CGSizeZero;
505
+
506
+ CGRect indicatorF = indicator.bounds;
507
+ indicatorF.size.width = MIN(indicatorF.size.width, maxWidth);
508
+ totalSize.width = MAX(totalSize.width, indicatorF.size.width);
509
+ totalSize.height += indicatorF.size.height;
510
+
511
+ CGSize labelSize = [label.text sizeWithFont:label.font];
512
+ labelSize.width = MIN(labelSize.width, maxWidth);
513
+ totalSize.width = MAX(totalSize.width, labelSize.width);
514
+ totalSize.height += labelSize.height;
515
+ if (labelSize.height > 0.f && indicatorF.size.height > 0.f) {
516
+ totalSize.height += kPadding;
517
+ }
518
+
519
+ CGFloat remainingHeight = bounds.size.height - totalSize.height - kPadding - 4 * margin;
520
+ CGSize maxSize = CGSizeMake(maxWidth, remainingHeight);
521
+ CGSize detailsLabelSize = [detailsLabel.text sizeWithFont:detailsLabel.font
522
+ constrainedToSize:maxSize lineBreakMode:detailsLabel.lineBreakMode];
523
+ totalSize.width = MAX(totalSize.width, detailsLabelSize.width);
524
+ totalSize.height += detailsLabelSize.height;
525
+ if (detailsLabelSize.height > 0.f && (indicatorF.size.height > 0.f || labelSize.height > 0.f)) {
526
+ totalSize.height += kPadding;
527
+ }
528
+
529
+ totalSize.width += 2 * margin;
530
+ totalSize.height += 2 * margin;
531
+
532
+ // Position elements
533
+ CGFloat yPos = roundf(((bounds.size.height - totalSize.height) / 2)) + margin + yOffset;
534
+ CGFloat xPos = xOffset;
535
+ indicatorF.origin.y = yPos;
536
+ indicatorF.origin.x = roundf((bounds.size.width - indicatorF.size.width) / 2) + xPos;
537
+ indicator.frame = indicatorF;
538
+ yPos += indicatorF.size.height;
539
+
540
+ if (labelSize.height > 0.f && indicatorF.size.height > 0.f) {
541
+ yPos += kPadding;
542
+ }
543
+ CGRect labelF;
544
+ labelF.origin.y = yPos;
545
+ labelF.origin.x = roundf((bounds.size.width - labelSize.width) / 2) + xPos;
546
+ labelF.size = labelSize;
547
+ label.frame = labelF;
548
+ yPos += labelF.size.height;
549
+
550
+ if (detailsLabelSize.height > 0.f && (indicatorF.size.height > 0.f || labelSize.height > 0.f)) {
551
+ yPos += kPadding;
552
+ }
553
+ CGRect detailsLabelF;
554
+ detailsLabelF.origin.y = yPos;
555
+ detailsLabelF.origin.x = roundf((bounds.size.width - detailsLabelSize.width) / 2) + xPos;
556
+ detailsLabelF.size = detailsLabelSize;
557
+ detailsLabel.frame = detailsLabelF;
558
+
559
+ // Enforce minsize and quare rules
560
+ if (square) {
561
+ CGFloat max = MAX(totalSize.width, totalSize.height);
562
+ if (max <= bounds.size.width - 2 * margin) {
563
+ totalSize.width = max;
564
+ }
565
+ if (max <= bounds.size.height - 2 * margin) {
566
+ totalSize.height = max;
567
+ }
568
+ }
569
+ if (totalSize.width < minSize.width) {
570
+ totalSize.width = minSize.width;
571
+ }
572
+ if (totalSize.height < minSize.height) {
573
+ totalSize.height = minSize.height;
574
+ }
575
+
576
+ self.size = totalSize;
577
+ }
578
+
579
+ #pragma mark BG Drawing
580
+
581
+ - (void)drawRect:(CGRect)rect {
582
+
583
+ CGContextRef context = UIGraphicsGetCurrentContext();
584
+ UIGraphicsPushContext(context);
585
+
586
+ if (self.dimBackground) {
587
+ //Gradient colours
588
+ size_t gradLocationsNum = 2;
589
+ CGFloat gradLocations[2] = {0.0f, 1.0f};
590
+ CGFloat gradColors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f};
591
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
592
+ CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradColors, gradLocations, gradLocationsNum);
593
+ CGColorSpaceRelease(colorSpace);
594
+ //Gradient center
595
+ CGPoint gradCenter= CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
596
+ //Gradient radius
597
+ float gradRadius = MIN(self.bounds.size.width , self.bounds.size.height) ;
598
+ //Gradient draw
599
+ CGContextDrawRadialGradient (context, gradient, gradCenter,
600
+ 0, gradCenter, gradRadius,
601
+ kCGGradientDrawsAfterEndLocation);
602
+ CGGradientRelease(gradient);
603
+ }
604
+
605
+ // Set background rect color
606
+ if (self.color) {
607
+ CGContextSetFillColorWithColor(context, self.color.CGColor);
608
+ } else {
609
+ CGContextSetGrayFillColor(context, 0.0f, self.opacity);
610
+ }
611
+
612
+
613
+ // Center HUD
614
+ CGRect allRect = self.bounds;
615
+ // Draw rounded HUD backgroud rect
616
+ CGRect boxRect = CGRectMake(roundf((allRect.size.width - size.width) / 2) + self.xOffset,
617
+ roundf((allRect.size.height - size.height) / 2) + self.yOffset, size.width, size.height);
618
+ float radius = 10.0f;
619
+ CGContextBeginPath(context);
620
+ CGContextMoveToPoint(context, CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect));
621
+ CGContextAddArc(context, CGRectGetMaxX(boxRect) - radius, CGRectGetMinY(boxRect) + radius, radius, 3 * (float)M_PI / 2, 0, 0);
622
+ CGContextAddArc(context, CGRectGetMaxX(boxRect) - radius, CGRectGetMaxY(boxRect) - radius, radius, 0, (float)M_PI / 2, 0);
623
+ CGContextAddArc(context, CGRectGetMinX(boxRect) + radius, CGRectGetMaxY(boxRect) - radius, radius, (float)M_PI / 2, (float)M_PI, 0);
624
+ CGContextAddArc(context, CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect) + radius, radius, (float)M_PI, 3 * (float)M_PI / 2, 0);
625
+ CGContextClosePath(context);
626
+ CGContextFillPath(context);
627
+
628
+ UIGraphicsPopContext();
629
+ }
630
+
631
+ #pragma mark - KVO
632
+
633
+ - (void)registerForKVO {
634
+ for (NSString *keyPath in [self observableKeypaths]) {
635
+ [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];
636
+ }
637
+ }
638
+
639
+ - (void)unregisterFromKVO {
640
+ for (NSString *keyPath in [self observableKeypaths]) {
641
+ [self removeObserver:self forKeyPath:keyPath];
642
+ }
643
+ }
644
+
645
+ - (NSArray *)observableKeypaths {
646
+ return [NSArray arrayWithObjects:@"mode", @"customView", @"labelText", @"labelFont",
647
+ @"detailsLabelText", @"detailsLabelFont", @"progress", nil];
648
+ }
649
+
650
+ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
651
+ if (![NSThread isMainThread]) {
652
+ [self performSelectorOnMainThread:@selector(updateUIForKeypath:) withObject:keyPath waitUntilDone:NO];
653
+ } else {
654
+ [self updateUIForKeypath:keyPath];
655
+ }
656
+ }
657
+
658
+ - (void)updateUIForKeypath:(NSString *)keyPath {
659
+ if ([keyPath isEqualToString:@"mode"] || [keyPath isEqualToString:@"customView"]) {
660
+ [self updateIndicators];
661
+ } else if ([keyPath isEqualToString:@"labelText"]) {
662
+ label.text = self.labelText;
663
+ } else if ([keyPath isEqualToString:@"labelFont"]) {
664
+ label.font = self.labelFont;
665
+ } else if ([keyPath isEqualToString:@"detailsLabelText"]) {
666
+ detailsLabel.text = self.detailsLabelText;
667
+ } else if ([keyPath isEqualToString:@"detailsLabelFont"]) {
668
+ detailsLabel.font = self.detailsLabelFont;
669
+ } else if ([keyPath isEqualToString:@"progress"]) {
670
+ if ([indicator respondsToSelector:@selector(setProgress:)]) {
671
+ [(id)indicator setProgress:progress];
672
+ }
673
+ return;
674
+ }
675
+ [self setNeedsLayout];
676
+ [self setNeedsDisplay];
677
+ }
678
+
679
+ #pragma mark - Notifications
680
+
681
+ - (void)registerForNotifications {
682
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
683
+ [nc addObserver:self selector:@selector(deviceOrientationDidChange:)
684
+ name:UIDeviceOrientationDidChangeNotification object:nil];
685
+ }
686
+
687
+ - (void)unregisterFromNotifications {
688
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
689
+ }
690
+
691
+ - (void)deviceOrientationDidChange:(NSNotification *)notification {
692
+ UIView *superview = self.superview;
693
+ if (!superview) {
694
+ return;
695
+ } else if ([superview isKindOfClass:[UIWindow class]]) {
696
+ [self setTransformForCurrentOrientation:YES];
697
+ } else {
698
+ self.bounds = self.superview.bounds;
699
+ [self setNeedsDisplay];
700
+ }
701
+ }
702
+
703
+ - (void)setTransformForCurrentOrientation:(BOOL)animated {
704
+ // Stay in sync with the superview
705
+ if (self.superview) {
706
+ self.bounds = self.superview.bounds;
707
+ [self setNeedsDisplay];
708
+ }
709
+
710
+ UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
711
+ CGFloat radians = 0;
712
+ if (UIInterfaceOrientationIsLandscape(orientation)) {
713
+ if (orientation == UIInterfaceOrientationLandscapeLeft) { radians = -(CGFloat)M_PI_2; }
714
+ else { radians = (CGFloat)M_PI_2; }
715
+ // Window coordinates differ!
716
+ self.bounds = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.width);
717
+ } else {
718
+ if (orientation == UIInterfaceOrientationPortraitUpsideDown) { radians = (CGFloat)M_PI; }
719
+ else { radians = 0; }
720
+ }
721
+ rotationTransform = CGAffineTransformMakeRotation(radians);
722
+
723
+ if (animated) {
724
+ [UIView beginAnimations:nil context:nil];
725
+ }
726
+ [self setTransform:rotationTransform];
727
+ if (animated) {
728
+ [UIView commitAnimations];
729
+ }
730
+ }
731
+
732
+ @end
733
+
734
+
735
+ @implementation MBRoundProgressView {
736
+ float _progress;
737
+ BOOL _annular;
738
+ }
739
+
740
+ #pragma mark - Properties
741
+
742
+ @synthesize progressTintColor = _progressTintColor;
743
+ @synthesize backgroundTintColor = _backgroundTintColor;
744
+
745
+ #pragma mark - Accessors
746
+
747
+ - (float)progress {
748
+ return _progress;
749
+ }
750
+
751
+ - (void)setProgress:(float)progress {
752
+ _progress = progress;
753
+ [self setNeedsDisplay];
754
+ }
755
+
756
+ - (BOOL)isAnnular {
757
+ return _annular;
758
+ }
759
+
760
+ - (void)setAnnular:(BOOL)annular {
761
+ _annular = annular;
762
+ [self setNeedsDisplay];
763
+ }
764
+
765
+ #pragma mark - Lifecycle
766
+
767
+ - (id)init {
768
+ return [self initWithFrame:CGRectMake(0.f, 0.f, 37.f, 37.f)];
769
+ }
770
+
771
+ - (id)initWithFrame:(CGRect)frame {
772
+ self = [super initWithFrame:frame];
773
+ if (self) {
774
+ self.backgroundColor = [UIColor clearColor];
775
+ self.opaque = NO;
776
+ _progress = 0.f;
777
+ _annular = NO;
778
+ _progressTintColor = [[UIColor alloc] initWithWhite:1.f alpha:1.f];
779
+ _backgroundTintColor = [[UIColor alloc] initWithWhite:1.f alpha:.1f];
780
+ [self registerForKVO];
781
+ }
782
+ return self;
783
+ }
784
+
785
+ - (void)dealloc {
786
+ [self unregisterFromKVO];
787
+ #if !__has_feature(objc_arc)
788
+ [_progressTintColor release];
789
+ [_backgroundTintColor release];
790
+ [super dealloc];
791
+ #endif
792
+ }
793
+
794
+ #pragma mark - Drawing
795
+
796
+ - (void)drawRect:(CGRect)rect {
797
+
798
+ CGRect allRect = self.bounds;
799
+ CGRect circleRect = CGRectInset(allRect, 2.0f, 2.0f);
800
+ CGContextRef context = UIGraphicsGetCurrentContext();
801
+
802
+ if (_annular) {
803
+ // Draw background
804
+ CGFloat lineWidth = 5.f;
805
+ UIBezierPath *processBackgroundPath = [UIBezierPath bezierPath];
806
+ processBackgroundPath.lineWidth = lineWidth;
807
+ processBackgroundPath.lineCapStyle = kCGLineCapRound;
808
+ CGPoint center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
809
+ CGFloat radius = (self.bounds.size.width - lineWidth)/2;
810
+ CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees
811
+ CGFloat endAngle = (2 * (float)M_PI) + startAngle;
812
+ [processBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
813
+ [_backgroundTintColor set];
814
+ [processBackgroundPath stroke];
815
+ // Draw progress
816
+ UIBezierPath *processPath = [UIBezierPath bezierPath];
817
+ processPath.lineCapStyle = kCGLineCapRound;
818
+ processPath.lineWidth = lineWidth;
819
+ endAngle = (self.progress * 2 * (float)M_PI) + startAngle;
820
+ [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
821
+ [_progressTintColor set];
822
+ [processPath stroke];
823
+ } else {
824
+ // Draw background
825
+ [_progressTintColor setStroke];
826
+ [_backgroundTintColor setFill];
827
+ CGContextSetLineWidth(context, 2.0f);
828
+ CGContextFillEllipseInRect(context, circleRect);
829
+ CGContextStrokeEllipseInRect(context, circleRect);
830
+ // Draw progress
831
+ CGPoint center = CGPointMake(allRect.size.width / 2, allRect.size.height / 2);
832
+ CGFloat radius = (allRect.size.width - 4) / 2;
833
+ CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees
834
+ CGFloat endAngle = (self.progress * 2 * (float)M_PI) + startAngle;
835
+ CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 1.0f); // white
836
+ CGContextMoveToPoint(context, center.x, center.y);
837
+ CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);
838
+ CGContextClosePath(context);
839
+ CGContextFillPath(context);
840
+ }
841
+ }
842
+
843
+ #pragma mark - KVO
844
+
845
+ - (void)registerForKVO {
846
+ for (NSString *keyPath in [self observableKeypaths]) {
847
+ [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];
848
+ }
849
+ }
850
+
851
+ - (void)unregisterFromKVO {
852
+ for (NSString *keyPath in [self observableKeypaths]) {
853
+ [self removeObserver:self forKeyPath:keyPath];
854
+ }
855
+ }
856
+
857
+ - (NSArray *)observableKeypaths {
858
+ return [NSArray arrayWithObjects:@"progressTintColor", @"backgroundTintColor", nil];
859
+ }
860
+
861
+ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
862
+ [self setNeedsDisplay];
863
+ }
864
+
865
+ @end