From bcf9dc8c72acfedc62f987f4097ed36683c2d17f Mon Sep 17 00:00:00 2001 From: marcoschmickler Date: Mon, 21 Aug 2023 19:51:43 +0200 Subject: [PATCH] MasterDetail --- Podfile | 13 +- Pods/Nimbus/LICENSE | 202 ----- Pods/Nimbus/README.mdown | 13 - .../src/core/src/NIActions+Subclassing.h | 37 - Pods/Nimbus/src/core/src/NIActions.h | 422 ---------- Pods/Nimbus/src/core/src/NIActions.m | 247 ------ Pods/Nimbus/src/core/src/NIButtonUtilities.h | 92 --- Pods/Nimbus/src/core/src/NIButtonUtilities.m | 83 -- Pods/Nimbus/src/core/src/NICommonMetrics.h | 172 ---- Pods/Nimbus/src/core/src/NICommonMetrics.m | 69 -- Pods/Nimbus/src/core/src/NIDebuggingTools.h | 194 ----- Pods/Nimbus/src/core/src/NIDebuggingTools.m | 61 -- .../Nimbus/src/core/src/NIDeviceOrientation.h | 92 --- .../Nimbus/src/core/src/NIDeviceOrientation.m | 76 -- Pods/Nimbus/src/core/src/NIError.h | 54 -- Pods/Nimbus/src/core/src/NIError.m | 24 - .../Nimbus/src/core/src/NIFoundationMethods.h | 421 ---------- .../Nimbus/src/core/src/NIFoundationMethods.m | 314 -------- Pods/Nimbus/src/core/src/NIImageUtilities.h | 48 -- Pods/Nimbus/src/core/src/NIImageUtilities.m | 24 - Pods/Nimbus/src/core/src/NIInMemoryCache.h | 316 -------- Pods/Nimbus/src/core/src/NIInMemoryCache.m | 453 ----------- Pods/Nimbus/src/core/src/NINetworkActivity.h | 101 --- Pods/Nimbus/src/core/src/NINetworkActivity.m | 171 ---- .../core/src/NINonEmptyCollectionTesting.h | 58 -- .../core/src/NINonEmptyCollectionTesting.m | 35 - .../src/core/src/NINonRetainingCollections.h | 65 -- .../src/core/src/NINonRetainingCollections.m | 36 - .../src/core/src/NIOperations+Subclassing.h | 20 - Pods/Nimbus/src/core/src/NIOperations.h | 209 ----- Pods/Nimbus/src/core/src/NIOperations.m | 111 --- Pods/Nimbus/src/core/src/NIPaths.h | 69 -- Pods/Nimbus/src/core/src/NIPaths.m | 61 -- .../src/core/src/NIPreprocessorMacros.h | 141 ---- .../core/src/NIRuntimeClassModifications.h | 74 -- .../core/src/NIRuntimeClassModifications.m | 37 - Pods/Nimbus/src/core/src/NISDKAvailability.h | 257 ------ Pods/Nimbus/src/core/src/NISDKAvailability.m | 72 -- Pods/Nimbus/src/core/src/NISnapshotRotation.h | 224 ------ Pods/Nimbus/src/core/src/NISnapshotRotation.m | 299 ------- Pods/Nimbus/src/core/src/NIState.h | 84 -- Pods/Nimbus/src/core/src/NIState.m | 58 -- Pods/Nimbus/src/core/src/NIViewRecycler.h | 164 ---- Pods/Nimbus/src/core/src/NIViewRecycler.m | 111 --- .../src/core/src/NimbusCore+Additions.h | 26 - Pods/Nimbus/src/core/src/NimbusCore.h | 120 --- .../src/core/src/UIResponder+NimbusCore.h | 26 - .../src/core/src/UIResponder+NimbusCore.m | 49 -- .../src/NIPagingScrollView+Subclassing.h | 123 --- .../pagingscrollview/src/NIPagingScrollView.h | 386 --------- .../pagingscrollview/src/NIPagingScrollView.m | 760 ------------------ .../src/NIPagingScrollViewPage.h | 36 - .../src/NIPagingScrollViewPage.m | 26 - .../src/NimbusPagingScrollView.h | 53 -- .../src/photos/src/NIPhotoAlbumScrollView.h | 170 ---- .../src/photos/src/NIPhotoAlbumScrollView.m | 221 ----- .../src/NIPhotoAlbumScrollViewDataSource.h | 93 --- .../src/NIPhotoAlbumScrollViewDelegate.h | 55 -- .../Nimbus/src/photos/src/NIPhotoScrollView.h | 162 ---- .../Nimbus/src/photos/src/NIPhotoScrollView.m | 512 ------------ .../photos/src/NIPhotoScrollViewDelegate.h | 41 - .../photos/src/NIPhotoScrollViewPhotoSize.h | 31 - .../src/photos/src/NIPhotoScrubberView.h | 168 ---- .../src/photos/src/NIPhotoScrubberView.m | 465 ----------- .../photos/src/NIToolbarPhotoViewController.h | 201 ----- .../photos/src/NIToolbarPhotoViewController.m | 533 ------------ Pods/Nimbus/src/photos/src/NimbusPhotos.h | 122 --- Pods/WebBrowser/LICENSE.md | 21 - Pods/WebBrowser/README.md | 90 --- .../WebBrowser/InternationalControl.swift | 44 - .../WebBrowser/NavigationBarAppearance.swift | 39 - .../en.lproj/WebBrowser.strings | 14 - .../ja.lproj/WebBrowser.strings | 14 - .../ko.lproj/WebBrowser.strings | 14 - .../zh-Hans.lproj/WebBrowser.strings | 14 - .../zh-Hant.lproj/WebBrowser.strings | 14 - .../WebBrowser.xcassets/Contents.json | 6 - .../backIcon.imageset/Contents.json | 23 - .../backIcon.imageset/backIcon.png | Bin 1254 -> 0 bytes .../backIcon.imageset/backIcon@2x.png | Bin 1604 -> 0 bytes .../backIcon.imageset/backIcon@3x.png | Bin 1949 -> 0 bytes .../forwardIcon.imageset/Contents.json | 23 - .../forwardIcon.imageset/forwardIcon.png | Bin 1281 -> 0 bytes .../forwardIcon.imageset/forwardIcon@2x.png | Bin 1588 -> 0 bytes .../forwardIcon.imageset/forwardIcon@3x.png | Bin 1953 -> 0 bytes .../safariIcon.imageset/Contents.json | 33 - .../safariIcon.imageset/safariIcon.png | Bin 1530 -> 0 bytes .../safariIcon.imageset/safariIcon@2x.png | Bin 3691 -> 0 bytes .../safariIcon@2x~iPad.png | Bin 5053 -> 0 bytes .../safariIcon.imageset/safariIcon@3x.png | Bin 6129 -> 0 bytes .../safariIcon.imageset/safariIcon~iPad.png | Bin 2109 -> 0 bytes .../WebBrowser/SafariActivity.swift | 49 -- .../WebBrowser/ToolbarAppearance.swift | 30 - Pods/WebBrowser/WebBrowser/WebBrowser.swift | 38 - .../WebBrowser/WebBrowserDelegate.swift | 46 -- .../WebBrowser/WebBrowserViewController.swift | 412 ---------- kplayer.xcodeproj/project.pbxproj | 46 +- .../xcschemes/kplayer.xcscheme | 44 +- kplayer/AppDelegate.swift | 37 +- kplayer/PlayerApp.swift | 25 + kplayer/core/DatabaseManager.swift | 21 +- kplayer/core/LocalManager.swift | 44 + kplayer/core/MediaItem.swift | 31 +- kplayer/core/NetworkManager.swift | 4 +- kplayer/detail/BrowserController.swift | 390 --------- kplayer/detail/DetailView.swift | 45 ++ .../detail/DetailViewController+Show.swift | 34 +- kplayer/detail/DetailViewController.swift | 73 +- kplayer/detail/ItemView.swift | 22 + kplayer/master/DocPickerViewController.swift | 45 ++ kplayer/master/MasterModel.swift | 262 ++++++ kplayer/master/MasterSplitView.swift | 63 ++ kplayer/master/MasterViewController.swift | 21 + kplayer/master/ServerDownloadDelegate.swift | 30 - kplayer/photo/PhotoController.swift | 423 ---------- kplayer/photo/SPhotoAlbumView.swift | 10 +- kplayer/server/raspberrypi.js | 30 +- kplayer/util/AsyncImage.swift | 10 +- kplayer/video/SVideoPlayer.swift | 88 +- kplayer/video/VideoPlayerView.swift | 19 + 120 files changed, 830 insertions(+), 12174 deletions(-) delete mode 100644 Pods/Nimbus/LICENSE delete mode 100644 Pods/Nimbus/README.mdown delete mode 100644 Pods/Nimbus/src/core/src/NIActions+Subclassing.h delete mode 100644 Pods/Nimbus/src/core/src/NIActions.h delete mode 100644 Pods/Nimbus/src/core/src/NIActions.m delete mode 100644 Pods/Nimbus/src/core/src/NIButtonUtilities.h delete mode 100644 Pods/Nimbus/src/core/src/NIButtonUtilities.m delete mode 100644 Pods/Nimbus/src/core/src/NICommonMetrics.h delete mode 100644 Pods/Nimbus/src/core/src/NICommonMetrics.m delete mode 100644 Pods/Nimbus/src/core/src/NIDebuggingTools.h delete mode 100644 Pods/Nimbus/src/core/src/NIDebuggingTools.m delete mode 100644 Pods/Nimbus/src/core/src/NIDeviceOrientation.h delete mode 100644 Pods/Nimbus/src/core/src/NIDeviceOrientation.m delete mode 100644 Pods/Nimbus/src/core/src/NIError.h delete mode 100644 Pods/Nimbus/src/core/src/NIError.m delete mode 100644 Pods/Nimbus/src/core/src/NIFoundationMethods.h delete mode 100644 Pods/Nimbus/src/core/src/NIFoundationMethods.m delete mode 100644 Pods/Nimbus/src/core/src/NIImageUtilities.h delete mode 100644 Pods/Nimbus/src/core/src/NIImageUtilities.m delete mode 100644 Pods/Nimbus/src/core/src/NIInMemoryCache.h delete mode 100644 Pods/Nimbus/src/core/src/NIInMemoryCache.m delete mode 100644 Pods/Nimbus/src/core/src/NINetworkActivity.h delete mode 100644 Pods/Nimbus/src/core/src/NINetworkActivity.m delete mode 100644 Pods/Nimbus/src/core/src/NINonEmptyCollectionTesting.h delete mode 100644 Pods/Nimbus/src/core/src/NINonEmptyCollectionTesting.m delete mode 100644 Pods/Nimbus/src/core/src/NINonRetainingCollections.h delete mode 100644 Pods/Nimbus/src/core/src/NINonRetainingCollections.m delete mode 100644 Pods/Nimbus/src/core/src/NIOperations+Subclassing.h delete mode 100644 Pods/Nimbus/src/core/src/NIOperations.h delete mode 100644 Pods/Nimbus/src/core/src/NIOperations.m delete mode 100644 Pods/Nimbus/src/core/src/NIPaths.h delete mode 100644 Pods/Nimbus/src/core/src/NIPaths.m delete mode 100644 Pods/Nimbus/src/core/src/NIPreprocessorMacros.h delete mode 100644 Pods/Nimbus/src/core/src/NIRuntimeClassModifications.h delete mode 100644 Pods/Nimbus/src/core/src/NIRuntimeClassModifications.m delete mode 100644 Pods/Nimbus/src/core/src/NISDKAvailability.h delete mode 100644 Pods/Nimbus/src/core/src/NISDKAvailability.m delete mode 100644 Pods/Nimbus/src/core/src/NISnapshotRotation.h delete mode 100644 Pods/Nimbus/src/core/src/NISnapshotRotation.m delete mode 100644 Pods/Nimbus/src/core/src/NIState.h delete mode 100644 Pods/Nimbus/src/core/src/NIState.m delete mode 100644 Pods/Nimbus/src/core/src/NIViewRecycler.h delete mode 100644 Pods/Nimbus/src/core/src/NIViewRecycler.m delete mode 100644 Pods/Nimbus/src/core/src/NimbusCore+Additions.h delete mode 100644 Pods/Nimbus/src/core/src/NimbusCore.h delete mode 100644 Pods/Nimbus/src/core/src/UIResponder+NimbusCore.h delete mode 100644 Pods/Nimbus/src/core/src/UIResponder+NimbusCore.m delete mode 100644 Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView+Subclassing.h delete mode 100644 Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView.h delete mode 100644 Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView.m delete mode 100644 Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollViewPage.h delete mode 100644 Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollViewPage.m delete mode 100644 Pods/Nimbus/src/pagingscrollview/src/NimbusPagingScrollView.h delete mode 100644 Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollView.h delete mode 100644 Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollView.m delete mode 100644 Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollViewDataSource.h delete mode 100644 Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollViewDelegate.h delete mode 100644 Pods/Nimbus/src/photos/src/NIPhotoScrollView.h delete mode 100644 Pods/Nimbus/src/photos/src/NIPhotoScrollView.m delete mode 100644 Pods/Nimbus/src/photos/src/NIPhotoScrollViewDelegate.h delete mode 100644 Pods/Nimbus/src/photos/src/NIPhotoScrollViewPhotoSize.h delete mode 100644 Pods/Nimbus/src/photos/src/NIPhotoScrubberView.h delete mode 100644 Pods/Nimbus/src/photos/src/NIPhotoScrubberView.m delete mode 100644 Pods/Nimbus/src/photos/src/NIToolbarPhotoViewController.h delete mode 100644 Pods/Nimbus/src/photos/src/NIToolbarPhotoViewController.m delete mode 100644 Pods/Nimbus/src/photos/src/NimbusPhotos.h delete mode 100755 Pods/WebBrowser/LICENSE.md delete mode 100644 Pods/WebBrowser/README.md delete mode 100644 Pods/WebBrowser/WebBrowser/InternationalControl.swift delete mode 100644 Pods/WebBrowser/WebBrowser/NavigationBarAppearance.swift delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/en.lproj/WebBrowser.strings delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/ja.lproj/WebBrowser.strings delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/ko.lproj/WebBrowser.strings delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/zh-Hans.lproj/WebBrowser.strings delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/zh-Hant.lproj/WebBrowser.strings delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/Contents.json delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/Contents.json delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/backIcon.png delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/backIcon@2x.png delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/backIcon@3x.png delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/forwardIcon.imageset/Contents.json delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/forwardIcon.imageset/forwardIcon.png delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/forwardIcon.imageset/forwardIcon@2x.png delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/forwardIcon.imageset/forwardIcon@3x.png delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/Contents.json delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon.png delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon@2x.png delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon@2x~iPad.png delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon@3x.png delete mode 100644 Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon~iPad.png delete mode 100644 Pods/WebBrowser/WebBrowser/SafariActivity.swift delete mode 100644 Pods/WebBrowser/WebBrowser/ToolbarAppearance.swift delete mode 100644 Pods/WebBrowser/WebBrowser/WebBrowser.swift delete mode 100644 Pods/WebBrowser/WebBrowser/WebBrowserDelegate.swift delete mode 100644 Pods/WebBrowser/WebBrowser/WebBrowserViewController.swift create mode 100644 kplayer/PlayerApp.swift delete mode 100644 kplayer/detail/BrowserController.swift create mode 100644 kplayer/detail/DetailView.swift create mode 100644 kplayer/detail/ItemView.swift create mode 100644 kplayer/master/DocPickerViewController.swift create mode 100644 kplayer/master/MasterModel.swift create mode 100644 kplayer/master/MasterSplitView.swift delete mode 100644 kplayer/master/ServerDownloadDelegate.swift delete mode 100644 kplayer/photo/PhotoController.swift diff --git a/Podfile b/Podfile index 6ac0cd7..367e738 100644 --- a/Podfile +++ b/Podfile @@ -6,11 +6,16 @@ use_frameworks! target 'kplayer' do pod 'Alamofire' #, '4.7' pod 'HanekeSwift', :git => 'https://github.com/Haneke/HanekeSwift.git' - pod 'Nimbus/Photos' - pod 'Nimbus/PagingScrollView' - pod 'NVActivityIndicatorView' - pod 'WebBrowser' pod 'FileBrowser' pod 'ZIPFoundation' end +post_install do |installer| + installer.generated_projects.each do |project| + project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' + end + end + end +end diff --git a/Pods/Nimbus/LICENSE b/Pods/Nimbus/LICENSE deleted file mode 100644 index d645695..0000000 --- a/Pods/Nimbus/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - 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. diff --git a/Pods/Nimbus/README.mdown b/Pods/Nimbus/README.mdown deleted file mode 100644 index 36411e8..0000000 --- a/Pods/Nimbus/README.mdown +++ /dev/null @@ -1,13 +0,0 @@ -Nimbus is an iOS framework whose feature set grows only as fast as its documentation. - -[![Build Status](https://travis-ci.org/jverkoey/nimbus.svg)](https://travis-ci.org/jverkoey/nimbus) - -Getting Started ---------------- - -- Visit the Nimbus website at [nimbuskit.info](http://nimbuskit.info). -- [Add Nimbus to your project](http://wiki.nimbuskit.info/Add-Nimbus-to-your-project). -- Follow Nimbus' development through its [version history](http://docs.nimbuskit.info/group___version-_history.html). -- See the [latest API diffs](http://docs.nimbuskit.info/group___version-9-3.html). -- Read the [Three20 Migration Guide](http://docs.nimbuskit.info/group___three20-_migration-_guide.html). -- Ask questions and get updates via the [Nimbus mailing list](http://groups.google.com/group/nimbusios). diff --git a/Pods/Nimbus/src/core/src/NIActions+Subclassing.h b/Pods/Nimbus/src/core/src/NIActions+Subclassing.h deleted file mode 100644 index ff397bc..0000000 --- a/Pods/Nimbus/src/core/src/NIActions+Subclassing.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIActions.h" - -@interface NIObjectActions : NSObject - -@property (nonatomic, copy) NIActionBlock tapAction; -@property (nonatomic, copy) NIActionBlock detailAction; -@property (nonatomic, copy) NIActionBlock navigateAction; - -@property (nonatomic) SEL tapSelector; -@property (nonatomic) SEL detailSelector; -@property (nonatomic) SEL navigateSelector; - -@end - -@interface NIActions () - -@property (nonatomic, weak) id target; - -- (NIObjectActions *)actionForObjectOrClassOfObject:(id)object; - -@end diff --git a/Pods/Nimbus/src/core/src/NIActions.h b/Pods/Nimbus/src/core/src/NIActions.h deleted file mode 100644 index 2ea0fc8..0000000 --- a/Pods/Nimbus/src/core/src/NIActions.h +++ /dev/null @@ -1,422 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import - -/** - * For attaching actions to objects. - * - * @ingroup NimbusCore - * @defgroup Actions Actions - * @{ - */ - -/** - * @param object An action was performed on this object. - * @param target The target that was attached to the NIActions instance. - * @param indexPath The index path of the object. - */ -typedef BOOL (^NIActionBlock)(id object, id target, NSIndexPath* indexPath); - -/** - * The attachable types of actions for NIAction. - */ -typedef NS_OPTIONS(NSUInteger, NIActionType) { - NIActionTypeNone = 0, - NIActionTypeTap = 1 << 0, - NIActionTypeDetail = 1 << 1, - NIActionTypeNavigate = 1 << 2, -}; - -/** - * The NIActions class provides a generic interface for attaching actions to objects. - * - * NIActions are used to implement user interaction in UITableViews and UICollectionViews via the - * corresponding classes (NITableViewActions and NICollectionViewActions) in the respective - * feature. NIActions separates the necessity - * - *

Types of Actions

- * - * The three primary types of actions are: - * - * - buttons, - * - detail views, - * - and pushing a new controller onto the navigation controller. - * - *

Attaching Actions

- * - * Actions may be attached to specific instances of objects or to entire classes of objects. When - * an action is attached to both a class of object and an instance of that class, only the instance - * action should be executed. - * - * All attachment methods return the object that was provided. This makes it simple to attach - * actions within an array creation statement. - * - * Actions come in two forms: blocks and selector invocations. Both can be attached to an object - * for each type of action and both will be executed, with the block being executed first. Blocks - * should be used for simple executions while selectors should be used when the action is complex. - * - * The following is an example of using NITableViewActions: - * -@code -NSArray *objects = @[ - [NITitleCellObject objectWithTitle:@"Implicit tap handler"], - [self.actions attachToObject:[NITitleCellObject objectWithTitle:@"Explicit tap handler"] - tapBlock: - ^BOOL(id object, id target) { - NSLog(@"Object was tapped with an explicit action: %@", object); - }] -]; - -[self.actions attachToClass:[NITitleCellObject class] - tapBlock: - ^BOOL(id object, id target) { - NSLog(@"Object was tapped: %@", object); - }]; -@endcode - * - */ -@interface NIActions : NSObject - -// Designated initializer. -- (id)initWithTarget:(id)target; - -#pragma mark Mapping Objects - -- (id)attachToObject:(id)object tapBlock:(NIActionBlock)action; -- (id)attachToObject:(id)object detailBlock:(NIActionBlock)action; -- (id)attachToObject:(id)object navigationBlock:(NIActionBlock)action; - -- (id)attachToObject:(id)object tapSelector:(SEL)selector; -- (id)attachToObject:(id)object detailSelector:(SEL)selector; -- (id)attachToObject:(id)object navigationSelector:(SEL)selector; - -#pragma mark Mapping Classes - -- (void)attachToClass:(Class)aClass tapBlock:(NIActionBlock)action; -- (void)attachToClass:(Class)aClass detailBlock:(NIActionBlock)action; -- (void)attachToClass:(Class)aClass navigationBlock:(NIActionBlock)action; - -- (void)attachToClass:(Class)aClass tapSelector:(SEL)selector; -- (void)attachToClass:(Class)aClass detailSelector:(SEL)selector; -- (void)attachToClass:(Class)aClass navigationSelector:(SEL)selector; - -#pragma mark Object State - -- (BOOL)isObjectActionable:(id)object; -- (NIActionType)attachedActionTypesForObject:(id)object; - -+ (id)objectFromKeyClass:(Class)keyClass map:(NSMutableDictionary *)map; - -@end - -#if defined __cplusplus -extern "C" { -#endif - -/** - * Returns a block that pushes an instance of the controllerClass onto the navigation stack. - * - * Allocates an instance of the controller class and calls the init selector. - * - * The target property of the NIActions instance must be an instance of UIViewController - * with an attached navigationController. - * - * @param controllerClass The class of controller to instantiate. - */ -NIActionBlock NIPushControllerAction(Class controllerClass); - -#if defined __cplusplus -}; -#endif - -/** The protocol for a data source that can be used with NIActions. */ -@protocol NIActionsDataSource - -/** - * The object located at the given indexPath. - * - * @param indexPath The index path of the requested object. - */ -- (id)objectAtIndexPath:(NSIndexPath *)indexPath; - -@end - -/** @name Creating Table View Actions */ - -/** - * Initializes a newly allocated table view actions object with the given controller. - * - * @attention This method is deprecated. Use the new method - * @link NIActions::initWithTarget: initWithTarget:@endlink. - * - * The controller is stored as a weak reference internally. - * - * @param controller The controller that will be used in action blocks. - * @fn NIActions::initWithController: - */ - -/** - * Initializes a newly allocated table view actions object with the given target. - * - * This is the designated initializer. - * - * The target is stored as a weak reference internally. - * - * @param target The target that will be provided to action blocks and on which selectors will - * be performed. - * @fn NIActions::initWithTarget: - */ - -/** @name Mapping Objects */ - -/** - * Attaches a tap action to the given object. - * - * A cell with an attached tap action will have its selectionStyle set to - * @c tableViewCellSelectionStyle when the cell is displayed. - * - * The action will be executed when the object's corresponding cell is tapped. The object argument - * of the block will be the object to which this action was attached. The target argument of the - * block will be this receiver's @c target. - * - * Return NO if the tap action is used to present a modal view controller. This provides a visual - * reminder to the user when the modal controller is dismissed as to which cell was tapped to invoke - * the modal controller. - * - * The tap action will be invoked first, followed by the navigation action if one is attached. - * - * @param object The object to attach the action to. This object must be contained within - * an NITableViewModel. - * @param action The tap action block. - * @returns The object that you attached this action to. - * @fn NIActions::attachToObject:tapBlock: - * @sa NIActions::attachToObject:tapSelector: - */ - -/** - * Attaches a detail action to the given object. - * - * When a cell with a detail action is displayed, its accessoryType will be set to - * UITableViewCellAccessoryDetailDisclosureButton. - * - * When a cell's detail button is tapped, the detail action block will be executed. The return - * value of the block is ignored. - * - * @param object The object to attach the action to. This object must be contained within - * an NITableViewModel. - * @param action The detail action block. - * @returns The object that you attached this action to. - * @fn NIActions::attachToObject:detailBlock: - */ - -/** - * Attaches a navigation action to the given object. - * - * When a cell with a navigation action is displayed, its accessoryType will be set to - * UITableViewCellAccessoryDisclosureIndicator if there is no detail action, otherwise the - * detail disclosure indicator takes precedence. - * - * When a cell with a navigation action is tapped the navigation block will be executed. - * - * If a tap action also exists for this object then the tap action will be executed first, followed - * by the navigation action. - * - * @param object The object to attach the action to. This object must be contained within - * an NITableViewModel. - * @param action The navigation action block. - * @returns The object that you attached this action to. - * @fn NIActions::attachToObject:navigationBlock: - */ - -/** - * Attaches a tap selector to the given object. - * - * The method signature for the selector is: - @code - - (BOOL)didTapObject:(id)object; - @endcode - * - * A cell with an attached tap action will have its selectionStyle set to - * @c tableViewCellSelectionStyle when the cell is displayed. - * - * The selector will be performed on the action object's target when a cell with a tap selector is - * tapped, unless that selector does not exist on the @c target in which case nothing happens. - * - * If the selector invocation returns YES then the cell will be deselected immediately after the - * invocation completes its execution. If NO is returned then the cell's selection will remain. - * - * Return NO if the tap action is used to present a modal view controller. This provides a visual - * reminder to the user when the modal controller is dismissed as to which cell was tapped to invoke - * the modal controller. - * - * The tap action will be invoked first, followed by the navigation action if one is attached. - * - * @param object The object to attach the selector to. This object must be contained within - * an NITableViewModel. - * @param selector The selector that will be invoked by this action. - * @returns The object that you attached this action to. - * @fn NIActions::attachToObject:tapSelector: - * @sa NIActions::attachToObject:tapBlock: - */ - -/** - * Attaches a detail selector to the given object. - * - * The method signature for the selector is: - @code - - (void)didTapObject:(id)object; - @endcode - * - * A cell with an attached tap action will have its selectionStyle set to - * @c tableViewCellSelectionStyle and its accessoryType set to - * @c UITableViewCellAccessoryDetailDisclosureButton when the cell is displayed. - * - * The selector will be performed on the action object's target when a cell with a detail selector's - * accessory indicator is tapped, unless that selector does not exist on the @c target in which - * case nothing happens. - * - * @param object The object to attach the selector to. This object must be contained within - * an NITableViewModel. - * @param selector The selector that will be invoked by this action. - * @returns The object that you attached this action to. - * @fn NIActions::attachToObject:detailSelector: - * @sa NIActions::attachToObject:detailBlock: - */ - -/** - * Attaches a navigation selector to the given object. - * - * The method signature for the selector is: - @code - - (void)didTapObject:(id)object; - @endcode - * - * A cell with an attached navigation action will have its selectionStyle set to - * @c tableViewCellSelectionStyle and its accessoryType set to - * @c UITableViewCellAccessoryDetailDisclosureButton, unless it also has an attached detail action, - * in which case its accessoryType will be set to @c UITableViewCellAccessoryDisclosureIndicator - * when the cell is displayed. - * - * The selector will be performed on the action object's target when a cell with a navigation - * selector is tapped, unless that selector does not exist on the @c target in which case nothing - * happens. - * - * @param object The object to attach the selector to. This object must be contained within - * an NITableViewModel. - * @param selector The selector that will be invoked by this action. - * @returns The object that you attached this action to. - * @fn NIActions::attachToObject:navigationSelector: - * @sa NIActions::attachToObject:navigationBlock: - */ - -/** @name Mapping Classes */ - -/** - * Attaches a tap block to a class. - * - * This method behaves similarly to attachToObject:tapBlock: except it attaches a tap action to - * all instances and subclassed instances of a given class. - * - * @param aClass The class to attach the action to. - * @param action The tap action block. - * @fn NIActions::attachToClass:tapBlock: - */ - -/** - * Attaches a detail block to a class. - * - * This method behaves similarly to attachToObject:detailBlock: except it attaches a detail action - * to all instances and subclassed instances of a given class. - * - * @param aClass The class to attach the action to. - * @param action The detail action block. - * @fn NIActions::attachToClass:detailBlock: - */ - -/** - * Attaches a navigation block to a class. - * - * This method behaves similarly to attachToObject:navigationBlock: except it attaches a navigation - * action to all instances and subclassed instances of a given class. - * - * @param aClass The class to attach the action to. - * @param action The navigation action block. - * @fn NIActions::attachToClass:navigationBlock: - */ - -/** - * Attaches a tap selector to a class. - * - * This method behaves similarly to attachToObject:tapBlock: except it attaches a tap action to - * all instances and subclassed instances of a given class. - * - * @param aClass The class to attach the action to. - * @param selector The tap selector. - * @fn NIActions::attachToClass:tapSelector: - */ - -/** - * Attaches a detail selector to a class. - * - * This method behaves similarly to attachToObject:detailBlock: except it attaches a detail action - * to all instances and subclassed instances of a given class. - * - * @param aClass The class to attach the action to. - * @param selector The tap selector. - * @fn NIActions::attachToClass:detailSelector: - */ - -/** - * Attaches a navigation selector to a class. - * - * This method behaves similarly to attachToObject:navigationBlock: except it attaches a navigation - * action to all instances and subclassed instances of a given class. - * - * @param aClass The class to attach the action to. - * @param selector The tap selector. - * @fn NIActions::attachToClass:navigationSelector: - */ - -/** @name Object State */ - -/** - * Returns whether or not the object has any actions attached to it. - * - * @fn NIActions::isObjectActionable: - */ - -/** - * Returns a bitmask of flags indicating the types of actions attached to the provided object. - * - * @fn NIActions::attachedActionTypesForObject: - */ - -/** - * Returns a mapped object from the given key class. - * - * If the key class is a subclass of any mapped key classes, the nearest ancestor class's mapped - * object will be returned and keyClass will be added to the map for future accesses. - * - * @param keyClass The key class that will be used to find the mapping in map. - * @param map A map of key classes to classes. May be modified if keyClass is a subclass of - * any existing key classes. - * @returns The mapped object if a match for keyClass was found in map. nil is returned - * otherwise. - * @fn NIActions::objectFromKeyClass:map: - */ - -/**@}*/// End of Actions ////////////////////////////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NIActions.m b/Pods/Nimbus/src/core/src/NIActions.m deleted file mode 100644 index 1b8b4a7..0000000 --- a/Pods/Nimbus/src/core/src/NIActions.m +++ /dev/null @@ -1,247 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIActions.h" -#import "NIActions+Subclassing.h" - -#import - -#import "NIDebuggingTools.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -@interface NIActions () - -@property (nonatomic, strong) NSMutableDictionary* objectToAction; -@property (nonatomic, strong) NSMutableDictionary* classToAction; -@property (nonatomic, strong) NSMutableSet* objectSet; - -@end - -@implementation NIActions - -- (id)initWithTarget:(id)target { - if ((self = [super init])) { - _target = target; - - _objectToAction = [[NSMutableDictionary alloc] init]; - _classToAction = [[NSMutableDictionary alloc] init]; - _objectSet = [[NSMutableSet alloc] init]; - } - return self; -} - -- (id)init { - return [self initWithTarget:nil]; -} - -#pragma mark - Private - -- (id)keyForObject:(id)object { - return @(object.hash); -} - -// -// actionForObject: and actionForClass: are used when attaching actions to objects and classes and -// will always return an NIObjectActions object. These methods should not be used for determining -// whether an action is attached to a given object or class. -// -// actionForObjectOrClassOfObject: determines whether an action has been attached to an object -// or class of object and then returns the NIObjectActions or nil if no actions have been attached. -// - -// Retrieves an NIObjectActions object for the given object or creates one if it doesn't yet exist -// so that actions may be attached. -- (NIObjectActions *)actionForObject:(id)object { - id key = [self keyForObject:object]; - NIObjectActions* action = [self.objectToAction objectForKey:key]; - if (nil == action) { - action = [[NIObjectActions alloc] init]; - [self.objectToAction setObject:action forKey:key]; - } - return action; -} - -// Retrieves an NIObjectActions object for the given class or creates one if it doesn't yet exist -// so that actions may be attached. -- (NIObjectActions *)actionForClass:(Class)class { - NIObjectActions* action = [self.classToAction objectForKey:class]; - if (nil == action) { - action = [[NIObjectActions alloc] init]; - [self.classToAction setObject:action forKey:(id)class]; - } - return action; -} - -// Fetches any attached actions for a given object. -- (NIObjectActions *)actionForObjectOrClassOfObject:(id)object { - id key = [self keyForObject:object]; - NIObjectActions* action = [self.objectToAction objectForKey:key]; - if (nil == action) { - action = [self.class objectFromKeyClass:object.class map:self.classToAction]; - } - return action; -} - -#pragma mark - Public - -- (id)attachToObject:(id)object tapBlock:(NIActionBlock)action { - [self.objectSet addObject:object]; - [self actionForObject:object].tapAction = action; - return object; -} - -- (id)attachToObject:(id)object detailBlock:(NIActionBlock)action { - [self.objectSet addObject:object]; - [self actionForObject:object].detailAction = action; - return object; -} - -- (id)attachToObject:(id)object navigationBlock:(NIActionBlock)action { - [self.objectSet addObject:object]; - [self actionForObject:object].navigateAction = action; - return object; -} - -- (id)attachToObject:(id)object tapSelector:(SEL)selector { - [self.objectSet addObject:object]; - [self actionForObject:object].tapSelector = selector; - return object; -} - -- (id)attachToObject:(id)object detailSelector:(SEL)selector { - [self.objectSet addObject:object]; - [self actionForObject:object].detailSelector = selector; - return object; -} - -- (id)attachToObject:(id)object navigationSelector:(SEL)selector { - [self.objectSet addObject:object]; - [self actionForObject:object].navigateSelector = selector; - return object; -} - -- (void)attachToClass:(Class)aClass tapBlock:(NIActionBlock)action { - [self actionForClass:aClass].tapAction = action; -} - -- (void)attachToClass:(Class)aClass detailBlock:(NIActionBlock)action { - [self actionForClass:aClass].detailAction = action; -} - -- (void)attachToClass:(Class)aClass navigationBlock:(NIActionBlock)action { - [self actionForClass:aClass].navigateAction = action; -} - -- (void)attachToClass:(Class)aClass tapSelector:(SEL)selector { - [self actionForClass:aClass].tapSelector = selector; -} - -- (void)attachToClass:(Class)aClass detailSelector:(SEL)selector { - [self actionForClass:aClass].detailSelector = selector; -} - -- (void)attachToClass:(Class)aClass navigationSelector:(SEL)selector { - [self actionForClass:aClass].navigateSelector = selector; -} - -- (BOOL)isObjectActionable:(id)object { - return NIActionTypeNone != [self attachedActionTypesForObject:object]; -} - -- (NIActionType)attachedActionTypesForObject:(id)object { - if (nil == object) { - return NIActionTypeNone; - } - - NIObjectActions* actions = [self actionForObjectOrClassOfObject:object]; - NIActionType attachedActionTypes = 0; - if (actions.tapAction || actions.tapSelector) { - attachedActionTypes |= NIActionTypeTap; - } - if (actions.detailAction || actions.detailSelector) { - attachedActionTypes |= NIActionTypeDetail; - } - if (actions.navigateAction || actions.navigateSelector) { - attachedActionTypes |= NIActionTypeNavigate; - } - return attachedActionTypes; -} - -+ (id)objectFromKeyClass:(Class)keyClass map:(NSMutableDictionary *)map { - id object = [map objectForKey:keyClass]; - - if (nil == object) { - // No mapping found for this key class, but it may be a subclass of another object that does - // have a mapping, so let's see what we can find. - Class superClass = nil; - for (Class class in map.allKeys) { - // We want to find the lowest node in the class hierarchy so that we pick the lowest ancestor - // in the hierarchy tree. - if ([keyClass isSubclassOfClass:class] - && (nil == superClass || [class isSubclassOfClass:superClass])) { - superClass = class; - } - } - - if (nil != superClass) { - object = [map objectForKey:superClass]; - - // Add this subclass to the map so that next time this result is instant. - [map setObject:object forKey:(id)keyClass]; - } - } - - if (nil == object) { - // We couldn't find a mapping at all so let's add an empty mapping. - [map setObject:[NSNull class] forKey:(id)keyClass]; - - } else if (object == [NSNull class]) { - // Don't return null mappings. - object = nil; - } - - return object; -} - -@end - -@implementation NIObjectActions -@end - -NIActionBlock NIPushControllerAction(Class controllerClass) { - return [^(id object, id target, NSIndexPath* indexPath) { - // You must initialize the actions object with initWithTarget: and pass a valid - // controller. - NIDASSERT(nil != target); - NIDASSERT([target isKindOfClass:[UIViewController class]]); - UIViewController *controller = target; - - if (nil != controller && [controller isKindOfClass:[UIViewController class]]) { - // No navigation controller to push this new controller; this controller - // is going to be lost. - NIDASSERT(nil != controller.navigationController); - - UIViewController* controllerToPush = [[controllerClass alloc] init]; - [controller.navigationController pushViewController:controllerToPush - animated:YES]; - } - - return NO; - } copy]; -} diff --git a/Pods/Nimbus/src/core/src/NIButtonUtilities.h b/Pods/Nimbus/src/core/src/NIButtonUtilities.h deleted file mode 100644 index 4174e25..0000000 --- a/Pods/Nimbus/src/core/src/NIButtonUtilities.h +++ /dev/null @@ -1,92 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import -#import - -#if defined __cplusplus -extern "C" { -#endif - -/** - * For manipulating UIButton objects. - * - * @ingroup NimbusCore - * @defgroup Button-Utilities Button Utilities - * @{ - * - * The methods provided here make it possible to specify different properties for different button - * states in a scalable way. For example, you can define a stylesheet class that has a number of - * class methods that return the various properties for buttons. - * -@code -@implementation Stylesheet - -+ (UIImage *)backgroundImageForButtonWithState:(UIControlState)state { - if (state & UIControlStateHighlighted) { - return [UIImage imageNamed:@"button_highlighted"]; - - } else if (state == UIControlStateNormal) { - return [UIImage imageNamed:@"button"]; - } - return nil; -} - -@end - -// The result of the implementation above will set the background images for the button's -// highlighted and default states. -NIApplyBackgroundImageSelectorToButton(@selector(backgroundImageForButtonWithState:), - [Stylesheet class], - button); -@endcode - */ - -/** - * Sets the images for a button's states. - * - * @param selector A selector of the form: - * (UIImage *)imageWithControlState:(UIControlState)controlState - * @param target The target upon which the selector will be invoked. - * @param button The button object whose properties should be modified. - */ -void NIApplyImageSelectorToButton(SEL selector, id target, UIButton* button); - -/** - * Sets the background images for a button's states. - * - * @param selector A selector of the form: - * (UIImage *)backgroundImageWithControlState:(UIControlState)controlState - * @param target The target upon which the selector will be invoked. - * @param button The button object whose properties should be modified. - */ -void NIApplyBackgroundImageSelectorToButton(SEL selector, id target, UIButton* button); - -/** - * Sets the title colors for a button's states. - * - * @param selector A selector of the form: - * (UIColor *)colorWithControlState:(UIControlState)controlState - * @param target The target upon which the selector will be invoked. - * @param button The button object whose properties should be modified. - */ -void NIApplyTitleColorSelectorToButton(SEL selector, id target, UIButton* button); - -/**@}*/// End of Button Utilities ///////////////////////////////////////////////////////////////// - -#if defined __cplusplus -}; -#endif diff --git a/Pods/Nimbus/src/core/src/NIButtonUtilities.m b/Pods/Nimbus/src/core/src/NIButtonUtilities.m deleted file mode 100644 index aa135a1..0000000 --- a/Pods/Nimbus/src/core/src/NIButtonUtilities.m +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIButtonUtilities.h" - -void NIApplyImageSelectorToButton(SEL selector, id target, UIButton* button) { - typedef UIImage* (*ImageMethod)(id, SEL, UIControlState); - ImageMethod method = (ImageMethod)[target methodForSelector:selector]; - UIImage* image = nil; - - image = method(target, selector, UIControlStateNormal); - [button setImage:image forState:UIControlStateNormal]; - - image = method(target, selector, UIControlStateHighlighted); - [button setImage:image forState:UIControlStateHighlighted]; - - image = method(target, selector, UIControlStateDisabled); - [button setImage:image forState:UIControlStateDisabled]; - - image = method(target, selector, UIControlStateSelected); - [button setImage:image forState:UIControlStateSelected]; - - UIControlState selectedHighlightState = UIControlStateSelected | UIControlStateHighlighted; - image = method(target, selector, selectedHighlightState); - [button setImage:image forState:selectedHighlightState]; -} - -void NIApplyBackgroundImageSelectorToButton(SEL selector, id target, UIButton* button) { - typedef UIImage* (*ImageMethod)(id, SEL, UIControlState); - ImageMethod method = (ImageMethod)[target methodForSelector:selector]; - UIImage* image = nil; - - image = method(target, selector, UIControlStateNormal); - [button setBackgroundImage:image forState:UIControlStateNormal]; - - image = method(target, selector, UIControlStateHighlighted); - [button setBackgroundImage:image forState:UIControlStateHighlighted]; - - image = method(target, selector, UIControlStateDisabled); - [button setBackgroundImage:image forState:UIControlStateDisabled]; - - image = method(target, selector, UIControlStateSelected); - [button setBackgroundImage:image forState:UIControlStateSelected]; - - UIControlState selectedHighlightState = UIControlStateSelected | UIControlStateHighlighted; - image = method(target, selector, selectedHighlightState); - [button setBackgroundImage:image forState:selectedHighlightState]; -} - -void NIApplyTitleColorSelectorToButton(SEL selector, id target, UIButton* button) { - typedef UIColor* (*ColorMethod)(id, SEL, UIControlState); - ColorMethod method = (ColorMethod)[target methodForSelector:selector]; - UIColor* color = nil; - - color = method(target, selector, UIControlStateNormal); - [button setTitleColor:color forState:UIControlStateNormal]; - - color = method(target, selector, UIControlStateHighlighted); - [button setTitleColor:color forState:UIControlStateHighlighted]; - - color = method(target, selector, UIControlStateDisabled); - [button setTitleColor:color forState:UIControlStateDisabled]; - - color = method(target, selector, UIControlStateSelected); - [button setTitleColor:color forState:UIControlStateSelected]; - - UIControlState selectedHighlightState = UIControlStateSelected | UIControlStateHighlighted; - color = method(target, selector, selectedHighlightState); - [button setTitleColor:color forState:selectedHighlightState]; -} diff --git a/Pods/Nimbus/src/core/src/NICommonMetrics.h b/Pods/Nimbus/src/core/src/NICommonMetrics.h deleted file mode 100644 index aa3c782..0000000 --- a/Pods/Nimbus/src/core/src/NICommonMetrics.h +++ /dev/null @@ -1,172 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import -#import - -#import "NIPreprocessorMacros.h" - -#if defined __cplusplus -extern "C" { -#endif - -/** - * For common system metrics. - * - * If you work with system metrics in any way it can be a pain in the ass to figure out what the - * exact metrics are. Figuring out how long it takes the status bar to animate is not something you - * should be spending your time on. The metrics in this file are provided as a means of unifying a - * number of system metrics for use in your applications. - * - *

What Qualifies as a Common Metric

- * - * Common metrics are system components, such as the dimensions of a toolbar in - * a particular orientation or the duration of a standard animation. This is - * not the place to put feature-specific metrics, such as the height of a photo scrubber - * view. - * - *

Examples

- * - *

Positioning a Toolbar

- * - * The following example updates the position and height of a toolbar when the device - * orientation is changing. This ensures that, in landscape mode on the iPhone, the toolbar - * is slightly shorter to accomodate the smaller height of the screen. - * - * @code - * - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation - * duration:(NSTimeInterval)duration { - * [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; - * - * CGRect toolbarFrame = self.toolbar.frame; - * toolbarFrame.size.height = NIToolbarHeightForOrientation(toInterfaceOrientation); - * toolbarFrame.origin.y = self.view.bounds.size.height - toolbarFrame.size.height; - * self.toolbar.frame = toolbarFrame; - * } - * @endcode - * - * @ingroup NimbusCore - * @defgroup Common-Metrics Common Metrics - * @{ - */ - -#ifndef UIViewAutoresizingFlexibleMargins -#define UIViewAutoresizingFlexibleMargins (UIViewAutoresizingFlexibleLeftMargin \ - | UIViewAutoresizingFlexibleTopMargin \ - | UIViewAutoresizingFlexibleRightMargin \ - | UIViewAutoresizingFlexibleBottomMargin) -#endif - -#ifndef UIViewAutoresizingFlexibleDimensions -#define UIViewAutoresizingFlexibleDimensions (UIViewAutoresizingFlexibleWidth \ - | UIViewAutoresizingFlexibleHeight) -#endif - -#ifndef UIViewAutoresizingNavigationBar -#define UIViewAutoresizingNavigationBar (UIViewAutoresizingFlexibleWidth \ - | UIViewAutoresizingFlexibleBottomMargin) -#endif - -#ifndef UIViewAutoresizingToolbar -#define UIViewAutoresizingToolbar (UIViewAutoresizingFlexibleWidth \ - | UIViewAutoresizingFlexibleTopMargin) -#endif - -/** - * The recommended number of points for a minimum tappable area. - * - * Value: 44 - */ -CGFloat NIMinimumTapDimension(void); - -/** - * Fetch the height of a toolbar in a given orientation. - * - * On the iPhone: - * - Portrait: 44 - * - Landscape: 33 - * - * On the iPad: always 44 - */ -CGFloat NIToolbarHeightForOrientation(UIInterfaceOrientation orientation); - -/** - * The animation curve used when changing the status bar's visibility. - * - * This is the curve of the animation used by - * -[[UIApplication sharedApplication] setStatusBarHidden:withAnimation:]. - * - * Value: UIViewAnimationCurveEaseIn - */ -UIViewAnimationCurve NIStatusBarAnimationCurve(void); - -/** - * The animation duration used when changing the status bar's visibility. - * - * This is the duration of the animation used by - * -[[UIApplication sharedApplication] setStatusBarHidden:withAnimation:]. - * - * Value: 0.3 seconds - */ -NSTimeInterval NIStatusBarAnimationDuration(void); - -/** - * The animation curve used when the status bar's bounds change (when a call is received, - * for example). - * - * Value: UIViewAnimationCurveEaseInOut - */ -UIViewAnimationCurve NIStatusBarBoundsChangeAnimationCurve(void); - -/** - * The animation duration used when the status bar's bounds change (when a call is received, - * for example). - * - * Value: 0.35 seconds - */ -NSTimeInterval NIStatusBarBoundsChangeAnimationDuration(void); - -/** - * Get the status bar's current height. - * - * If the status bar is hidden this will return 0. - * - * This is generally 20 when the status bar is its normal height. - */ -CGFloat NIStatusBarHeight(void) NI_EXTENSION_UNAVAILABLE_IOS(""); - -/** - * The animation duration when the device is rotating to a new orientation. - * - * Value: 0.4 seconds if the device is being rotated 90 degrees. - * 0.8 seconds if the device is being rotated 180 degrees. - * - * @param isFlippingUpsideDown YES if the device is being flipped upside down. - */ -NSTimeInterval NIDeviceRotationDuration(BOOL isFlippingUpsideDown); - -/** - * The padding around a standard cell in a table view. - * - * Value: 10 pixels on all sides. - */ -UIEdgeInsets NICellContentPadding(void); - -#if defined __cplusplus -}; -#endif - -/**@}*/// End of Common Metrics /////////////////////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NICommonMetrics.m b/Pods/Nimbus/src/core/src/NICommonMetrics.m deleted file mode 100644 index 7aae538..0000000 --- a/Pods/Nimbus/src/core/src/NICommonMetrics.m +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NICommonMetrics.h" - -#import "NISDKAvailability.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -CGFloat NIMinimumTapDimension(void) { - return 44; -} - -CGFloat NIToolbarHeightForOrientation(UIInterfaceOrientation orientation) { - return (NIIsPad() - ? 44 - : (UIInterfaceOrientationIsPortrait(orientation) - ? 44 - : 33)); -} - -UIViewAnimationCurve NIStatusBarAnimationCurve(void) { - return UIViewAnimationCurveEaseIn; -} - -NSTimeInterval NIStatusBarAnimationDuration(void) { - return 0.3; -} - -UIViewAnimationCurve NIStatusBarBoundsChangeAnimationCurve(void) { - return UIViewAnimationCurveEaseInOut; -} - -NSTimeInterval NIStatusBarBoundsChangeAnimationDuration(void) { - return 0.35; -} - -CGFloat NIStatusBarHeight(void) { - CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; - - // We take advantage of the fact that the status bar will always be wider than it is tall - // in order to avoid having to check the status bar orientation. - CGFloat statusBarHeight = MIN(statusBarFrame.size.width, statusBarFrame.size.height); - - return statusBarHeight; -} - -NSTimeInterval NIDeviceRotationDuration(BOOL isFlippingUpsideDown) { - return isFlippingUpsideDown ? 0.8 : 0.4; -} - -UIEdgeInsets NICellContentPadding(void) { - return UIEdgeInsetsMake(10, 10, 10, 10); -} diff --git a/Pods/Nimbus/src/core/src/NIDebuggingTools.h b/Pods/Nimbus/src/core/src/NIDebuggingTools.h deleted file mode 100644 index 1a2b84b..0000000 --- a/Pods/Nimbus/src/core/src/NIDebuggingTools.h +++ /dev/null @@ -1,194 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import - -/** - * For inspecting code and writing to logs in debug builds. - * - * Nearly all of the following macros will only do anything if the DEBUG macro is defined. - * The recommended way to enable the debug tools is to specify DEBUG in the "Preprocessor Macros" - * field in your application's Debug target settings. Be careful not to set this for your release - * or app store builds because this will enable code that may cause your app to be rejected. - * - * - *

Debug Assertions

- * - * Debug assertions are a lightweight "sanity check". They won't crash the app, nor will they - * be included in release builds. They will halt the app's execution when debugging so - * that you can inspect the values that caused the failure. - * - * @code - * NIDASSERT(statement); - * @endcode - * - * If statement is false, the statement will be written to the log and if a debugger is - * attached, the app will break on the assertion line. - * - * - *

Debug Logging

- * - * @code - * NIDPRINT(@"formatted log text %d", param1); - * @endcode - * - * Print the given formatted text to the log. - * - * @code - * NIDPRINTMETHODNAME(); - * @endcode - * - * Print the current method name to the log. - * - * @code - * NIDCONDITIONLOG(statement, @"formatted log text %d", param1); - * @endcode - * - * If statement is true, then the formatted text will be written to the log. - * - * @code - * NIDINFO/NIDWARNING/NIDERROR(@"formatted log text %d", param1); - * @endcode - * - * Will only write the formatted text to the log if NIMaxLogLevel is greater than the respective - * NID* method's log level. See below for log levels. - * - * The default maximum log level is NILOGLEVEL_WARNING. - * - *

Turning up the log level while the app is running

- * - * NIMaxLogLevel is declared a non-const extern so that you can modify it at runtime. This can - * be helpful for turning logging on while the application is running. - * - * @code - * NIMaxLogLevel = NILOGLEVEL_INFO; - * @endcode - * - * @ingroup NimbusCore - * @defgroup Debugging-Tools Debugging Tools - * @{ - */ - -#if defined(DEBUG) || defined(NI_DEBUG) - -/** - * Assertions that only fire when DEBUG is defined. - * - * An assertion is like a programmatic breakpoint. Use it for sanity checks to save headache while - * writing your code. - */ -#import - -#if defined __cplusplus -extern "C" { -#endif - -int NIIsInDebugger(void); - -#if defined __cplusplus -} -#endif - -#if TARGET_IPHONE_SIMULATOR -// We leave the __asm__ in this macro so that when a break occurs, we don't have to step out of -// a "breakInDebugger" function. -#define NIDASSERT(xx) { if (!(xx)) { NIDPRINT(@"NIDASSERT failed: %s", #xx); \ -if (NIDebugAssertionsShouldBreak && NIIsInDebugger()) { __asm__("int $3\n" : : ); } } \ -} ((void)0) -#else -#define NIDASSERT(xx) { if (!(xx)) { NIDPRINT(@"NIDASSERT failed: %s", #xx); \ -if (NIDebugAssertionsShouldBreak && NIIsInDebugger()) { raise(SIGTRAP); } } \ -} ((void)0) -#endif // #if TARGET_IPHONE_SIMULATOR - -#else -#define NIDASSERT(xx) ((void)0) -#endif // #if defined(DEBUG) || defined(NI_DEBUG) - - -#define NILOGLEVEL_INFO 5 -#define NILOGLEVEL_WARNING 3 -#define NILOGLEVEL_ERROR 1 - -/** - * The maximum log level to output for Nimbus debug logs. - * - * This value may be changed at run-time. - * - * The default value is NILOGLEVEL_WARNING. - */ -extern NSInteger NIMaxLogLevel; - -/** - * Whether or not debug assertions should halt program execution like a breakpoint when they fail. - * - * An example of when this is used is in unit tests, when failure cases are tested that will - * fire debug assertions. - * - * The default value is YES. - */ -extern BOOL NIDebugAssertionsShouldBreak; - -/** - * Only writes to the log when DEBUG is defined. - * - * This log method will always write to the log, regardless of log levels. It is used by all - * of the other logging methods in Nimbus' debugging library. - */ -#if defined(DEBUG) || defined(NI_DEBUG) -#define NIDPRINT(xx, ...) NSLog(@"%s(%d): " xx, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__) -#else -#define NIDPRINT(xx, ...) ((void)0) -#endif // #if defined(DEBUG) || defined(NI_DEBUG) - -/** - * Write the containing method's name to the log using NIDPRINT. - */ -#define NIDPRINTMETHODNAME() NIDPRINT(@"%s", __PRETTY_FUNCTION__) - -#if defined(DEBUG) || defined(NI_DEBUG) -/** - * Only writes to the log if condition is satisified. - * - * This macro powers the level-based loggers. It can also be used for conditionally enabling - * families of logs. - */ -#define NIDCONDITIONLOG(condition, xx, ...) { if ((condition)) { NIDPRINT(xx, ##__VA_ARGS__); } \ -} ((void)0) -#else -#define NIDCONDITIONLOG(condition, xx, ...) ((void)0) -#endif // #if defined(DEBUG) || defined(NI_DEBUG) - - -/** - * Only writes to the log if NIMaxLogLevel >= NILOGLEVEL_ERROR. - */ -#define NIDERROR(xx, ...) NIDCONDITIONLOG((NILOGLEVEL_ERROR <= NIMaxLogLevel), xx, ##__VA_ARGS__) - -/** - * Only writes to the log if NIMaxLogLevel >= NILOGLEVEL_WARNING. - */ -#define NIDWARNING(xx, ...) NIDCONDITIONLOG((NILOGLEVEL_WARNING <= NIMaxLogLevel), \ -xx, ##__VA_ARGS__) - -/** - * Only writes to the log if NIMaxLogLevel >= NILOGLEVEL_INFO. - */ -#define NIDINFO(xx, ...) NIDCONDITIONLOG((NILOGLEVEL_INFO <= NIMaxLogLevel), xx, ##__VA_ARGS__) - -/**@}*/// End of Debugging Tools ////////////////////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NIDebuggingTools.m b/Pods/Nimbus/src/core/src/NIDebuggingTools.m deleted file mode 100644 index c81e569..0000000 --- a/Pods/Nimbus/src/core/src/NIDebuggingTools.m +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// Copyright 2009-2011 Facebook -// -// 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. -// - -#import "NIDebuggingTools.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -NSInteger NIMaxLogLevel = NILOGLEVEL_WARNING; -BOOL NIDebugAssertionsShouldBreak = YES; - -#if defined(DEBUG) || defined(NI_DEBUG) - -#import -#import - -// From: http://developer.apple.com/mac/library/qa/qa2004/qa1361.html -int NIIsInDebugger(void) { - int mib[4]; - struct kinfo_proc info; - size_t size; - - // Initialize the flags so that, if sysctl fails for some bizarre - // reason, we get a predictable result. - - info.kp_proc.p_flag = 0; - - // Initialize mib, which tells sysctl the info we want, in this case - // we're looking for information about a specific process ID. - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - - // Call sysctl. - - size = sizeof(info); - sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0); - - // We're being debugged if the P_TRACED flag is set. - - return (info.kp_proc.p_flag & P_TRACED) != 0; -} - -#endif // #if defined(DEBUG) || defined(NI_DEBUG) diff --git a/Pods/Nimbus/src/core/src/NIDeviceOrientation.h b/Pods/Nimbus/src/core/src/NIDeviceOrientation.h deleted file mode 100644 index f3b6b7a..0000000 --- a/Pods/Nimbus/src/core/src/NIDeviceOrientation.h +++ /dev/null @@ -1,92 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import -#import - -#import "NIPreprocessorMacros.h" - -#if defined __cplusplus -extern "C" { -#endif - -/** - * For dealing with device orientations. - * - *

Examples

- * - *

Use NIIsSupportedOrientation to Enable Autorotation

- * - * @code - * - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { - * return NIIsSupportedOrientation(toInterfaceOrientation); - * } - * @endcode - * - * @ingroup NimbusCore - * @defgroup Device-Orientation Device Orientation - * @{ - */ - -/** - * For use in shouldAutorotateToInterfaceOrientation: - * - * On iPhone/iPod touch: - * - * Returns YES if the orientation is portrait, landscape left, or landscape right. - * This helps to ignore upside down and flat orientations. - * - * On iPad: - * - * Always returns YES. - */ -BOOL NIIsSupportedOrientation(UIInterfaceOrientation orientation); - -/** - * Returns the application's current interface orientation. - * - * This is simply a convenience method for [UIApplication sharedApplication].statusBarOrientation. - * - * @returns The current interface orientation. - */ -UIInterfaceOrientation NIInterfaceOrientation(void) NI_EXTENSION_UNAVAILABLE_IOS(""); - -/** - * Returns YES if the device is a phone and the orientation is landscape. - * - * This is a useful check for phone landscape mode which often requires - * additional logic to handle the smaller vertical real estate. - * - * @returns YES if the device is a phone and orientation is landscape. - */ -BOOL NIIsLandscapePhoneOrientation(UIInterfaceOrientation orientation); - -/** - * Creates an affine transform for the given device orientation. - * - * This is useful for creating a transformation matrix for a view that has been added - * directly to the window and doesn't automatically have its transformation modified. - */ -CGAffineTransform NIRotateTransformForOrientation(UIInterfaceOrientation orientation); - -#if defined __cplusplus -}; -#endif - -/**@}*/// End of Device Orientation /////////////////////////////////////////////////////////////// - diff --git a/Pods/Nimbus/src/core/src/NIDeviceOrientation.m b/Pods/Nimbus/src/core/src/NIDeviceOrientation.m deleted file mode 100644 index fefb006..0000000 --- a/Pods/Nimbus/src/core/src/NIDeviceOrientation.m +++ /dev/null @@ -1,76 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import "NIDeviceOrientation.h" - -#import - -#import "NIDebuggingTools.h" -#import "NISDKAvailability.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -BOOL NIIsSupportedOrientation(UIInterfaceOrientation orientation) { - if (NIIsPad()) { - return YES; - - } else { - switch (orientation) { - case UIInterfaceOrientationPortrait: - case UIInterfaceOrientationLandscapeLeft: - case UIInterfaceOrientationLandscapeRight: - return YES; - default: - return NO; - } - } -} - -UIInterfaceOrientation NIInterfaceOrientation(void) { - UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation; - - // This code used to use the Three20 navigator to find the currently visible view controller and - // fall back to checking its orientation if we didn't know the status bar's orientation. - // It's unclear when this was actually necessary, though, so this assertion is here to try - // to find that case. If this assertion fails then the repro case needs to be analyzed and - // this method made more robust to handle that case. - NIDASSERT(UIDeviceOrientationUnknown != orient); - - return orient; -} - -BOOL NIIsLandscapePhoneOrientation(UIInterfaceOrientation orientation) { - return NIIsPhone() && UIInterfaceOrientationIsLandscape(orientation); -} - -CGAffineTransform NIRotateTransformForOrientation(UIInterfaceOrientation orientation) { - if (orientation == UIInterfaceOrientationLandscapeLeft) { - return CGAffineTransformMakeRotation((CGFloat)(M_PI * 1.5)); - - } else if (orientation == UIInterfaceOrientationLandscapeRight) { - return CGAffineTransformMakeRotation((CGFloat)(M_PI / 2.0)); - - } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) { - return CGAffineTransformMakeRotation((CGFloat)(-M_PI)); - - } else { - return CGAffineTransformIdentity; - } -} diff --git a/Pods/Nimbus/src/core/src/NIError.h b/Pods/Nimbus/src/core/src/NIError.h deleted file mode 100644 index 89a14db..0000000 --- a/Pods/Nimbus/src/core/src/NIError.h +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import -#import - -/** - * For defining various error types used throughout the Nimbus framework. - * - * @ingroup NimbusCore - * @defgroup Errors Errors - * @{ - */ - -/** The Nimbus error domain. */ -extern NSString* const NINimbusErrorDomain; - -/** The key used for images in the error's userInfo. */ -extern NSString* const NIImageErrorKey; - -/** NSError codes in NINimbusErrorDomain. */ -typedef enum { - /** The image is too small to be used. */ - NIImageTooSmall = 1, -} NINimbusErrorDomainCode; - - -/**@}*/// End of Errors /////////////////////////////////////////////////////////////////////////// - -/** - *

Example

- * - * @code - * error = [NSError errorWithDomain: NINimbusErrorDomain - * code: NIImageTooSmall - * userInfo: [NSDictionary dictionaryWithObject: image - * forKey: NIImageErrorKey]]; - * @endcode - * - * @enum NINimbusErrorDomainCode - */ diff --git a/Pods/Nimbus/src/core/src/NIError.m b/Pods/Nimbus/src/core/src/NIError.m deleted file mode 100644 index 652829b..0000000 --- a/Pods/Nimbus/src/core/src/NIError.m +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIError.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -NSString* const NINimbusErrorDomain = @"com.nimbus.error"; -NSString* const NIImageErrorKey = @"image"; diff --git a/Pods/Nimbus/src/core/src/NIFoundationMethods.h b/Pods/Nimbus/src/core/src/NIFoundationMethods.h deleted file mode 100644 index cc8be31..0000000 --- a/Pods/Nimbus/src/core/src/NIFoundationMethods.h +++ /dev/null @@ -1,421 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import -#import - -#import "NIPreprocessorMacros.h" - -#if defined __cplusplus -extern "C" { -#endif - -/** - * For filling in gaps in Apple's Foundation framework. - * - * @ingroup NimbusCore - * @defgroup Foundation-Methods Foundation Methods - * @{ - * - * Utility methods save time and headache. You've probably written dozens of your own. Nimbus - * hopes to provide an ever-growing set of convenience methods that compliment the Foundation - * framework's functionality. - */ - -#pragma mark - NSInvocation Methods - -/** - * Construct an NSInvocation with an instance of an object and a selector - * - * @return an NSInvocation that will call the given selector on the given target - */ -NSInvocation* NIInvocationWithInstanceTarget(NSObject* target, SEL selector); - -/** - * This method is deprecated. Please use NIInvocationWithInstanceTarget([object class], selector) - * instead. - */ -NSInvocation* NIInvocationWithClassTarget(Class targetClass, SEL selector) __NI_DEPRECATED_METHOD; - -#pragma mark - CGRect Methods - -/** - * For manipulating CGRects. - * - * @defgroup CGRect-Methods CGRect Methods - * @{ - * - * These methods provide additional means of modifying the edges of CGRects beyond the basics - * included in CoreGraphics. - */ - -/** - * Modifies only the right and bottom edges of a CGRect. - * - * @return a CGRect with dx and dy subtracted from the width and height. - * - * Example result: CGRectMake(x, y, w - dx, h - dy) - */ -CGRect NIRectContract(CGRect rect, CGFloat dx, CGFloat dy); - -/** - * Modifies only the right and bottom edges of a CGRect. - * - * @return a CGRect with dx and dy added to the width and height. - * - * Example result: CGRectMake(x, y, w + dx, h + dy) - */ -CGRect NIRectExpand(CGRect rect, CGFloat dx, CGFloat dy); - -/** - * Modifies only the top and left edges of a CGRect. - * - * @return a CGRect whose origin has been offset by dx, dy, and whose size has been - * contracted by dx, dy. - * - * Example result: CGRectMake(x + dx, y + dy, w - dx, h - dy) - */ -CGRect NIRectShift(CGRect rect, CGFloat dx, CGFloat dy); - -/** - * Inverse of UIEdgeInsetsInsetRect. - * - * Example result: CGRectMake(x - left, y - top, - * w + left + right, h + top + bottom) - */ -CGRect NIEdgeInsetsOutsetRect(CGRect rect, UIEdgeInsets outsets); - -/** - * Returns the x position that will center size within containerSize. - * - * Example result: floorf((containerSize.width - size.width) / 2.f) - */ -CGFloat NICenterX(CGSize containerSize, CGSize size); - -/** - * Returns the y position that will center size within containerSize. - * - * Example result: floorf((containerSize.height - size.height) / 2.f) - */ -CGFloat NICenterY(CGSize containerSize, CGSize size); - -/** - * Returns a rect that will center viewToCenter within containerView. - * - * @return a CGPoint that will center viewToCenter within containerView. - */ -CGRect NIFrameOfCenteredViewWithinView(UIView* viewToCenter, UIView* containerView); - -/** - * Returns the size of the string with given UILabel properties. - */ -CGSize NISizeOfStringWithLabelProperties(NSString *string, CGSize constrainedToSize, UIFont *font, NSLineBreakMode lineBreakMode, NSInteger numberOfLines); - -/**@}*/ - - -#pragma mark - NSRange Methods - -/** - * For manipulating NSRange. - * - * @defgroup NSRange-Methods NSRange Methods - * @{ - */ - -/** - * Create an NSRange object from a CFRange object. - * - * @return an NSRange object with the same values as the CFRange object. - * - * @attention This has the potential to behave unexpectedly because it converts the - * CFRange's long values to unsigned integers. Nimbus will fire off a debug - * assertion at runtime if the value will be chopped or the sign will change. - * Even though the assertion will fire, the method will still chop or change - * the sign of the values so you should take care to fix this. - */ -NSRange NIMakeNSRangeFromCFRange(CFRange range); - -/**@}*/ - - -#pragma mark - NSData Methods - -/** - * For manipulating NSData. - * - * @defgroup NSData-Methods NSData Methods - * @{ - */ - -/** - * Calculates an md5 hash of the data using CC_MD5. - */ -NSString* NIMD5HashFromData(NSData* data); - -/** - * Calculates a sha1 hash of the data using CC_SHA1. - */ -NSString* NISHA1HashFromData(NSData* data); - -/**@}*/ - - -#pragma mark - NSString Methods - -/** - * For manipulating NSStrings. - * - * @defgroup NSString-Methods NSString Methods - * @{ - */ - -/** - * Calculates an md5 hash of the string using CC_MD5. - * - * Treats the string as UTF8. - */ -NSString* NIMD5HashFromString(NSString* string); - -/** - * Calculates a sha1 hash of the string using CC_SHA1. - * - * Treats the string as UTF8. - */ -NSString* NISHA1HashFromString(NSString* string); - -/** - * Returns a Boolean value indicating whether the string is a NSString object that contains only - * whitespace and newlines. - */ -BOOL NIIsStringWithWhitespaceAndNewlines(NSString* string); - -/** - * Compares two strings expressing software versions. - * - * The comparison is (except for the development version provisions noted below) lexicographic - * string comparison. So as long as the strings being compared use consistent version formats, - * a variety of schemes are supported. For example "3.02" < "3.03" and "3.0.2" < "3.0.3". If you - * mix such schemes, like trying to compare "3.02" and "3.0.3", the result may not be what you - * expect. - * - * Development versions are also supported by adding an "a" character and more version info after - * it. For example "3.0a1" or "3.01a4". The way these are handled is as follows: if the parts - * before the "a" are different, the parts after the "a" are ignored. If the parts before the "a" - * are identical, the result of the comparison is the result of NUMERICALLY comparing the parts - * after the "a". If the part after the "a" is empty, it is treated as if it were "0". If one - * string has an "a" and the other does not (e.g. "3.0" and "3.0a1") the one without the "a" - * is newer. - * - * Examples (?? means undefined): - * @htmlonly - *
- *   "3.0" = "3.0"
- *   "3.0a2" = "3.0a2"
- *   "3.0" > "2.5"
- *   "3.1" > "3.0"
- *   "3.0a1" < "3.0"
- *   "3.0a1" < "3.0a4"
- *   "3.0a2" < "3.0a19"  <-- numeric, not lexicographic
- *   "3.0a" < "3.0a1"
- *   "3.02" < "3.03"
- *   "3.0.2" < "3.0.3"
- *   "3.00" ?? "3.0"
- *   "3.02" ?? "3.0.3"
- *   "3.02" ?? "3.0.2"
- * 
- * @endhtmlonly - */ -NSComparisonResult NICompareVersionStrings(NSString* string1, NSString* string2); - -/** - * Parses a URL query string into a dictionary where the values are arrays. - * - * A query string is one that looks like ¶m1=value1¶m2=value2... - * - * The resulting NSDictionary will contain keys for each parameter name present in the query. - * The value for each key will be an NSArray which may be empty if the key is simply present - * in the query. Otherwise each object in the array with be an NSString corresponding to a value - * in the query for that parameter. - */ -NSDictionary* NIQueryDictionaryFromStringUsingEncoding(NSString* string, NSStringEncoding encoding); - -/** - * Returns a string that has been escaped for use as a URL parameter. - */ -NSString* NIStringByAddingPercentEscapesForURLParameterString(NSString* parameter); - -/** - * Appends a dictionary of query parameters to a string, adding the ? character if necessary. - */ -NSString* NIStringByAddingQueryDictionaryToString(NSString* string, NSDictionary* query); - -/**@}*/ - - -#pragma mark - CGFloat Methods - -/** - * For manipulating CGFloat. - * - * @defgroup CGFloat-Methods CGFloat Methods - * @{ - * - * These methods provide math functions on CGFloats. They could easily be replaced with - * but that is currently (Xcode 5.0) incompatible with CLANG_ENABLE_MODULES (on by default for - * many projects/targets). We'll use CG_INLINE because this really should be completely inline. - */ - -#if CGFLOAT_IS_DOUBLE - #define NI_CGFLOAT_EPSILON DBL_EPSILON -#else - #define NI_CGFLOAT_EPSILON FLT_EPSILON -#endif - -/** - * fabs()/fabsf() sized for CGFloat - */ -CG_INLINE CGFloat NICGFloatAbs(CGFloat x) { -#if CGFLOAT_IS_DOUBLE - return (CGFloat)fabs(x); -#else - return (CGFloat)fabsf(x); -#endif -} - -/** - * floor()/floorf() sized for CGFloat - */ -CG_INLINE CGFloat NICGFloatFloor(CGFloat x) { -#if CGFLOAT_IS_DOUBLE - return (CGFloat)floor(x); -#else - return (CGFloat)floorf(x); -#endif -} - -/** - * ceil()/ceilf() sized for CGFloat - */ -CG_INLINE CGFloat NICGFloatCeil(CGFloat x) { -#if CGFLOAT_IS_DOUBLE - return (CGFloat)ceil(x); -#else - return (CGFloat)ceilf(x); -#endif -} - -/** - * round()/roundf() sized for CGFloat - */ -CG_INLINE CGFloat NICGFloatRound(CGFloat x) { -#if CGFLOAT_IS_DOUBLE - return (CGFloat)round(x); -#else - return (CGFloat)roundf(x); -#endif -} - -/** - * sqrt()/sqrtf() sized for CGFloat - */ -CG_INLINE CGFloat NICGFloatSqRt(CGFloat x) { -#if CGFLOAT_IS_DOUBLE - return (CGFloat)sqrt(x); -#else - return (CGFloat)sqrtf(x); -#endif -} - -/** - * copysign()/copysignf() sized for CGFloat - */ -CG_INLINE CGFloat NICGFloatCopySign(CGFloat x, CGFloat y) { -#if CGFLOAT_IS_DOUBLE - return (CGFloat)copysign(x, y); -#else - return (CGFloat)copysignf(x, y); -#endif -} - -/** - * pow()/powf() sized for CGFloat - */ -CG_INLINE CGFloat NICGFloatPow(CGFloat x, CGFloat y) { -#if CGFLOAT_IS_DOUBLE - return (CGFloat)pow(x, y); -#else - return (CGFloat)powf(x, y); -#endif -} - -/** - * cos()/cosf() sized for CGFloat - */ -CG_INLINE CGFloat NICGFloatCos(CGFloat x) { -#if CGFLOAT_IS_DOUBLE - return (CGFloat)cos(x); -#else - return (CGFloat)cosf(x); -#endif -} - -/**@}*/ - -#pragma mark - General Purpose Methods - -/** - * For general purpose foundation type manipulation. - * - * @defgroup General-Purpose-Methods General Purpose Methods - * @{ - */ - -/** - * Deprecated method. Use NIBoundf instead. - */ -CGFloat boundf(CGFloat value, CGFloat min, CGFloat max) __NI_DEPRECATED_METHOD; // Use NIBoundf instead. MAINTENANCE: Remove by Feb 28, 2014. - -/** - * Deprecated method. Use NIBoundi instead. - */ -NSInteger boundi(NSInteger value, NSInteger min, NSInteger max) __NI_DEPRECATED_METHOD; // Use NIBoundi instead. MAINTENANCE: Remove by Feb 28, 2014. - -/** - * Bounds a given value within the min and max values. - * - * If max < min then value will be min. - * - * @returns min <= result <= max - */ -CGFloat NIBoundf(CGFloat value, CGFloat min, CGFloat max); - -/** - * Bounds a given value within the min and max values. - * - * If max < min then value will be min. - * - * @returns min <= result <= max - */ -NSInteger NIBoundi(NSInteger value, NSInteger min, NSInteger max); - -/**@}*/ - -#if defined __cplusplus -}; -#endif - -/**@}*/// End of Foundation Methods /////////////////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NIFoundationMethods.m b/Pods/Nimbus/src/core/src/NIFoundationMethods.m deleted file mode 100644 index 16c9601..0000000 --- a/Pods/Nimbus/src/core/src/NIFoundationMethods.m +++ /dev/null @@ -1,314 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIFoundationMethods.h" - -#import "NIDebuggingTools.h" -#import -#import - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -#pragma mark - NSInvocation - -NSInvocation* NIInvocationWithInstanceTarget(NSObject *targetObject, SEL selector) { - NSMethodSignature* sig = [targetObject methodSignatureForSelector:selector]; - NSInvocation* inv = [NSInvocation invocationWithMethodSignature:sig]; - [inv setTarget:targetObject]; - [inv setSelector:selector]; - return inv; -} - -// Deprecated. Please delete on the next minor version upgrade. -NSInvocation* NIInvocationWithClassTarget(Class targetClass, SEL selector) { - return NIInvocationWithInstanceTarget((NSObject *)targetClass, selector); -} - -#pragma mark - CGRect - -CGRect NIRectContract(CGRect rect, CGFloat dx, CGFloat dy) { - return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width - dx, rect.size.height - dy); -} - -CGRect NIRectExpand(CGRect rect, CGFloat dx, CGFloat dy) { - return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width + dx, rect.size.height + dy); -} - -CGRect NIRectShift(CGRect rect, CGFloat dx, CGFloat dy) { - return CGRectOffset(NIRectContract(rect, dx, dy), dx, dy); -} - -CGRect NIEdgeInsetsOutsetRect(CGRect rect, UIEdgeInsets outsets) { - return CGRectMake(rect.origin.x - outsets.left, - rect.origin.y - outsets.top, - rect.size.width + outsets.left + outsets.right, - rect.size.height + outsets.top + outsets.bottom); -} - -CGFloat NICenterX(CGSize containerSize, CGSize size) { - return NICGFloatFloor((containerSize.width - size.width) / 2.f); -} - -CGFloat NICenterY(CGSize containerSize, CGSize size) { - return NICGFloatFloor((containerSize.height - size.height) / 2.f); -} - -CGRect NIFrameOfCenteredViewWithinView(UIView* viewToCenter, UIView* containerView) { - CGPoint origin; - CGSize containerViewSize = containerView.bounds.size; - CGSize viewSize = viewToCenter.frame.size; - origin.x = NICenterX(containerViewSize, viewSize); - origin.y = NICenterY(containerViewSize, viewSize); - return CGRectMake(origin.x, origin.y, viewSize.width, viewSize.height); -} - -CGSize NISizeOfStringWithLabelProperties(NSString *string, CGSize constrainedToSize, UIFont *font, NSLineBreakMode lineBreakMode, NSInteger numberOfLines) { - if (string.length == 0) { - return CGSizeZero; - } - - CGFloat lineHeight = font.lineHeight; - CGSize size = CGSizeZero; - - if (numberOfLines == 1) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - size = [string sizeWithFont:font forWidth:constrainedToSize.width lineBreakMode:lineBreakMode]; -#pragma clang diagnostic pop - } else { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - size = [string sizeWithFont:font constrainedToSize:constrainedToSize lineBreakMode:lineBreakMode]; -#pragma clang diagnostic pop - if (numberOfLines > 0) { - size.height = MIN(size.height, numberOfLines * lineHeight); - } - } - - return size; -} - -#pragma mark - NSRange - -NSRange NIMakeNSRangeFromCFRange(CFRange range) { - // CFRange stores its values in signed longs, but we're about to copy the values into - // unsigned integers, let's check whether we're about to lose any information. - NIDASSERT(range.location >= 0 && range.location <= NSIntegerMax); - NIDASSERT(range.length >= 0 && range.length <= NSIntegerMax); - return NSMakeRange(range.location, range.length); -} - -#pragma mark - NSData - -NSString* NIMD5HashFromData(NSData* data) { - unsigned char result[CC_MD5_DIGEST_LENGTH]; - bzero(result, sizeof(result)); - CC_MD5_CTX md5Context; - CC_MD5_Init(&md5Context); - size_t bytesHashed = 0; - while (bytesHashed < [data length]) { - CC_LONG updateSize = 1024 * 1024; - if (([data length] - bytesHashed) < (size_t)updateSize) { - updateSize = (CC_LONG)([data length] - bytesHashed); - } - CC_MD5_Update(&md5Context, (char *)[data bytes] + bytesHashed, updateSize); - bytesHashed += updateSize; - } - CC_MD5_Final(result, &md5Context); - - return [NSString stringWithFormat: - @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7], - result[8], result[9], result[10], result[11], result[12], result[13], result[14], - result[15] - ]; -} - -NSString* NISHA1HashFromData(NSData* data) { - unsigned char result[CC_SHA1_DIGEST_LENGTH]; - bzero(result, sizeof(result)); - CC_SHA1_CTX sha1Context; - CC_SHA1_Init(&sha1Context); - size_t bytesHashed = 0; - while (bytesHashed < [data length]) { - CC_LONG updateSize = 1024 * 1024; - if (([data length] - bytesHashed) < (size_t)updateSize) { - updateSize = (CC_LONG)([data length] - bytesHashed); - } - CC_SHA1_Update(&sha1Context, (char *)[data bytes] + bytesHashed, updateSize); - bytesHashed += updateSize; - } - CC_SHA1_Final(result, &sha1Context); - - return [NSString stringWithFormat: - @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7], - result[8], result[9], result[10], result[11], result[12], result[13], result[14], - result[15], result[16], result[17], result[18], result[19] - ]; -} - -#pragma mark - NSString - -NSString* NIMD5HashFromString(NSString* string) { - return NIMD5HashFromData([string dataUsingEncoding:NSUTF8StringEncoding]); -} - -NSString* NISHA1HashFromString(NSString* string) { - return NISHA1HashFromData([string dataUsingEncoding:NSUTF8StringEncoding]); -} - -BOOL NIIsStringWithWhitespaceAndNewlines(NSString* string) { - NSCharacterSet* notWhitespaceAndNewlines = [[NSCharacterSet whitespaceAndNewlineCharacterSet] invertedSet]; - return [string isKindOfClass:[NSString class]] && [string rangeOfCharacterFromSet:notWhitespaceAndNewlines].length == 0; -} - -NSComparisonResult NICompareVersionStrings(NSString* string1, NSString* string2) { - NSArray *oneComponents = [string1 componentsSeparatedByString:@"a"]; - NSArray *twoComponents = [string2 componentsSeparatedByString:@"a"]; - - // The parts before the "a" - NSString *oneMain = [oneComponents objectAtIndex:0]; - NSString *twoMain = [twoComponents objectAtIndex:0]; - - // If main parts are different, return that result, regardless of alpha part - NSComparisonResult mainDiff; - if ((mainDiff = [oneMain compare:twoMain]) != NSOrderedSame) { - return mainDiff; - } - - // At this point the main parts are the same; just deal with alpha stuff - // If one has an alpha part and the other doesn't, the one without is newer - if ([oneComponents count] < [twoComponents count]) { - return NSOrderedDescending; - - } else if ([oneComponents count] > [twoComponents count]) { - return NSOrderedAscending; - - } else if ([oneComponents count] == 1) { - // Neither has an alpha part, and we know the main parts are the same - return NSOrderedSame; - } - - // At this point the main parts are the same and both have alpha parts. Compare the alpha parts - // numerically. If it's not a valid number (including empty string) it's treated as zero. - NSNumber *oneAlpha = [NSNumber numberWithInt:[[oneComponents objectAtIndex:1] intValue]]; - NSNumber *twoAlpha = [NSNumber numberWithInt:[[twoComponents objectAtIndex:1] intValue]]; - return [oneAlpha compare:twoAlpha]; -} - -NSDictionary* NIQueryDictionaryFromStringUsingEncoding(NSString* string, NSStringEncoding encoding) { - NSCharacterSet* delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@"&;"]; - NSMutableDictionary* pairs = [NSMutableDictionary dictionary]; - NSScanner* scanner = [[NSScanner alloc] initWithString:string]; - - while (![scanner isAtEnd]) { - NSString* pairString = nil; - [scanner scanUpToCharactersFromSet:delimiterSet intoString:&pairString]; - [scanner scanCharactersFromSet:delimiterSet intoString:NULL]; - - NSArray* kvPair = [pairString componentsSeparatedByString:@"="]; - if (kvPair.count == 1 || kvPair.count == 2) { - NSString* key = [kvPair[0] stringByReplacingPercentEscapesUsingEncoding:encoding]; - - NSMutableArray* values = pairs[key]; - if (nil == values) { - values = [NSMutableArray array]; - pairs[key] = values; - } - - if (kvPair.count == 1) { - [values addObject:[NSNull null]]; - - } else if (kvPair.count == 2) { - NSString* value = [kvPair[1] stringByReplacingPercentEscapesUsingEncoding:encoding]; - [values addObject:value]; - } - } - } - return [pairs copy]; -} - -NSString* NIStringByAddingPercentEscapesForURLParameterString(NSString* parameter) { - CFStringRef buffer = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, - (__bridge CFStringRef)parameter, - NULL, - (__bridge CFStringRef)@"!*'();:@&=+$,/?%#[]", - kCFStringEncodingUTF8); - - NSString* result = [NSString stringWithString:(__bridge NSString *)buffer]; - CFRelease(buffer); - return result; -} - -NSString* NIStringByAddingQueryDictionaryToString(NSString* string, NSDictionary* query) { - NSMutableArray* pairs = [NSMutableArray array]; - for (NSString* key in [query keyEnumerator]) { - NSString* value = NIStringByAddingPercentEscapesForURLParameterString([query objectForKey:key]); - NSString* pair = [NSString stringWithFormat:@"%@=%@", key, value]; - [pairs addObject:pair]; - } - - NSString* params = [pairs componentsJoinedByString:@"&"]; - if ([string rangeOfString:@"?"].location == NSNotFound) { - return [string stringByAppendingFormat:@"?%@", params]; - - } else { - return [string stringByAppendingFormat:@"&%@", params]; - } -} - -#pragma mark - General Purpose - -// Deprecated. -CGFloat boundf(CGFloat value, CGFloat min, CGFloat max) { - return NIBoundf(value, min, max); -} - -// Deprecated. -NSInteger boundi(NSInteger value, NSInteger min, NSInteger max) { - return NIBoundi(value, min, max); -} - -CGFloat NIBoundf(CGFloat value, CGFloat min, CGFloat max) { - if (max < min) { - max = min; - } - CGFloat bounded = value; - if (bounded > max) { - bounded = max; - } - if (bounded < min) { - bounded = min; - } - return bounded; -} - -NSInteger NIBoundi(NSInteger value, NSInteger min, NSInteger max) { - if (max < min) { - max = min; - } - NSInteger bounded = value; - if (bounded > max) { - bounded = max; - } - if (bounded < min) { - bounded = min; - } - return bounded; -} diff --git a/Pods/Nimbus/src/core/src/NIImageUtilities.h b/Pods/Nimbus/src/core/src/NIImageUtilities.h deleted file mode 100644 index e0dc4dd..0000000 --- a/Pods/Nimbus/src/core/src/NIImageUtilities.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import -#import - -#if defined __cplusplus -extern "C" { -#endif - -/** - * For manipulating UIImage objects. - * - * @ingroup NimbusCore - * @defgroup Image-Utilities Image Utilities - * @{ - */ - -/** - * Returns an image that is stretchable from the center. - * - * A common use of this method is to create an image that has rounded corners for a button - * and then assign a stretchable version of that image to a UIButton. - * - * This stretches the middle vertical and horizontal line of pixels, so use care when - * stretching images that have gradients. For example, an image with a vertical gradient - * can be stretched horizontally, but will look odd if stretched vertically. - */ -UIImage* NIStretchableImageFromImage(UIImage* image); - -/**@}*/// End of Image Utilities ////////////////////////////////////////////////////////////////// - -#if defined __cplusplus -}; -#endif diff --git a/Pods/Nimbus/src/core/src/NIImageUtilities.m b/Pods/Nimbus/src/core/src/NIImageUtilities.m deleted file mode 100644 index f7b866a..0000000 --- a/Pods/Nimbus/src/core/src/NIImageUtilities.m +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIImageUtilities.h" - -UIImage* NIStretchableImageFromImage(UIImage* image) { - const CGSize size = image.size; - NSInteger midX = (NSInteger)(size.width / 2.f); - NSInteger midY = (NSInteger)(size.height / 2.f); - return [image stretchableImageWithLeftCapWidth:midX topCapHeight:midY]; -} diff --git a/Pods/Nimbus/src/core/src/NIInMemoryCache.h b/Pods/Nimbus/src/core/src/NIInMemoryCache.h deleted file mode 100644 index dc5dbb7..0000000 --- a/Pods/Nimbus/src/core/src/NIInMemoryCache.h +++ /dev/null @@ -1,316 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import - -#import "NIPreprocessorMacros.h" - -/** - * For storing and accessing objects in memory. - * - * The base class, NIMemoryCache, is a generic object store that may be used for anything that - * requires support for expiration. - * - * @ingroup NimbusCore - * @defgroup In-Memory-Caches In-Memory Caches - * @{ - */ - -/** - * An in-memory cache for storing objects with expiration support. - * - * The Nimbus in-memory object cache allows you to store objects in memory with an expiration - * date attached. Objects with expiration dates drop out of the cache when they have expired. - */ -@interface NIMemoryCache : NSObject - -// Designated initializer. -- (id)initWithCapacity:(NSUInteger)capacity; - -- (NSUInteger)count; - -- (void)storeObject:(id)object withName:(NSString *)name; -- (void)storeObject:(id)object withName:(NSString *)name expiresAfter:(NSDate *)expirationDate; - -- (void)removeObjectWithName:(NSString *)name; -- (void)removeAllObjectsWithPrefix:(NSString *)prefix; -- (void)removeAllObjects; - -- (id)objectWithName:(NSString *)name; -- (BOOL)containsObjectWithName:(NSString *)name; -- (NSDate *)dateOfLastAccessWithName:(NSString *)name; - -- (NSString *)nameOfLeastRecentlyUsedObject; -- (NSString *)nameOfMostRecentlyUsedObject; - -- (void)reduceMemoryUsage; - -// Subclassing - -- (BOOL)shouldSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject; -- (void)didSetObject:(id)object withName:(NSString *)name; -- (void)willRemoveObject:(id)object withName:(NSString *)name; - -// Deprecated method. Use shouldSetObject:withName:previousObject: instead. -- (BOOL)willSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject __NI_DEPRECATED_METHOD; - -@end - -/** - * An in-memory cache for storing images with caps on the total number of pixels. - * - * When reduceMemoryUsage is called, the least recently used images are removed from the cache - * until the numberOfPixels is below maxNumberOfPixelsUnderStress. - * - * When an image is added to the cache that causes the memory usage to pass the max, the - * least recently used images are removed from the cache until the numberOfPixels is below - * maxNumberOfPixels. - * - * By default the image memory cache has no limit to its pixel count. You must explicitly - * set this value in your application. - * - * @attention If the cache is too small to fit the newly added image, then all images - * will end up being removed including the one being added. - * - * @see Nimbus::imageMemoryCache - * @see Nimbus::setImageMemoryCache: - */ -@interface NIImageMemoryCache : NIMemoryCache - -@property (nonatomic, readonly) unsigned long long numberOfPixels; - -@property (nonatomic) unsigned long long maxNumberOfPixels; // Default: 0 (unlimited) -@property (nonatomic) unsigned long long maxNumberOfPixelsUnderStress; // Default: 0 (unlimited) - -@end - -/**@}*/// End of In-Memory Cache ////////////////////////////////////////////////////////////////// - -/** @name Creating an In-Memory Cache */ - -/** - * Initializes a newly allocated cache with the given capacity. - * - * @returns An in-memory cache initialized with the given capacity. - * @fn NIMemoryCache::initWithCapacity: - */ - -/** @name Storing Objects in the Cache */ - -/** - * Stores an object in the cache. - * - * The object will be stored without an expiration date. The object will stay in the cache until - * it's bumped out due to the cache's memory limit. - * - * @param object The object being stored in the cache. - * @param name The name used as a key to store this object. - * @fn NIMemoryCache::storeObject:withName: - */ - -/** - * Stores an object in the cache with an expiration date. - * - * If an object is stored with an expiration date that has already passed then the object will - * not be stored in the cache and any existing object will be removed. The rationale behind this - * is that the object would be removed from the cache the next time it was accessed anyway. - * - * @param object The object being stored in the cache. - * @param name The name used as a key to store this object. - * @param expirationDate A date after which this object is no longer valid in the cache. - * @fn NIMemoryCache::storeObject:withName:expiresAfter: - */ - -/** @name Removing Objects from the Cache */ - -/** - * Removes an object from the cache with the given name. - * - * @param name The name used as a key to store this object. - * @fn NIMemoryCache::removeObjectWithName: - */ - -/** - * Removes all objects from the cache with a given prefix. - * - * This method requires a scan of the cache entries. - * - * @param prefix Any object name that has this prefix will be removed from the cache. - * @fn NIMemoryCache::removeAllObjectsWithPrefix: - */ - -/** - * Removes all objects from the cache, regardless of expiration dates. - * - * This will completely clear out the cache and all objects in the cache will be released. - * - * @fn NIMemoryCache::removeAllObjects - */ - -/** @name Accessing Objects in the Cache */ - -/** - * Retrieves an object from the cache. - * - * If the object has expired then the object will be removed from the cache and nil will be - * returned. - * - * @returns The object stored in the cache. The object is retained and autoreleased to - * ensure that it survives this run loop if you then remove it from the cache. - * @fn NIMemoryCache::objectWithName: - */ - -/** - * Returns a Boolean value that indicates whether an object with the given name is present - * in the cache. - * - * Does not update the access time of the object. - * - * If the object has expired then the object will be removed from the cache and NO will be - * returned. - * - * @returns YES if an object with the given name is present in the cache and has not expired, - * otherwise NO. - * @fn NIMemoryCache::containsObjectWithName: - */ - -/** - * Returns the date that the object with the given name was last accessed. - * - * Does not update the access time of the object. - * - * If the object has expired then the object will be removed from the cache and nil will be - * returned. - * - * @returns The last access date of the object if it exists and has not expired, nil - * otherwise. - * @fn NIMemoryCache::dateOfLastAccessWithName: - */ - -/** - * Retrieve the name of the object that was least recently used. - * - * This will not update the access time of the object. - * - * If the cache is empty, returns nil. - * - * @fn NIMemoryCache::nameOfLeastRecentlyUsedObject - */ - -/** - * Retrieve the key with the most fresh access. - * - * This will not update the access time of the object. - * - * If the cache is empty, returns nil. - * - * @fn NIMemoryCache::nameOfMostRecentlyUsedObject - */ - -/** @name Reducing Memory Usage Explicitly */ - -/** - * Removes all expired objects from the cache. - * - * Subclasses may add additional functionality to this implementation. - * Subclasses should call super in order to prune expired objects. - * - * This will be called when UIApplicationDidReceiveMemoryWarningNotification - * is posted. - * - * @fn NIMemoryCache::reduceMemoryUsage - */ - -/** @name Querying an In-Memory Cache */ - -/** - * Returns the number of objects currently in the cache. - * - * @returns The number of objects currently in the cache. - * @fn NIMemoryCache::count - */ - -/** - * @name Subclassing - * - * The following methods are provided to aid in subclassing and are not meant to be - * used externally. - */ - -/** - * An object is about to be stored in the cache. - * - * @param object The object that is about to be stored in the cache. - * @param name The cache name for the object. - * @param previousObject The object previously stored in the cache. This may be the - * same as object. - * @returns YES If object is allowed to be stored in the cache. - * @fn NIMemoryCache::shouldSetObject:withName:previousObject: - */ - -/** - * This method is deprecated. Please use shouldSetObject:withName:previousObject: instead. - * - * @fn NIMemoryCache::willSetObject:withName:previousObject: - */ - -/** - * An object has been stored in the cache. - * - * @param object The object that was stored in the cache. - * @param name The cache name for the object. - * @fn NIMemoryCache::didSetObject:withName: - */ - -/** - * An object is about to be removed from the cache. - * - * @param object The object about to removed from the cache. - * @param name The cache name for the object about to be removed. - * @fn NIMemoryCache::willRemoveObject:withName: - */ - -// NIImageMemoryCache - -/** @name Querying an In-Memory Image Cache */ - -/** - * Returns the total number of pixels being stored in the cache. - * - * @returns The total number of pixels being stored in the cache. - * @fn NIImageMemoryCache::numberOfPixels - */ - -/** @name Setting the Maximum Number of Pixels */ - -/** - * The maximum number of pixels this cache may ever store. - * - * Defaults to 0, which is special cased to represent an unlimited number of pixels. - * - * @returns The maximum number of pixels this cache may ever store. - * @fn NIImageMemoryCache::maxNumberOfPixels - */ - -/** - * The maximum number of pixels this cache may store after a call to reduceMemoryUsage. - * - * Defaults to 0, which is special cased to represent an unlimited number of pixels. - * - * @returns The maximum number of pixels this cache may store after a call - * to reduceMemoryUsage. - * @fn NIImageMemoryCache::maxNumberOfPixelsUnderStress - */ diff --git a/Pods/Nimbus/src/core/src/NIInMemoryCache.m b/Pods/Nimbus/src/core/src/NIInMemoryCache.m deleted file mode 100644 index da895d0..0000000 --- a/Pods/Nimbus/src/core/src/NIInMemoryCache.m +++ /dev/null @@ -1,453 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIInMemoryCache.h" - -#import "NIDebuggingTools.h" -#import "NIPreprocessorMacros.h" - -#import - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -@interface NIMemoryCache() -// Mapping from a name (usually a URL) to an internal object. -@property (nonatomic, strong) NSMutableDictionary* cacheMap; -// A linked list of least recently used cache objects. Most recently used is the tail. -@property (nonatomic, strong) NSMutableOrderedSet* lruCacheObjects; -@end - -/** - * @brief A single cache item's information. - * - * Used in expiration calculations and for storing the actual cache object. - */ -@interface NIMemoryCacheInfo : NSObject - -/** - * @brief The name used to store this object in the cache. - */ -@property (nonatomic, copy) NSString* name; - -/** - * @brief The object stored in the cache. - */ -@property (nonatomic, strong) id object; - -/** - * @brief The date after which the image is no longer valid and should be removed from the cache. - */ -@property (nonatomic, strong) NSDate* expirationDate; - -/** - * @brief The last time this image was accessed. - * - * This property is updated every time the image is fetched from or stored into the cache. It - * is used when the memory peak has been reached as a fast means of removing least-recently-used - * images. When the memory limit is reached, we sort the cache based on the last access times and - * then prune images until we're under the memory limit again. - */ -@property (nonatomic, strong) NSDate* lastAccessTime; - -/** - * @brief Determine whether this cache entry has past its expiration date. - * - * @returns YES if an expiration date has been specified and the expiration date has been passed. - * NO in all other cases. Notably if there is no expiration date then this object will - * never expire. - */ -- (BOOL)hasExpired; - -@end - -@implementation NIMemoryCache - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (id)init { - return [self initWithCapacity:0]; -} - -- (id)initWithCapacity:(NSUInteger)capacity { - if ((self = [super init])) { - _cacheMap = [[NSMutableDictionary alloc] initWithCapacity:capacity]; - _lruCacheObjects = [NSMutableOrderedSet orderedSet]; - - // Automatically reduce memory usage when we get a memory warning. - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(reduceMemoryUsage) - name:UIApplicationDidReceiveMemoryWarningNotification - object:nil]; - } - return self; -} - -- (NSString *)description { - return [NSString stringWithFormat: - @"<%@" - @" lruObjects: %@" - @" cache map: %@" - @">", - [super description], - self.lruCacheObjects, - self.cacheMap]; -} - -#pragma mark - Internal - -- (void)updateAccessTimeForInfo:(NIMemoryCacheInfo *)info { - @synchronized(self) { - NIDASSERT(nil != info); - if (nil == info) { - return; // COV_NF_LINE - } - info.lastAccessTime = [NSDate date]; - - [self.lruCacheObjects removeObject:info]; - [self.lruCacheObjects addObject:info]; - } -} - -- (NIMemoryCacheInfo *)cacheInfoForName:(NSString *)name { - NIMemoryCacheInfo* info; - @synchronized(self) { - info = self.cacheMap[name]; - } - return info; -} - -- (void)setCacheInfo:(NIMemoryCacheInfo *)info forName:(NSString *)name { - @synchronized(self) { - NIDASSERT(nil != name); - if (nil == name) { - return; - } - - // Storing in the cache counts as an access of the object, so we update the access time. - [self updateAccessTimeForInfo:info]; - - id previousObject = [self cacheInfoForName:name].object; - if ([self shouldSetObject:info.object withName:name previousObject:previousObject]) { - self.cacheMap[name] = info; - [self didSetObject:info.object withName:name]; - } - } -} - -- (void)removeCacheInfoForName:(NSString *)name { - @synchronized(self) { - NIDASSERT(nil != name); - if (nil == name) { - return; - } - - NIMemoryCacheInfo* cacheInfo = [self cacheInfoForName:name]; - [self willRemoveObject:cacheInfo.object withName:name]; - - [self.lruCacheObjects removeObject:cacheInfo]; - [self.cacheMap removeObjectForKey:name]; - } -} - -#pragma mark - Subclassing - -// Deprecated method. -- (BOOL)willSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject { - return [self shouldSetObject:object withName:name previousObject:previousObject]; -} - -- (BOOL)shouldSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject { - // Allow anything to be stored. - return YES; -} - -- (void)didSetObject:(id)object withName:(NSString *)name { - // No-op -} - -- (void)willRemoveObject:(id)object withName:(NSString *)name { - // No-op -} - -#pragma mark - Public - -- (void)storeObject:(id)object withName:(NSString *)name { - @synchronized(self) { - [self storeObject:object withName:name expiresAfter:nil]; - } -} - -- (void)storeObject:(id)object withName:(NSString *)name expiresAfter:(NSDate *)expirationDate { - @synchronized(self) { - // Don't store nil objects in the cache. - if (nil == object) { - return; - } - - if (nil != expirationDate && [[NSDate date] timeIntervalSinceDate:expirationDate] >= 0) { - // The object being stored is already expired so remove the object from the cache altogether. - [self removeObjectWithName:name]; - - // We're done here. - return; - } - - NIMemoryCacheInfo* info = [self cacheInfoForName:name]; - - // Create a new cache entry. - if (nil == info) { - info = [[NIMemoryCacheInfo alloc] init]; - info.name = name; - } - - // Store the object in the cache item. - info.object = object; - - // Override any existing expiration date. - info.expirationDate = expirationDate; - - // Commit the changes to the cache. - [self setCacheInfo:info forName:name]; - } -} - -- (id)objectWithName:(NSString *)name { - @synchronized(self) { - NIMemoryCacheInfo* info = [self cacheInfoForName:name]; - - id object = nil; - - if (nil != info) { - if ([info hasExpired]) { - [self removeObjectWithName:name]; - - } else { - // Update the access time whenever we fetch an object from the cache. - [self updateAccessTimeForInfo:info]; - - object = info.object; - } - } - - return object; - } -} - -- (BOOL)containsObjectWithName:(NSString *)name { - @synchronized(self) { - NIMemoryCacheInfo* info = [self cacheInfoForName:name]; - - if ([info hasExpired]) { - [self removeObjectWithName:name]; - return NO; - } - - return (nil != info); - } -} - -- (NSDate *)dateOfLastAccessWithName:(NSString *)name { - @synchronized(self) { - NIMemoryCacheInfo* info = [self cacheInfoForName:name]; - - if ([info hasExpired]) { - [self removeObjectWithName:name]; - return nil; - } - - return [info lastAccessTime]; - } -} - -- (NSString *)nameOfLeastRecentlyUsedObject { - @synchronized(self) { - NIMemoryCacheInfo* info = [self.lruCacheObjects firstObject]; - - if ([info hasExpired]) { - [self removeObjectWithName:info.name]; - return nil; - } - - return info.name; - } -} - -- (NSString *)nameOfMostRecentlyUsedObject { - @synchronized(self) { - NIMemoryCacheInfo* info = [self.lruCacheObjects lastObject]; - - if ([info hasExpired]) { - [self removeObjectWithName:info.name]; - return nil; - } - - return info.name; - } -} - -- (void)removeObjectWithName:(NSString *)name { - @synchronized(self) { - [self removeCacheInfoForName:name]; - } -} - -- (void)removeAllObjectsWithPrefix:(NSString *)prefix { - @synchronized(self) { - // Assertions fire if you try to modify the object you're iterating over, so we make a copy. - for (NSString* name in [self.cacheMap copy]) { - if ([name hasPrefix:prefix]) { - [self removeObjectWithName:name]; - } - } - } -} - -- (void)removeAllObjects { - @synchronized(self) { - [self.cacheMap removeAllObjects]; - [self.lruCacheObjects removeAllObjects]; - } -} - -- (void)reduceMemoryUsage { - @synchronized(self) { - // Assertions fire if you try to modify the object you're iterating over, so we make a copy. - for (id name in [self.cacheMap copy]) { - NIMemoryCacheInfo* info = [self cacheInfoForName:name]; - - if ([info hasExpired]) { - [self removeCacheInfoForName:name]; - } - } - } -} - -- (NSUInteger)count { - @synchronized(self) { - return self.cacheMap.count; - } -} - -@end - -@implementation NIMemoryCacheInfo - -- (BOOL)hasExpired { - return (nil != _expirationDate - && [[NSDate date] timeIntervalSinceDate:_expirationDate] >= 0); -} - -- (NSString *)description { - return [NSString stringWithFormat: - @"<%@" - @" name: %@" - @" object: %@" - @" expiration date: %@" - @" last access time: %@" - @">", - [super description], - self.name, - self.object, - self.expirationDate, - self.lastAccessTime]; -} - -@end - -@interface NIImageMemoryCache() -@property (nonatomic, assign) unsigned long long numberOfPixels; -@end - -@implementation NIImageMemoryCache - -- (unsigned long long)numberOfPixelsUsedByImage:(UIImage *)image { - @synchronized(self) { - if (nil == image) { - return 0; - } - - return (unsigned long long)(image.size.width * image.size.height * [image scale] * [image scale]); - } -} - -- (void)removeAllObjects { - @synchronized(self) { - [super removeAllObjects]; - - self.numberOfPixels = 0; - } -} - -- (void)reduceMemoryUsage { - @synchronized(self) { - // Remove all expired images first. - [super reduceMemoryUsage]; - - if (self.maxNumberOfPixelsUnderStress > 0) { - // Remove the least recently used images by iterating over the linked list. - while (self.numberOfPixels > self.maxNumberOfPixelsUnderStress) { - NIMemoryCacheInfo* info = [self.lruCacheObjects firstObject]; - [self removeCacheInfoForName:info.name]; - } - } - } -} - -- (BOOL)shouldSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject { - @synchronized(self) { - NIDASSERT(nil == object || [object isKindOfClass:[UIImage class]]); - if (![object isKindOfClass:[UIImage class]]) { - return NO; - } - - _numberOfPixels -= [self numberOfPixelsUsedByImage:previousObject]; - _numberOfPixels += [self numberOfPixelsUsedByImage:object]; - - return YES; - } -} - -- (void)didSetObject:(id)object withName:(NSString *)name { - @synchronized(self) { - // Reduce the cache size after the object has been set in case the cache size is smaller - // than the object that's being added and we need to remove this object right away. - if (self.maxNumberOfPixels > 0) { - // Remove least recently used images until we satisfy our memory constraints. - while (self.numberOfPixels > self.maxNumberOfPixels) { - NIMemoryCacheInfo* info = [self.lruCacheObjects firstObject]; - [self removeCacheInfoForName:info.name]; - } - } - } -} - -- (void)willRemoveObject:(id)object withName:(NSString *)name { - @synchronized(self) { - NIDASSERT(nil == object || [object isKindOfClass:[UIImage class]]); - if (nil == object || ![object isKindOfClass:[UIImage class]]) { - return; - } - - self.numberOfPixels -= [self numberOfPixelsUsedByImage:object]; - } -} - -@end - diff --git a/Pods/Nimbus/src/core/src/NINetworkActivity.h b/Pods/Nimbus/src/core/src/NINetworkActivity.h deleted file mode 100644 index aeacbf8..0000000 --- a/Pods/Nimbus/src/core/src/NINetworkActivity.h +++ /dev/null @@ -1,101 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 July 2, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import - -#import "NIPreprocessorMacros.h" - -#if defined __cplusplus -extern "C" { -#endif - -/** - * For showing network activity in the device's status bar. - * - * @ingroup NimbusCore - * @defgroup Network-Activity Network Activity - * @{ - * - * Two methods for keeping track of all active network tasks. These methods are threadsafe - * and act as a simple counter. When the counter is positive, the network activity indicator - * is displayed. - */ - -/** - * Increment the number of active network tasks. - * - * The status bar activity indicator will be spinning while there are active tasks. - * - * This method is threadsafe. - */ -void NINetworkActivityTaskDidStart(void) NI_EXTENSION_UNAVAILABLE_IOS(""); - -/** - * Decrement the number of active network tasks. - * - * The status bar activity indicator will be spinning while there are active tasks. - * - * This method is threadsafe. - */ -void NINetworkActivityTaskDidFinish(void); - -/** - * @name For Debugging Only - * @{ - * - * Methods that will only do anything interesting if the DEBUG preprocessor macro is defined. - */ - -/** - * Enable network activity debugging. - * - * @attention This won't do anything unless the DEBUG preprocessor macro is defined. - * - * The Nimbus network activity methods will only work correctly if they are the only methods to - * touch networkActivityIndicatorVisible. If you are using another library that touches - * networkActivityIndicatorVisible then the network activity indicator might not accurately - * represent its state. - * - * When enabled, the networkActivityIndicatorVisible method on UIApplication will be swizzled - * with a debugging method that checks the global network task count and verifies that state - * is maintained correctly. If it is found that networkActivityIndicatorVisible is being accessed - * directly, then an assertion will be fired. - * - * If debugging was previously enabled, this does nothing. - */ -void NIEnableNetworkActivityDebugging(void); - -/** - * Disable network activity debugging. - * - * @attention This won't do anything unless the DEBUG preprocessor macro is defined. - * - * When disabled, the networkActivityIndicatorVisible will be restored if this was previously - * enabled, otherwise this method does nothing. - * - * If debugging wasn't previously enabled, this does nothing. - */ -void NIDisableNetworkActivityDebugging(void); - -/**@}*/// End of For Debugging Only - -#if defined __cplusplus -}; -#endif - -/**@}*/// End of Network Activity ///////////////////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NINetworkActivity.m b/Pods/Nimbus/src/core/src/NINetworkActivity.m deleted file mode 100644 index eaaf064..0000000 --- a/Pods/Nimbus/src/core/src/NINetworkActivity.m +++ /dev/null @@ -1,171 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NINetworkActivity.h" - -#import "NIDebuggingTools.h" -#import "NIPreprocessorMacros.h" - -#if defined(DEBUG) || defined(NI_DEBUG) -#import "NIRuntimeClassModifications.h" -#endif - -#import -#import - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -static int gNetworkTaskCount = 0; -static pthread_mutex_t gMutex = PTHREAD_MUTEX_INITIALIZER; -static const NSTimeInterval kDelayBeforeDisablingActivity = 0.1; -static NSTimer* gScheduledDelayTimer = nil; - -@interface NINetworkActivity : NSObject -@end - - -@implementation NINetworkActivity - - -// Called after a certain amount of time has passed since all network activity has stopped. -// By delaying the turnoff of the network activity we avoid "flickering" effects when network -// activity is starting and stopping rapidly. -+ (void)disableNetworkActivity NI_EXTENSION_UNAVAILABLE_IOS("") { - pthread_mutex_lock(&gMutex); - if (nil != gScheduledDelayTimer) { - [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; - gScheduledDelayTimer = nil; - } - pthread_mutex_unlock(&gMutex); -} - -@end - - -void NINetworkActivityTaskDidStart(void) { - pthread_mutex_lock(&gMutex); - - BOOL enableNetworkActivityIndicator = (0 == gNetworkTaskCount); - - ++gNetworkTaskCount; - [gScheduledDelayTimer invalidate]; - gScheduledDelayTimer = nil; - - if (enableNetworkActivityIndicator) { - [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; - } - - pthread_mutex_unlock(&gMutex); -} - -void NINetworkActivityTaskDidFinish(void) { - pthread_mutex_lock(&gMutex); - - --gNetworkTaskCount; - // If this asserts, you don't have enough stop requests to match your start requests. - NIDASSERT(gNetworkTaskCount >= 0); - gNetworkTaskCount = MAX(0, gNetworkTaskCount); - - if (gNetworkTaskCount == 0) { - [gScheduledDelayTimer invalidate]; - gScheduledDelayTimer = nil; - - // Ensure that the timer is scheduled on the main loop, otherwise it will die when the thread - // dies. - dispatch_async(dispatch_get_main_queue(), ^{ - pthread_mutex_lock(&gMutex); - gScheduledDelayTimer = [NSTimer scheduledTimerWithTimeInterval:kDelayBeforeDisablingActivity - target:[NINetworkActivity class] - selector:@selector(disableNetworkActivity) - userInfo:nil - repeats:NO]; - pthread_mutex_unlock(&gMutex); - }); - } - - pthread_mutex_unlock(&gMutex); -} - -#pragma mark - Network Activity Debugging - -#if defined(DEBUG) || defined(NI_DEBUG) - -static BOOL gNetworkActivityDebuggingEnabled = NO; - -void NISwizzleMethodsForNetworkActivityDebugging(void); - -@implementation UIApplication (NimbusNetworkActivityDebugging) - - -- (void)nimbusDebugSetNetworkActivityIndicatorVisible:(BOOL)visible { - // This method will only be used when swizzled, so this will actually call - // setNetworkActivityIndicatorVisible: - [self nimbusDebugSetNetworkActivityIndicatorVisible:visible]; - - // Sanity check that this method isn't being called directly when debugging isn't enabled. - NIDASSERT(gNetworkActivityDebuggingEnabled); - - // If either of the following assertions fail then you should look at the call stack to - // determine what code is erroneously calling setNetworkActivityIndicatorVisible: directly. - if (visible) { - // The only time we should be enabling the network activity indicator is when the task - // count is one. - NIDASSERT(1 == gNetworkTaskCount); - - } else { - // The only time we should be disabling the network activity indicator is when the task - // count is zero. - NIDASSERT(0 == gNetworkTaskCount); - } -} - -@end - - -void NISwizzleMethodsForNetworkActivityDebugging(void) { - NISwapInstanceMethods([UIApplication class], - @selector(setNetworkActivityIndicatorVisible:), - @selector(nimbusDebugSetNetworkActivityIndicatorVisible:)); -} - -void NIEnableNetworkActivityDebugging(void) { - if (!gNetworkActivityDebuggingEnabled) { - gNetworkActivityDebuggingEnabled = YES; - NISwizzleMethodsForNetworkActivityDebugging(); - } -} - -void NIDisableNetworkActivityDebugging(void) { - if (gNetworkActivityDebuggingEnabled) { - gNetworkActivityDebuggingEnabled = NO; - NISwizzleMethodsForNetworkActivityDebugging(); - } -} - -#else // #ifndef DEBUG - - -void NIEnableNetworkActivityDebugging(void) { - // No-op -} - -void NIDisableNetworkActivityDebugging(void) { - // No-op -} - -#endif // #if defined(DEBUG) || defined(NI_DEBUG) diff --git a/Pods/Nimbus/src/core/src/NINonEmptyCollectionTesting.h b/Pods/Nimbus/src/core/src/NINonEmptyCollectionTesting.h deleted file mode 100644 index f1eb699..0000000 --- a/Pods/Nimbus/src/core/src/NINonEmptyCollectionTesting.h +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import - -#if defined __cplusplus -extern "C" { -#endif - -/** - * For testing whether a collection is of a certain type and is non-empty. - * - * @ingroup NimbusCore - * @defgroup Non-Empty-Collection-Testing Non-Empty Collection Testing - * @{ - * - * Simply calling -count on an object may not yield the expected results when enumerating it if - * certain assumptions are also made about the object's type. For example, if a JSON response - * returns a dictionary when you expected an array, casting the result to an NSArray and - * calling count will yield a positive value, but objectAtIndex: will crash the application. - * These methods provide a safer check for non-emptiness of collections. - */ - -/** - * Tests if an object is a non-nil array which is not empty. - */ -BOOL NIIsArrayWithObjects(id object); - -/** - * Tests if an object is a non-nil set which is not empty. - */ -BOOL NIIsSetWithObjects(id object); - -/** - * Tests if an object is a non-nil string which is not empty. - */ -BOOL NIIsStringWithAnyText(id object); - -#if defined __cplusplus -}; -#endif - -/**@}*/// End of Non-Empty Collection Testing ///////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NINonEmptyCollectionTesting.m b/Pods/Nimbus/src/core/src/NINonEmptyCollectionTesting.m deleted file mode 100644 index 6c1b9c9..0000000 --- a/Pods/Nimbus/src/core/src/NINonEmptyCollectionTesting.m +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import "NINonEmptyCollectionTesting.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -BOOL NIIsArrayWithObjects(id object) { - return [object isKindOfClass:[NSArray class]] && [(NSArray*)object count] > 0; -} - -BOOL NIIsSetWithObjects(id object) { - return [object isKindOfClass:[NSSet class]] && [(NSSet*)object count] > 0; -} - -BOOL NIIsStringWithAnyText(id object) { - return [object isKindOfClass:[NSString class]] && [(NSString*)object length] > 0; -} diff --git a/Pods/Nimbus/src/core/src/NINonRetainingCollections.h b/Pods/Nimbus/src/core/src/NINonRetainingCollections.h deleted file mode 100644 index 5c39e4d..0000000 --- a/Pods/Nimbus/src/core/src/NINonRetainingCollections.h +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import - -#if defined __cplusplus -extern "C" { -#endif - -/** - * For collections that don't retain their objects. - * - * @ingroup NimbusCore - * @defgroup Non-Retaining-Collections Non-Retaining Collections - * @{ - * - * Non-retaining collections have historically been used when we needed more than one delegate - * in an object. However, NSNotificationCenter is a much better solution for n > 1 delegates. - * Using a non-retaining collection is dangerous, so if you must use one, use it with extreme care. - * The danger primarily lies in the fact that by all appearances the collection should still - * operate like a regular collection, so this might lead to a lot of developer error if the - * developer assumes that the collection does, in fact, retain the object. - */ - -/** - * Creates a mutable array which does not retain references to the objects it contains. - * - * Typically used with arrays of delegates. - */ -NSMutableArray* NICreateNonRetainingMutableArray(void); - -/** - * Creates a mutable dictionary which does not retain references to the values it contains. - * - * Typically used with dictionaries of delegates. - */ -NSMutableDictionary* NICreateNonRetainingMutableDictionary(void); - -/** - * Creates a mutable set which does not retain references to the values it contains. - * - * Typically used with sets of delegates. - */ -NSMutableSet* NICreateNonRetainingMutableSet(void); - -#if defined __cplusplus -}; -#endif - -/**@}*/// End of Non-Retaining Collections //////////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NINonRetainingCollections.m b/Pods/Nimbus/src/core/src/NINonRetainingCollections.m deleted file mode 100644 index 1fa3612..0000000 --- a/Pods/Nimbus/src/core/src/NINonRetainingCollections.m +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 9, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import "NINonRetainingCollections.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -NSMutableArray* NICreateNonRetainingMutableArray(void) { - return (__bridge_transfer NSMutableArray *)CFArrayCreateMutable(nil, 0, nil); -} - -NSMutableDictionary* NICreateNonRetainingMutableDictionary(void) { - return (__bridge_transfer NSMutableDictionary *)CFDictionaryCreateMutable(nil, 0, nil, nil); -} - -NSMutableSet* NICreateNonRetainingMutableSet(void) { - return (__bridge_transfer NSMutableSet *)CFSetCreateMutable(nil, 0, nil); -} - diff --git a/Pods/Nimbus/src/core/src/NIOperations+Subclassing.h b/Pods/Nimbus/src/core/src/NIOperations+Subclassing.h deleted file mode 100644 index b08592a..0000000 --- a/Pods/Nimbus/src/core/src/NIOperations+Subclassing.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// -#import "NIOperations.h" - -@interface NIOperation() -@property (strong) NSError* lastError; -@end diff --git a/Pods/Nimbus/src/core/src/NIOperations.h b/Pods/Nimbus/src/core/src/NIOperations.h deleted file mode 100644 index 2841dae..0000000 --- a/Pods/Nimbus/src/core/src/NIOperations.h +++ /dev/null @@ -1,209 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import -#import - -#import "NIPreprocessorMacros.h" /* for weak */ - -@class NIOperation; - -typedef void (^NIOperationBlock)(NIOperation* operation); -typedef void (^NIOperationDidFailBlock)(NIOperation* operation, NSError* error); - -/** - * For writing code that runs concurrently. - * - * @ingroup NimbusCore - * @defgroup Operations Operations - * - * This collection of NSOperation implementations is meant to provide a set of common - * operations that might be used in an application to offload complex processing to a separate - * thread. - */ - -@protocol NIOperationDelegate; - -/** - * A base implementation of an NSOperation that supports traditional delegation and blocks. - * - *

Subclassing

- * - * A subclass should call the operationDid* methods to notify the delegate on the main thread - * of changes in the operation's state. Calling these methods will notify the delegate and the - * blocks if provided. - * - * @ingroup Operations - */ -@interface NIOperation : NSOperation - -@property (weak) id delegate; -@property (readonly, strong) NSError* lastError; -@property (assign) NSInteger tag; - -@property (copy) NIOperationBlock didStartBlock; -@property (copy) NIOperationBlock didFinishBlock; -@property (copy) NIOperationDidFailBlock didFailWithErrorBlock; -@property (copy) NIOperationBlock willFinishBlock; - -- (void)didStart; -- (void)didFinish; -- (void)didFailWithError:(NSError *)error; -- (void)willFinish; - -@end - -/** - * The delegate protocol for an NIOperation. - * - * @ingroup Operations - */ -@protocol NIOperationDelegate -@optional - -/** @name [NIOperationDelegate] State Changes */ - -/** The operation has started executing. */ -- (void)nimbusOperationDidStart:(NIOperation *)operation; - -/** - * The operation is about to complete successfully. - * - * This will not be called if the operation fails. - * - * This will be called from within the operation's runloop and must be thread safe. - */ -- (void)nimbusOperationWillFinish:(NIOperation *)operation; - -/** - * The operation has completed successfully. - * - * This will not be called if the operation fails. - */ -- (void)nimbusOperationDidFinish:(NIOperation *)operation; - -/** - * The operation failed in some way and has completed. - * - * operationDidFinish: will not be called. - */ -- (void)nimbusOperationDidFail:(NIOperation *)operation withError:(NSError *)error; - -@end - - -// NIOperation - -/** @name Delegation */ - -/** - * The delegate through which changes are notified for this operation. - * - * All delegate methods are performed on the main thread. - * - * @fn NIOperation::delegate - */ - - -/** @name Post-Operation Properties */ - -/** - * The error last passed to the didFailWithError notification. - * - * @fn NIOperation::lastError - */ - - -/** @name Identification */ - -/** - * A simple tagging mechanism for identifying operations. - * - * @fn NIOperation::tag - */ - - -/** @name Blocks */ - -/** - * The operation has started executing. - * - * Performed on the main thread. - * - * @fn NIOperation::didStartBlock - */ - -/** - * The operation has completed successfully. - * - * This will not be called if the operation fails. - * - * Performed on the main thread. - * - * @fn NIOperation::didFinishBlock - */ - -/** - * The operation failed in some way and has completed. - * - * didFinishBlock will not be executed. - * - * Performed on the main thread. - * - * @fn NIOperation::didFailWithErrorBlock - */ - -/** - * The operation is about to complete successfully. - * - * This will not be called if the operation fails. - * - * Performed in the operation's thread. - * - * @fn NIOperation::willFinishBlock - */ - - -/** - * @name Subclassing - * - * The following methods are provided to aid in subclassing and are not meant to be - * used externally. - */ - -/** - * On the main thread, notify the delegate that the operation has begun. - * - * @fn NIOperation::didStart - */ - -/** - * On the main thread, notify the delegate that the operation has finished. - * - * @fn NIOperation::didFinish - */ - -/** - * On the main thread, notify the delegate that the operation has failed. - * - * @fn NIOperation::didFailWithError: - */ - -/** - * In the operation's thread, notify the delegate that the operation will finish successfully. - * - * @fn NIOperation::willFinish - */ diff --git a/Pods/Nimbus/src/core/src/NIOperations.m b/Pods/Nimbus/src/core/src/NIOperations.m deleted file mode 100644 index e865417..0000000 --- a/Pods/Nimbus/src/core/src/NIOperations.m +++ /dev/null @@ -1,111 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIOperations.h" - -#import "NIDebuggingTools.h" -#import "NIPreprocessorMacros.h" -#import "NIOperations+Subclassing.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -@implementation NIOperation - -- (void)dealloc { - // For an unknown reason these block objects are not released when the NIOperation is deallocated - // with ARC enabled. - _didStartBlock = nil; - _didFinishBlock = nil; - _didFailWithErrorBlock = nil; - _willFinishBlock = nil; -} - -#pragma mark - Initiate delegate notification from the NSOperation - -- (void)didStart { - [self performSelectorOnMainThread:@selector(onMainThreadOperationDidStart) - withObject:nil - waitUntilDone:[NSThread isMainThread]]; -} - -- (void)didFinish { - [self performSelectorOnMainThread:@selector(onMainThreadOperationDidFinish) - withObject:nil - waitUntilDone:[NSThread isMainThread]]; -} - -- (void)didFailWithError:(NSError *)error { - self.lastError = error; - - [self performSelectorOnMainThread:@selector(onMainThreadOperationDidFailWithError:) - withObject:error - waitUntilDone:[NSThread isMainThread]]; -} - -- (void)willFinish { - if ([self.delegate respondsToSelector:@selector(nimbusOperationWillFinish:)]) { - [self.delegate nimbusOperationWillFinish:self]; - } - - if (nil != self.willFinishBlock) { - self.willFinishBlock(self); - } -} - -#pragma mark - Main Thread - -- (void)onMainThreadOperationDidStart { - // This method should only be called on the main thread. - NIDASSERT([NSThread isMainThread]); - - if ([self.delegate respondsToSelector:@selector(nimbusOperationDidStart:)]) { - [self.delegate nimbusOperationDidStart:self]; - } - - if (nil != self.didStartBlock) { - self.didStartBlock(self); - } -} - -- (void)onMainThreadOperationDidFinish { - // This method should only be called on the main thread. - NIDASSERT([NSThread isMainThread]); - - if ([self.delegate respondsToSelector:@selector(nimbusOperationDidFinish:)]) { - [self.delegate nimbusOperationDidFinish:self]; - } - - if (nil != self.didFinishBlock) { - self.didFinishBlock(self); - } -} - -- (void)onMainThreadOperationDidFailWithError:(NSError *)error { - // This method should only be called on the main thread. - NIDASSERT([NSThread isMainThread]); - - if ([self.delegate respondsToSelector:@selector(nimbusOperationDidFail:withError:)]) { - [self.delegate nimbusOperationDidFail:self withError:error]; - } - - if (nil != self.didFailWithErrorBlock) { - self.didFailWithErrorBlock(self, error); - } -} - -@end diff --git a/Pods/Nimbus/src/core/src/NIPaths.h b/Pods/Nimbus/src/core/src/NIPaths.h deleted file mode 100644 index 64e41e1..0000000 --- a/Pods/Nimbus/src/core/src/NIPaths.h +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import - -#if defined __cplusplus -extern "C" { -#endif - -/** - * For creating standard system paths. - * - * @ingroup NimbusCore - * @defgroup Paths Paths - * @{ - */ - -/** - * Create a path with the given bundle and the relative path appended. - * - * @param bundle The bundle to append relativePath to. If nil, [NSBundle mainBundle] - * will be used. - * @param relativePath The relative path to append to the bundle's path. - * - * @returns The bundle path concatenated with the given relative path. - */ -NSString* NIPathForBundleResource(NSBundle* bundle, NSString* relativePath); - -/** - * Create a path with the documents directory and the relative path appended. - * - * @returns The documents path concatenated with the given relative path. - */ -NSString* NIPathForDocumentsResource(NSString* relativePath); - -/** - * Create a path with the Library directory and the relative path appended. - * - * @returns The Library path concatenated with the given relative path. - */ -NSString* NIPathForLibraryResource(NSString* relativePath); - -/** - * Create a path with the caches directory and the relative path appended. - * - * @returns The caches path concatenated with the given relative path. - */ -NSString* NIPathForCachesResource(NSString* relativePath); - -#if defined __cplusplus -}; -#endif - -/**@}*/// End of Paths //////////////////////////////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NIPaths.m b/Pods/Nimbus/src/core/src/NIPaths.m deleted file mode 100644 index 32dd2af..0000000 --- a/Pods/Nimbus/src/core/src/NIPaths.m +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import "NIPaths.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -NSString* NIPathForBundleResource(NSBundle* bundle, NSString* relativePath) { - NSString* resourcePath = [(nil == bundle ? [NSBundle mainBundle] : bundle) resourcePath]; - return [resourcePath stringByAppendingPathComponent:relativePath]; -} - -NSString* NIPathForDocumentsResource(NSString* relativePath) { - static NSString* documentsPath = nil; - if (nil == documentsPath) { - NSArray* dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, - NSUserDomainMask, - YES); - documentsPath = [dirs objectAtIndex:0]; - } - return [documentsPath stringByAppendingPathComponent:relativePath]; -} - -NSString* NIPathForLibraryResource(NSString* relativePath) { - static NSString* libraryPath = nil; - if (nil == libraryPath) { - NSArray* dirs = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, - NSUserDomainMask, - YES); - libraryPath = [dirs objectAtIndex:0]; - } - return [libraryPath stringByAppendingPathComponent:relativePath]; -} - -NSString* NIPathForCachesResource(NSString* relativePath) { - static NSString* cachesPath = nil; - if (nil == cachesPath) { - NSArray* dirs = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, - NSUserDomainMask, - YES); - cachesPath = [dirs objectAtIndex:0]; - } - return [cachesPath stringByAppendingPathComponent:relativePath]; -} diff --git a/Pods/Nimbus/src/core/src/NIPreprocessorMacros.h b/Pods/Nimbus/src/core/src/NIPreprocessorMacros.h deleted file mode 100644 index 8f33e13..0000000 --- a/Pods/Nimbus/src/core/src/NIPreprocessorMacros.h +++ /dev/null @@ -1,141 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import - - -#pragma mark - Preprocessor Macros - -/** - * Preprocessor macros are added to Nimbus with care. Macros hide functionality and are difficult - * to debug, so most macros found in Nimbus are one-liners or compiler utilities. - * - *

Creating Byte- and Hex-based Colors

- * - * Nimbus provides the RGBCOLOR and RGBACOLOR macros for easily creating UIColor objects - * with byte and hex values. - * - *

Examples

- * -@code -UIColor* color = RGBCOLOR(255, 128, 64); // Fully opaque orange -UIColor* color = RGBACOLOR(255, 128, 64, 0.5); // Orange with 50% transparency -UIColor* color = RGBCOLOR(0xFF, 0x7A, 0x64); // Hexadecimal color -@endcode - * - *

Why it exists

- * - * There is no easy way to create UIColor objects using 0 - 255 range values or hexadecimal. This - * leads to code like this being written: - * -@code -UIColor* color = [UIColor colorWithRed:128.f/255.0f green:64.f/255.0f blue:32.f/255.0f alpha:1] -@endcode - * - *

Avoid requiring the -all_load and -force_load flags

- * - * Categories can introduce the need for the -all_load and -force_load because of the fact that - * the application will not load these categories on startup without them. This is due to the way - * Xcode deals with .m files that only contain categories: it doesn't load them without the - * -all_load or -force_load flag specified. - * - * There is, however, a way to force Xcode into loading the category .m file. If you provide an - * empty class implementation in the .m file then your app will pick up the category - * implementation. - * - * Example in plain UIKit: - * -@code -@interface BogusClass -@end -@implementation BogusClass -@end - -@implementation UIViewController (MyCustomCategory) -... -@end -@endcode - * - * NI_FIX_CATEGORY_BUG is a Nimbus macro that you include in your category `.m` file to save you - * the trouble of having to write a bogus class for every category. Just be sure that the name you - * provide to the macro is unique across your project or you will encounter duplicate symbol errors - * when linking. - * -@code -NI_FIX_CATEGORY_BUG(UIViewController_MyCustomCategory); - -@implementation UIViewController (MyCustomCategory) -... -@end -@endcode - * - * @ingroup NimbusCore - * @defgroup Preprocessor-Macros Preprocessor Macros - * @{ - */ - -/** - * Mark a method or property as deprecated to the compiler. - * - * Any use of a deprecated method or property will flag a warning when compiling. - * - * Borrowed from Apple's AvailabiltyInternal.h header. - * - * @htmlonly - *
- *   __AVAILABILITY_INTERNAL_DEPRECATED         __attribute__((deprecated))
- * 
- * @endhtmlonly - */ -#define __NI_DEPRECATED_METHOD __attribute__((deprecated)) - -/** - * Mark APIs as unavailable in app extensions. - * - * Use of unavailable methods, classes, or functions produces a compile error when built as part - * of an app extension target. If the method, class or function using the unavailable API has also - * been marked as unavailable in app extensions, the error will be suppressed. - */ -#ifdef NS_EXTENSION_UNAVAILABLE_IOS -#define NI_EXTENSION_UNAVAILABLE_IOS(msg) NS_EXTENSION_UNAVAILABLE_IOS(msg) -#else -#define NI_EXTENSION_UNAVAILABLE_IOS(msg) -#endif - -/** - * Force a category to be loaded when an app starts up. - * - * Add this macro before each category implementation, so we don't have to use - * -all_load or -force_load to load object files from static libraries that only contain - * categories and no classes. - * See http://developer.apple.com/library/mac/#qa/qa2006/qa1490.html for more info. - */ -#define NI_FIX_CATEGORY_BUG(name) @interface NI_FIX_CATEGORY_BUG_##name : NSObject @end \ -@implementation NI_FIX_CATEGORY_BUG_##name @end - -/** - * Creates an opaque UIColor object from a byte-value color definition. - */ -#define RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1] - -/** - * Creates a UIColor object from a byte-value color definition and alpha transparency. - */ -#define RGBACOLOR(r,g,b,a) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:(a)] - -/**@}*/// End of Preprocessor Macros ////////////////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NIRuntimeClassModifications.h b/Pods/Nimbus/src/core/src/NIRuntimeClassModifications.h deleted file mode 100644 index e3d76ae..0000000 --- a/Pods/Nimbus/src/core/src/NIRuntimeClassModifications.h +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import - -#if defined __cplusplus -extern "C" { -#endif - -/** - * For modifying class implementations at runtime. - * - * @ingroup NimbusCore - * @defgroup Runtime-Class-Modifications Runtime Class Modifications - * @{ - * - * @attention Please use caution when modifying class implementations at runtime. - * Apple is prone to rejecting apps for gratuitous use of method swapping. - * In particular, avoid swapping any NSObject methods such as dealloc, init, - * and retain/release on UIKit classes. - * - * See example: @link ExampleRuntimeDebugging.m Runtime Debugging with Method Swizzling@endlink - */ - -/** - * Swap two class instance method implementations. - * - * Use this method when you would like to replace an existing method implementation in a class - * with your own implementation at runtime. In practice this is often used to replace the - * implementations of UIKit classes where subclassing isn't an adequate solution. - * - * This will only work for methods declared with a -. - * - * After calling this method, any calls to originalSel will actually call newSel and vice versa. - * - * Uses method_exchangeImplementations to accomplish this. - */ -void NISwapInstanceMethods(Class cls, SEL originalSel, SEL newSel); - -/** - * Swap two class method implementations. - * - * Use this method when you would like to replace an existing method implementation in a class - * with your own implementation at runtime. In practice this is often used to replace the - * implementations of UIKit classes where subclassing isn't an adequate solution. - * - * This will only work for methods declared with a +. - * - * After calling this method, any calls to originalSel will actually call newSel and vice versa. - * - * Uses method_exchangeImplementations to accomplish this. - */ -void NISwapClassMethods(Class cls, SEL originalSel, SEL newSel); - -#if defined __cplusplus -}; -#endif - -/**@}*/// End of Runtime Class Modifications ////////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NIRuntimeClassModifications.m b/Pods/Nimbus/src/core/src/NIRuntimeClassModifications.m deleted file mode 100644 index 41e32bb..0000000 --- a/Pods/Nimbus/src/core/src/NIRuntimeClassModifications.m +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import "NIRuntimeClassModifications.h" - -#import - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -void NISwapInstanceMethods(Class cls, SEL originalSel, SEL newSel) { - Method originalMethod = class_getInstanceMethod(cls, originalSel); - Method newMethod = class_getInstanceMethod(cls, newSel); - method_exchangeImplementations(originalMethod, newMethod); -} - -void NISwapClassMethods(Class cls, SEL originalSel, SEL newSel) { - Method originalMethod = class_getClassMethod(cls, originalSel); - Method newMethod = class_getClassMethod(cls, newSel); - method_exchangeImplementations(originalMethod, newMethod); -} diff --git a/Pods/Nimbus/src/core/src/NISDKAvailability.h b/Pods/Nimbus/src/core/src/NISDKAvailability.h deleted file mode 100644 index a0ce759..0000000 --- a/Pods/Nimbus/src/core/src/NISDKAvailability.h +++ /dev/null @@ -1,257 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import -#import - -#import "NIPreprocessorMacros.h" - -/** - * For checking SDK feature availibility. - * - * @ingroup NimbusCore - * @defgroup SDK-Availability SDK Availability - * @{ - * - * NIIOS macros are defined in parallel to their __IPHONE_ counterparts as a consistently-defined - * means of checking __IPHONE_OS_VERSION_MAX_ALLOWED. - * - * For example: - * - * @htmlonly - *
- *     #if __IPHONE_OS_VERSION_MAX_ALLOWED >= NIIOS_3_2
- *       // This code will only compile on versions >= iOS 3.2
- *     #endif
- * 
- * @endhtmlonly - */ - -/** - * Released on July 11, 2008 - */ -#define NIIOS_2_0 20000 - -/** - * Released on September 9, 2008 - */ -#define NIIOS_2_1 20100 - -/** - * Released on November 21, 2008 - */ -#define NIIOS_2_2 20200 - -/** - * Released on June 17, 2009 - */ -#define NIIOS_3_0 30000 - -/** - * Released on September 9, 2009 - */ -#define NIIOS_3_1 30100 - -/** - * Released on April 3, 2010 - */ -#define NIIOS_3_2 30200 - -/** - * Released on June 21, 2010 - */ -#define NIIOS_4_0 40000 - -/** - * Released on September 8, 2010 - */ -#define NIIOS_4_1 40100 - -/** - * Released on November 22, 2010 - */ -#define NIIOS_4_2 40200 - -/** - * Released on March 9, 2011 - */ -#define NIIOS_4_3 40300 - -/** - * Released on October 12, 2011. - */ -#define NIIOS_5_0 50000 - -/** - * Released on March 7, 2012. - */ -#define NIIOS_5_1 50100 - -/** - * Released on September 19, 2012. - */ -#define NIIOS_6_0 60000 - -/** - * Released on January 28, 2013. - */ -#define NIIOS_6_1 60100 - -/** - * Released on September 18, 2013 - */ -#define NIIOS_7_0 70000 - -#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_0 -#define kCFCoreFoundationVersionNumber_iPhoneOS_2_0 478.23 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_1 -#define kCFCoreFoundationVersionNumber_iPhoneOS_2_1 478.26 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_2 -#define kCFCoreFoundationVersionNumber_iPhoneOS_2_2 478.29 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_0 -#define kCFCoreFoundationVersionNumber_iPhoneOS_3_0 478.47 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_1 -#define kCFCoreFoundationVersionNumber_iPhoneOS_3_1 478.52 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_2 -#define kCFCoreFoundationVersionNumber_iPhoneOS_3_2 478.61 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iOS_4_0 -#define kCFCoreFoundationVersionNumber_iOS_4_0 550.32 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iOS_4_1 -#define kCFCoreFoundationVersionNumber_iOS_4_1 550.38 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iOS_4_2 -#define kCFCoreFoundationVersionNumber_iOS_4_2 550.52 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iOS_4_3 -#define kCFCoreFoundationVersionNumber_iOS_4_3 550.52 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iOS_5_0 -#define kCFCoreFoundationVersionNumber_iOS_5_0 675.00 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iOS_5_1 -#define kCFCoreFoundationVersionNumber_iOS_5_1 690.10 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iOS_6_0 -#define kCFCoreFoundationVersionNumber_iOS_6_0 793.00 -#endif - -#ifndef kCFCoreFoundationVersionNumber_iOS_6_1 -#define kCFCoreFoundationVersionNumber_iOS_6_1 793.00 -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -/** - * Checks whether the device the app is currently running on is an iPad or not. - * - * @returns YES if the device is an iPad. - */ -BOOL NIIsPad(void); - -/** - * Checks whether the device the app is currently running on is an - * iPhone/iPod touch or not. - * - * @returns YES if the device is an iPhone or iPod touch. - */ -BOOL NIIsPhone(void); - -/** - * Checks whether the device supports tint colors on all UIViews. - * - * @returns YES if all UIView instances on the device respond to tintColor. - */ -BOOL NIIsTintColorGloballySupported(void); - -/** - * Checks whether the device's OS version is at least the given version number. - * - * Useful for runtime checks of the device's version number. - * - * @param versionNumber Any value of kCFCoreFoundationVersionNumber. - * - * @attention Apple recommends using respondsToSelector where possible to check for - * feature support. Use this method as a last resort. - */ -BOOL NIDeviceOSVersionIsAtLeast(double versionNumber); - -/** - * Fetch the screen's scale. - */ -CGFloat NIScreenScale(void); - -/** - * Returns YES if the screen is a retina display, NO otherwise. - */ -BOOL NIIsRetina(void); - -/** - * This method is now deprecated. Use [UIPopoverController class] instead. - * - * MAINTENANCE: Remove by Feb 28, 2014. - */ -Class NIUIPopoverControllerClass(void) __NI_DEPRECATED_METHOD; - -/** - * This method is now deprecated. Use [UITapGestureRecognizer class] instead. - * - * MAINTENANCE: Remove by Feb 28, 2014. - */ -Class NIUITapGestureRecognizerClass(void) __NI_DEPRECATED_METHOD; - -#if defined(__cplusplus) -} // extern "C" -#endif - -#pragma mark Building with Old SDKs - -// Define methods that were introduced in iOS 7.0. -#if __IPHONE_OS_VERSION_MAX_ALLOWED < NIIOS_7_0 - -@interface UIViewController (Nimbus7SDKAvailability) - -@property (nonatomic, assign) UIRectEdge edgesForExtendedLayout; -- (void)setNeedsStatusBarAppearanceUpdate; - -@end - -#endif - - -/**@}*/// End of SDK Availability ///////////////////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NISDKAvailability.m b/Pods/Nimbus/src/core/src/NISDKAvailability.m deleted file mode 100644 index 19703c7..0000000 --- a/Pods/Nimbus/src/core/src/NISDKAvailability.m +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook -// -// 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. -// - -#import "NimbusCore.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -#if __IPHONE_OS_VERSION_MAX_ALLOWED < NIIOS_6_0 -const UIImageResizingMode UIImageResizingModeStretch = -1; -#endif - -BOOL NIIsPad(void) { - static NSInteger isPad = -1; - if (isPad < 0) { - isPad = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) ? 1 : 0; - } - return isPad > 0; -} - -BOOL NIIsPhone(void) { - static NSInteger isPhone = -1; - if (isPhone < 0) { - isPhone = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) ? 1 : 0; - } - return isPhone > 0; -} - -BOOL NIIsTintColorGloballySupported(void) { - static NSInteger isTintColorGloballySupported = -1; - if (isTintColorGloballySupported < 0) { - UIView* view = [[UIView alloc] init]; - isTintColorGloballySupported = [view respondsToSelector:@selector(tintColor)]; - } - return isTintColorGloballySupported > 0; -} - -BOOL NIDeviceOSVersionIsAtLeast(double versionNumber) { - return kCFCoreFoundationVersionNumber >= versionNumber; -} - -CGFloat NIScreenScale(void) { - return [[UIScreen mainScreen] scale]; -} - -BOOL NIIsRetina(void) { - return NIScreenScale() > 1.f; -} - -Class NIUIPopoverControllerClass(void) { - return [UIPopoverController class]; -} - -Class NIUITapGestureRecognizerClass(void) { - return [UITapGestureRecognizer class]; -} diff --git a/Pods/Nimbus/src/core/src/NISnapshotRotation.h b/Pods/Nimbus/src/core/src/NISnapshotRotation.h deleted file mode 100644 index 219eedb..0000000 --- a/Pods/Nimbus/src/core/src/NISnapshotRotation.h +++ /dev/null @@ -1,224 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import -#import - -/** - * An object designed to easily implement snapshot rotation. - * - * Snapshot rotation involves taking two screenshots of a UIView: the "before" and the "after" - * state of the rotation. These two images are then cross-faded during the rotation, creating an - * animation that minimizes visual artifacts that would otherwise be noticed when rotation occurs. - * - * This feature will only function on iOS 6.0 and higher. On older iOS versions the view will rotate - * just as it always has. - * - * This functionality has been adopted from WWDC 2012 session 240 "Polishing Your Interface - * Rotations". - * - * @ingroup NimbusCore - * @defgroup Snapshot-Rotation Snapshot Rotation - * @{ - */ - -@protocol NISnapshotRotationDelegate; - -/** - * The NISnapshotRotation class provides support for implementing snapshot-based rotations on views. - * - * You must call this object's rotation methods from your controller in order for the rotation - * object to implement the rotation animations correctly. - */ -@interface NISnapshotRotation : NSObject - -// Designated initializer. -- (id)initWithDelegate:(id)delegate; - -@property (nonatomic, weak) id delegate; - -@property (nonatomic, readonly, assign) CGRect frameBeforeRotation; -@property (nonatomic, readonly, assign) CGRect frameAfterRotation; - -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration; -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration; -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation; - -@end - -/** - * The NITableViewSnapshotRotation class implements the fixedInsetsForSnapshotRotation: delegate - * method and forwards all other delegate methods along. - * - * If you are rotating a UITableView you can instantiate a NITableViewSnapshotRotation object and - * use it just like you would a snapshot rotation object. The NITableViewSnapshotRotation class - * intercepts the fixedInsetsForSnapshotRotation: method and returns insets that map to the - * dimensions of the content view for the first visible cell in the table view. - * - * The assigned delegate only needs to implement containerViewForSnapshotRotation: and - * rotatingViewForSnapshotRotation:. - */ -@interface NITableViewSnapshotRotation : NISnapshotRotation -@end - -/** - * The methods declared by the NISnapshotRotation protocol allow the adopting delegate to respond to - * messages from the NISnapshotRotation class and thus implement snapshot rotations. - */ -@protocol NISnapshotRotationDelegate -@required - -/** @name Accessing Rotation Views */ - -/** - * Tells the delegate to return the container view of the rotating view. - * - * This is often the controller's self.view. This view must not be the same as the rotatingView and - * rotatingView must be in the subview tree of containerView. - * - * @sa NISnapshotRotation::rotatingViewForSnapshotRotation: - */ -- (UIView *)containerViewForSnapshotRotation:(NISnapshotRotation *)snapshotRotation; - -/** - * Tells the delegate to return the rotating view. - * - * The rotating view is the view that will be snapshotted during the rotation. - * - * This view must not be the same as the containerView and must be in the subview tree of - * containerView. - * - * @sa NISnapshotRotation::containerViewForSnapshotRotation: - */ -- (UIView *)rotatingViewForSnapshotRotation:(NISnapshotRotation *)snapshotRotation; - -@optional - -/** @name Configuring Fixed Insets */ - -/** - * Asks the delegate to return the insets of the rotating view that should be fixed during rotation. - * - * This method will only be called on iOS 6.0 and higher. - * - * The returned insets will denote which parts of the snapshotted images will not stretch during - * the rotation animation. - */ -- (UIEdgeInsets)fixedInsetsForSnapshotRotation:(NISnapshotRotation *)snapshotRotation; - -@end - -#if defined __cplusplus -extern "C" { -#endif - -/** - * Returns an opaque UIImage snapshot of the given view. - * - * This method takes into account the offset of scrollable views and captures whatever is currently - * in the frame of the view. - * - * @param view A snapshot will be taken of this view. - * @returns A UIImage with the snapshot of @c view. - */ -UIImage* NISnapshotOfView(UIView* view); - -/** - * Returns a UIImageView with an image snapshot of the given view. - * - * The frame of the returned view is set to match the frame of @c view. - * - * @param view A snapshot will be taken of this view. - * @returns A UIImageView with the snapshot of @c view and matching frame. - */ -UIImageView* NISnapshotViewOfView(UIView* view); - -/** - * Returns a UIImage snapshot of the given view with transparency. - * - * This method takes into account the offset of scrollable views and captures whatever is currently - * in the frame of the view. - * - * @param view A snapshot will be taken of this view. - * @returns A UIImage with the snapshot of @c view. - */ -UIImage* NISnapshotOfViewWithTransparency(UIView* view); - -/** - * Returns a UIImageView with an image snapshot with transparency of the given view. - * - * The frame of the returned view is set to match the frame of @c view. - * - * @param view A snapshot will be taken of this view. - * @returns A UIImageView with the snapshot of @c view and matching frame. - */ -UIImageView* NISnapshotViewOfViewWithTransparency(UIView* view); - -#if defined __cplusplus -} -#endif - -/** - * @} - */ - -/** @name Creating a Snapshot Rotation Object */ - -/** - * Initializes a newly allocated rotation object with a given delegate. - * - * @param delegate A delegate that implements the NISnapshotRotation protocol. - * @returns A NISnapshotRotation object initialized with @c delegate. - * @fn NISnapshotRotation::initWithDelegate: - */ - -/** @name Accessing the Delegate */ - -/** - * The delegate of the snapshot rotation object. - * - * The delegate must adopt the NISnapshotRotation protocol. The NISnapshotRotation class, which does - * not retain the delegate, invokes each protocol method the delegate implements. - * - * @fn NISnapshotRotation::delegate - */ - -/** @name Implementing UIViewController Autorotation */ - -/** - * Prepares the animation for a rotation by taking a snapshot of the rotatingView in its current - * state. - * - * This method must be called from your UIViewController implementation. - * - * @fn NISnapshotRotation::willRotateToInterfaceOrientation:duration: - */ - -/** - * Crossfades between the initial and final snapshots. - * - * This method must be called from your UIViewController implementation. - * - * @fn NISnapshotRotation::willAnimateRotationToInterfaceOrientation:duration: - */ - -/** - * Finalizes the rotation animation by removing the snapshot views from the container view. - * - * This method must be called from your UIViewController implementation. - * - * @fn NISnapshotRotation::didRotateFromInterfaceOrientation: - */ diff --git a/Pods/Nimbus/src/core/src/NISnapshotRotation.m b/Pods/Nimbus/src/core/src/NISnapshotRotation.m deleted file mode 100644 index c337e6a..0000000 --- a/Pods/Nimbus/src/core/src/NISnapshotRotation.m +++ /dev/null @@ -1,299 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// This code was originally found in Apple's WWDC Session 240 on -// "Polishing Your Interface Rotations" and has been repurposed into a reusable class. -// -// 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. -// - -#import "NISnapshotRotation.h" - -#import "NIDebuggingTools.h" -#import "NISDKAvailability.h" -#import -#import - -#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0 -#error "Nimbus Snapshot Rotation requires iOS 6 or higher." -#endif - -UIImage* NISnapshotOfViewWithTransparencyOption(UIView* view, BOOL transparency); - -UIImage* NISnapshotOfViewWithTransparencyOption(UIView* view, BOOL transparency) { - // Passing 0 as the last argument ensures that the image context will match the current device's - // scaling mode. - UIGraphicsBeginImageContextWithOptions(view.bounds.size, !transparency, 0); - - CGContextRef cx = UIGraphicsGetCurrentContext(); - - // Views that can scroll do so by modifying their bounds. We want to capture the part of the view - // that is currently in the frame, so we offset by the bounds of the view accordingly. - CGContextTranslateCTM(cx, -view.bounds.origin.x, -view.bounds.origin.y); - - BOOL didDraw = NO; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= NIIOS_7_0 - if ([view respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) { - didDraw = [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES]; - } -#endif - if (!didDraw) { - [view.layer renderInContext:cx]; - } - - UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - return image; -} - -UIImage* NISnapshotOfView(UIView* view) { - return NISnapshotOfViewWithTransparencyOption(view, NO); -} - -UIImageView* NISnapshotViewOfView(UIView* view) { - UIImage* image = NISnapshotOfView(view); - - UIImageView* snapshotView = [[UIImageView alloc] initWithImage:image]; - snapshotView.frame = view.frame; - - return snapshotView; -} - -UIImage* NISnapshotOfViewWithTransparency(UIView* view) { - return NISnapshotOfViewWithTransparencyOption(view, YES); -} - -UIImageView* NISnapshotViewOfViewWithTransparency(UIView* view) { - UIImage* image = NISnapshotOfViewWithTransparency(view); - - UIImageView* snapshotView = [[UIImageView alloc] initWithImage:image]; - snapshotView.frame = view.frame; - - return snapshotView; -} - -@interface NISnapshotRotation() -@property (nonatomic, assign) BOOL isSupportedOS; -@property (nonatomic, assign) CGRect frameBeforeRotation; -@property (nonatomic, assign) CGRect frameAfterRotation; - -@property (nonatomic, strong) UIImageView* snapshotViewBeforeRotation; -@property (nonatomic, strong) UIImageView* snapshotViewAfterRotation; -@end - -@implementation NISnapshotRotation - -- (id)initWithDelegate:(id)delegate { - if ((self = [super init])) { - _delegate = delegate; - - // Check whether this feature is supported or not. - UIImage* image = [[UIImage alloc] init]; - _isSupportedOS = [image respondsToSelector:@selector(resizableImageWithCapInsets:resizingMode:)]; - } - return self; -} - -- (id)init { - return [self initWithDelegate:nil]; -} - -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - if (!self.isSupportedOS) { - return; - } - - UIView* containerView = [self.delegate containerViewForSnapshotRotation:self]; - UIView* rotationView = [self.delegate rotatingViewForSnapshotRotation:self]; - - // The container view must not be the same as the rotation view. - NIDASSERT(containerView != rotationView); - if (containerView == rotationView) { - return; - } - - self.frameBeforeRotation = rotationView.frame; - self.snapshotViewBeforeRotation = NISnapshotViewOfViewWithTransparency(rotationView); - [containerView insertSubview:self.snapshotViewBeforeRotation aboveSubview:rotationView]; -} - -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - if (!self.isSupportedOS) { - return; - } - - UIView* containerView = [self.delegate containerViewForSnapshotRotation:self]; - UIView* rotationView = [self.delegate rotatingViewForSnapshotRotation:self]; - - // The container view must not be the same as the rotation view. - NIDASSERT(containerView != rotationView); - if (containerView == rotationView) { - return; - } - - self.frameAfterRotation = rotationView.frame; - - [UIView setAnimationsEnabled:NO]; - - self.snapshotViewAfterRotation = NISnapshotViewOfViewWithTransparency(rotationView); - // Set the new frame while maintaining the old frame's height. - self.snapshotViewAfterRotation.frame = CGRectMake(self.frameBeforeRotation.origin.x, - self.frameBeforeRotation.origin.y, - self.frameBeforeRotation.size.width, - self.snapshotViewAfterRotation.frame.size.height); - - UIImage* imageBeforeRotation = self.snapshotViewBeforeRotation.image; - UIImage* imageAfterRotation = self.snapshotViewAfterRotation.image; - - if ([self.delegate respondsToSelector:@selector(fixedInsetsForSnapshotRotation:)]) { - UIEdgeInsets fixedInsets = [self.delegate fixedInsetsForSnapshotRotation:self]; - - imageBeforeRotation = [imageBeforeRotation resizableImageWithCapInsets:fixedInsets resizingMode:UIImageResizingModeStretch]; - imageAfterRotation = [imageAfterRotation resizableImageWithCapInsets:fixedInsets resizingMode:UIImageResizingModeStretch]; - } - - self.snapshotViewBeforeRotation.image = imageBeforeRotation; - self.snapshotViewAfterRotation.image = imageAfterRotation; - - [UIView setAnimationsEnabled:YES]; - - if (imageAfterRotation.size.height < imageBeforeRotation.size.height) { - self.snapshotViewAfterRotation.alpha = 0; - - [containerView insertSubview:self.snapshotViewAfterRotation aboveSubview:self.snapshotViewBeforeRotation]; - - self.snapshotViewAfterRotation.alpha = 1; - - } else { - [containerView insertSubview:self.snapshotViewAfterRotation belowSubview:self.snapshotViewBeforeRotation]; - self.snapshotViewBeforeRotation.alpha = 0; - } - - self.snapshotViewAfterRotation.frame = self.frameAfterRotation; - self.snapshotViewBeforeRotation.frame = CGRectMake(self.frameAfterRotation.origin.x, - self.frameAfterRotation.origin.y, - self.frameAfterRotation.size.width, - self.snapshotViewBeforeRotation.frame.size.height); - - rotationView.hidden = YES; -} - -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { - if (!self.isSupportedOS) { - return; - } - - UIView* containerView = [self.delegate containerViewForSnapshotRotation:self]; - UIView* rotationView = [self.delegate rotatingViewForSnapshotRotation:self]; - - // The container view must not be the same as the rotation view. - NIDASSERT(containerView != rotationView); - if (containerView == rotationView) { - return; - } - - [self.snapshotViewBeforeRotation removeFromSuperview]; - [self.snapshotViewAfterRotation removeFromSuperview]; - self.snapshotViewBeforeRotation = nil; - self.snapshotViewAfterRotation = nil; - - rotationView.hidden = NO; -} - -@end - -@interface NITableViewSnapshotRotation() -@property (nonatomic, weak) id forwardingDelegate; -@end - -@implementation NITableViewSnapshotRotation - -- (void)setDelegate:(id)delegate { - if (delegate == self) { - [super setDelegate:delegate]; - - } else { - self.forwardingDelegate = delegate; - } -} - -- (id)init { - if ((self = [super init])) { - self.delegate = self; - } - return self; -} - -#pragma mark - Forward Invocations - -- (BOOL)shouldForwardSelectorToDelegate:(SEL)selector { - struct objc_method_description description; - // Only forward the selector if it's part of the protocol. - description = protocol_getMethodDescription(@protocol(NISnapshotRotationDelegate), selector, NO, YES); - - BOOL isSelectorInProtocol = (description.name != NULL && description.types != NULL); - return (isSelectorInProtocol && [self.forwardingDelegate respondsToSelector:selector]); -} - -- (BOOL)respondsToSelector:(SEL)selector { - if ([super respondsToSelector:selector] == YES) { - return YES; - - } else { - return [self shouldForwardSelectorToDelegate:selector]; - } -} - -- (id)forwardingTargetForSelector:(SEL)selector { - if ([self shouldForwardSelectorToDelegate:selector]) { - return self.forwardingDelegate; - - } else { - return nil; - } -} - -#pragma mark - NISnapshotRotation - -- (UIView *)containerViewForSnapshotRotation:(NISnapshotRotation *)snapshotRotation { - return [self.forwardingDelegate containerViewForSnapshotRotation:snapshotRotation]; -} - -- (UIView *)rotatingViewForSnapshotRotation:(NISnapshotRotation *)snapshotRotation { - return [self.forwardingDelegate rotatingViewForSnapshotRotation:snapshotRotation]; -} - -- (UIEdgeInsets)fixedInsetsForSnapshotRotation:(NISnapshotRotation *)snapshotRotation { - UIEdgeInsets insets = UIEdgeInsetsZero; - - // Find the right edge of the content view in the coordinate space of the UITableView. - UIView* rotatingView = [self.forwardingDelegate rotatingViewForSnapshotRotation:snapshotRotation]; - NIDASSERT([rotatingView isKindOfClass:[UITableView class]]); - if ([rotatingView isKindOfClass:[UITableView class]]) { - UITableView* tableView = (UITableView *)rotatingView; - - NSArray* visibleCells = tableView.visibleCells; - if (visibleCells.count > 0) { - UIView* contentView = [[visibleCells objectAtIndex:0] contentView]; - CGFloat contentViewRightEdge = [tableView convertPoint:CGPointMake(contentView.bounds.size.width, 0) fromView:contentView].x; - - CGFloat fixedRightWidth = tableView.bounds.size.width - contentViewRightEdge; - CGFloat fixedLeftWidth = MIN(snapshotRotation.frameAfterRotation.size.width, snapshotRotation.frameBeforeRotation.size.width) - fixedRightWidth - 1; - insets = UIEdgeInsetsMake(0, fixedLeftWidth, 0, fixedRightWidth); - } - } - return insets; -} - -@end diff --git a/Pods/Nimbus/src/core/src/NIState.h b/Pods/Nimbus/src/core/src/NIState.h deleted file mode 100644 index 7d53e9c..0000000 --- a/Pods/Nimbus/src/core/src/NIState.h +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import - -@class NIImageMemoryCache; - -/** - * For modifying Nimbus state information. - * - * @ingroup NimbusCore - * @defgroup Core-State State - * @{ - * - * The Nimbus core provides a common layer of features used by nearly all of the libraries in - * the Nimbus ecosystem. Here you will find methods for accessing and setting the global image - * cache amongst other things. - */ - -/** - * The Nimbus state interface. - * - * @ingroup Core-State - */ -@interface Nimbus : NSObject - -#pragma mark Accessing Global State /** @name Accessing Global State */ - -/** - * Access the global image memory cache. - * - * If a cache hasn't been assigned via Nimbus::setGlobalImageMemoryCache: then one will be created - * automatically. - * - * @remarks The default image cache has no upper limit on its memory consumption. It is - * up to you to specify an upper limit in your application. - */ -+ (NIImageMemoryCache *)imageMemoryCache; - -/** - * Access the global network operation queue. - * - * The global network operation queue exists to be used for asynchronous network requests if - * you choose. By defining a global operation queue in the core of Nimbus, we can ensure that - * all libraries that depend on core will use the same network operation queue unless configured - * otherwise. - * - * If an operation queue hasn't been assigned via Nimbus::setGlobalNetworkOperationQueue: then - * one will be created automatically with the default iOS settings. - */ -+ (NSOperationQueue *)networkOperationQueue; - -#pragma mark Modifying Global State /** @name Modifying Global State */ - -/** - * Set the global image memory cache. - * - * The cache will be retained and the old cache released. - */ -+ (void)setImageMemoryCache:(NIImageMemoryCache *)imageMemoryCache; - -/** - * Set the global network operation queue. - * - * The queue will be retained and the old queue released. - */ -+ (void)setNetworkOperationQueue:(NSOperationQueue *)queue; - -@end - -/**@}*/// End of State //////////////////////////////////////////////////////////////////////////// diff --git a/Pods/Nimbus/src/core/src/NIState.m b/Pods/Nimbus/src/core/src/NIState.m deleted file mode 100644 index 064e20f..0000000 --- a/Pods/Nimbus/src/core/src/NIState.m +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIState.h" - -#import "NIInMemoryCache.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -static NIImageMemoryCache* sNimbusGlobalMemoryCache = nil; -static NSOperationQueue* sNimbusGlobalOperationQueue = nil; - -@implementation Nimbus - -+ (void)setImageMemoryCache:(NIImageMemoryCache *)imageMemoryCache { - if (sNimbusGlobalMemoryCache != imageMemoryCache) { - sNimbusGlobalMemoryCache = nil; - sNimbusGlobalMemoryCache = imageMemoryCache; - } -} - -+ (NIImageMemoryCache *)imageMemoryCache { - if (nil == sNimbusGlobalMemoryCache) { - sNimbusGlobalMemoryCache = [[NIImageMemoryCache alloc] init]; - } - return sNimbusGlobalMemoryCache; -} - -+ (void)setNetworkOperationQueue:(NSOperationQueue *)queue { - if (sNimbusGlobalOperationQueue != queue) { - sNimbusGlobalOperationQueue = nil; - sNimbusGlobalOperationQueue = queue; - } -} - -+ (NSOperationQueue *)networkOperationQueue { - if (nil == sNimbusGlobalOperationQueue) { - sNimbusGlobalOperationQueue = [[NSOperationQueue alloc] init]; - } - return sNimbusGlobalOperationQueue; -} - -@end diff --git a/Pods/Nimbus/src/core/src/NIViewRecycler.h b/Pods/Nimbus/src/core/src/NIViewRecycler.h deleted file mode 100644 index 1925ce1..0000000 --- a/Pods/Nimbus/src/core/src/NIViewRecycler.h +++ /dev/null @@ -1,164 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import -#import - -/** - * For recycling views in scroll views. - * - * @ingroup NimbusCore - * @defgroup Core-View-Recycling View Recyling - * @{ - * - * View recycling is an important aspect of iOS memory management and performance when building - * scroll views. UITableView uses view recycling via the table cell dequeue mechanism. - * NIViewRecycler implements this recycling functionality, allowing you to implement recycling - * mechanisms in your own views and controllers. - * - * - *

Example Use

- * - * Imagine building a UITableView. We'll assume that a viewRecycler object exists in the view. - * - * Views are usually recycled once they are no longer on screen, so within a did scroll event - * we might have code like the following: - * -@code -for (UIView* view in visibleViews) { - if (![self isVisible:view]) { - [viewRecycler recycleView:view]; - [view removeFromSuperview]; - } -} -@endcode - * - * This will take the views that are no longer visible and add them to the recycler. At a later - * point in that same didScroll code we will check if there are any new views that are visible. - * This is when we try to dequeue a recycled view from the recycler. - * -@code -UIView* view = [viewRecycler dequeueReusableViewWithIdentifier:reuseIdentifier]; -if (nil == view) { - // Allocate a new view that conforms to the NIRecyclableView protocol. - view = [[[...]] autorelease]; -} -[self addSubview:view]; -@endcode - * - */ - -@protocol NIRecyclableView; - -/** - * An object for efficiently reusing views by recycling and dequeuing them from a pool of views. - * - * This sort of object is likely what UITableView and NIPagingScrollView use to recycle their views. - */ -@interface NIViewRecycler : NSObject - -- (UIView *)dequeueReusableViewWithIdentifier:(NSString *)reuseIdentifier; - -- (void)recycleView:(UIView *)view; - -- (void)removeAllViews; - -@end - -/** - * The NIRecyclableView protocol defines a set of optional methods that a view may implement to - * handle being added to a NIViewRecycler. - */ -@protocol NIRecyclableView - -@optional - -/** - * The identifier used to categorize views into buckets for reuse. - * - * Views will be reused when a new view is requested with a matching identifier. - * - * If the reuseIdentifier is nil then the class name will be used. - */ -@property (nonatomic, copy) NSString* reuseIdentifier; - -/** - * Called immediately after the view has been dequeued from the recycled view pool. - */ -- (void)prepareForReuse; - -@end - -/** - * A simple implementation of the NIRecyclableView protocol as a UIView. - * - * This class can be used as a base class for building recyclable views if specific reuse - * identifiers are necessary, e.g. when the same class might have different implementations - * depending on the reuse identifier. - * - * Assuming functionality is consistent for a given class it is simpler not to have a - * reuseIdentifier, making the view recycler use the class name as the reuseIdentifier. In this case - * subclassing this class is overkill. - */ -@interface NIRecyclableView : UIView - -// Designated initializer. -- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier; - -@property (nonatomic, copy) NSString* reuseIdentifier; - -@end - -/**@}*/ // End of View Recyling - -/** - * Dequeues a reusable view from the recycled views pool if one exists, otherwise returns nil. - * - * @fn NIViewRecycler::dequeueReusableViewWithIdentifier: - * @param reuseIdentifier Often the name of the class of view you wish to fetch. - */ - -/** - * Adds a given view to the recycled views pool. - * - * @fn NIViewRecycler::recycleView: - * @param view The view to recycle. The reuse identifier will be retrieved from the view - * via the NIRecyclableView protocol. - */ - -/** - * Removes all of the views from the recycled views pool. - * - * @fn NIViewRecycler::removeAllViews - */ - -/** - * Initializes a newly allocated view with the given reuse identifier. - * - * This is the designated initializer. - * - * @fn NIRecyclableView::initWithReuseIdentifier: - * @param reuseIdentifier The identifier that will be used to group this view in the view - * recycler. - */ - -/** - * This view's reuse identifier. - * - * Used by NIViewRecycler to pool this view into a group of similar recycled views. - * - * @fn NIRecyclableView::reuseIdentifier - */ diff --git a/Pods/Nimbus/src/core/src/NIViewRecycler.m b/Pods/Nimbus/src/core/src/NIViewRecycler.m deleted file mode 100644 index d5bcf50..0000000 --- a/Pods/Nimbus/src/core/src/NIViewRecycler.m +++ /dev/null @@ -1,111 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIViewRecycler.h" - -#import "NimbusCore.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -@interface NIViewRecycler() -@property (nonatomic, strong) NSMutableDictionary* reuseIdentifiersToRecycledViews; -@end - -@implementation NIViewRecycler - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (id)init { - if ((self = [super init])) { - _reuseIdentifiersToRecycledViews = [[NSMutableDictionary alloc] init]; - - NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:self - selector:@selector(reduceMemoryUsage) - name:UIApplicationDidReceiveMemoryWarningNotification - object:nil]; - } - return self; -} - -#pragma mark - Memory Warnings - -- (void)reduceMemoryUsage { - [self removeAllViews]; -} - -#pragma mark - Public - -- (UIView *)dequeueReusableViewWithIdentifier:(NSString *)reuseIdentifier { - NSMutableArray* views = [_reuseIdentifiersToRecycledViews objectForKey:reuseIdentifier]; - UIView* view = [views lastObject]; - if (nil != view) { - [views removeLastObject]; - if ([view respondsToSelector:@selector(prepareForReuse)]) { - [view prepareForReuse]; - } - } - return view; -} - -- (void)recycleView:(UIView *)view { - NIDASSERT([view isKindOfClass:[UIView class]]); - - NSString* reuseIdentifier = nil; - if ([view respondsToSelector:@selector(reuseIdentifier)]) { - reuseIdentifier = [view reuseIdentifier];; - } - if (nil == reuseIdentifier) { - reuseIdentifier = NSStringFromClass([view class]); - } - - NIDASSERT(nil != reuseIdentifier); - if (nil == reuseIdentifier) { - return; - } - - NSMutableArray* views = [_reuseIdentifiersToRecycledViews objectForKey:reuseIdentifier]; - if (nil == views) { - views = [[NSMutableArray alloc] init]; - [_reuseIdentifiersToRecycledViews setObject:views forKey:reuseIdentifier]; - } - [views addObject:view]; -} - -- (void)removeAllViews { - [_reuseIdentifiersToRecycledViews removeAllObjects]; -} - -@end - -@implementation NIRecyclableView - -- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier { - if ((self = [super initWithFrame:CGRectZero])) { - _reuseIdentifier = reuseIdentifier; - } - return self; -} - -- (id)initWithFrame:(CGRect)frame { - return [self initWithReuseIdentifier:nil]; -} - -@end diff --git a/Pods/Nimbus/src/core/src/NimbusCore+Additions.h b/Pods/Nimbus/src/core/src/NimbusCore+Additions.h deleted file mode 100644 index aebaa2a..0000000 --- a/Pods/Nimbus/src/core/src/NimbusCore+Additions.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -// All category documentation is found in the source files due to limitations of Doxygen. -// Look for the documentation in the Classes tab of the documentation. - -#import -#import - -#import "NimbusCore.h" - -// Additions -#import "UIResponder+NimbusCore.h" diff --git a/Pods/Nimbus/src/core/src/NimbusCore.h b/Pods/Nimbus/src/core/src/NimbusCore.h deleted file mode 100644 index 71c2aa9..0000000 --- a/Pods/Nimbus/src/core/src/NimbusCore.h +++ /dev/null @@ -1,120 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -/** - * @defgroup NimbusCore Nimbus Core - * - *
- * - * Nimbus' Core defines the foundation upon which all other Nimbus features are built. - * Within the core you will find common elements used to build iOS applications - * including in-memory caches, path manipulation, and SDK availability. These features form - * the foundation upon which all other Nimbus libraries are built. - * - *

How Features are Added to the Core

- * - * As a general rule of thumb, if something is used between multiple independent libraries or - * applications with little variation, it likely qualifies to be added to the Core. - * - *

Exceptions

- * - * Standalone user interface components are rarely acceptable features to add to the Core. - * For example: photo viewers, pull to refresh, launchers, attributed labels. - * - * Nimbus is not UIKit: we don't have the privilege of being an assumed cost on every iOS - * device. Developers must carefully weigh whether it is worth adding a Nimbus feature - along - * with its dependencies - over building the feature themselves or using another library. This - * means that an incredible amount of care must be placed into deciding what gets added to the - * Core. - * - *

How Features are Removed from the Core

- * - * It is inevitable that certain aspects of the Core will grow and develop over time. If a - * feature gets to the point where the value of being a separate library is greater than the - * overhead of managing such a library, then the feature should be considered for removal - * from the Core. - * - * Great care must be taken to ensure that Nimbus doesn't become a framework composed of - * hundreds of miniscule libraries. - * - *

Common autoresizing masks

- * - * Nimbus provides the following macros: UIViewAutoresizingFlexibleMargins, - * UIViewAutoresizingFlexibleDimensions, UIViewAutoresizingNavigationBar, and - * UIViewAutoresizingToolbarBar. - * -@code -// Create a view that fills its superview's bounds. -UIView* contentView = [[UIView alloc] initWithFrame:self.view.bounds]; -contentView.autoresizingMask = UIViewAutoresizingFlexibleDimensions; -[self.view addSubview:contentView]; - -// Create a view that is always centered in the superview's bounds. -UIView* centeredView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)]; -centeredView.autoresizingMask = UIViewAutoresizingFlexibleMargins; -// Center the view within the superview however you choose. -[self.view addSubview:centeredView]; - -// Create a navigation bar that stays fixed to the top. -UINavigationBar* navBar = [[UINavigationBar alloc] initWithFrame:CGRectZero]; -[navBar sizeToFit]; -navBar.autoresizingMask = UIViewAutoresizingNavigationBar; -[self.view addSubview:navBar]; - -// Create a toolbar that stays fixed to the bottom. -UIToolbar* toolBar = [[UIToolbar alloc] initWithFrame:CGRectZero]; -[toolBar sizeToFit]; -toolBar.autoresizingMask = UIViewAutoresizingToolbarBar; -[self.view addSubview:toolBar]; -@endcode - * - *

Why they exist

- * - * Using the existing UIViewAutoresizing flags can be tedious for common flags. - * - * For example, to make a view have flexible margins you would need to write four flags: - * -@code -view.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin - | UIViewAutoresizingFlexibleTopMargin - | UIViewAutoresizingFlexibleRightMargin - | UIViewAutoresizingFlexibleBottomMargin); -@endcode - */ - -#import -#import - -#import "NIActions.h" -#import "NIButtonUtilities.h" -#import "NICommonMetrics.h" -#import "NIDebuggingTools.h" -#import "NIDeviceOrientation.h" -#import "NIError.h" -#import "NIFoundationMethods.h" -#import "NIImageUtilities.h" -#import "NIInMemoryCache.h" -#import "NINetworkActivity.h" -#import "NINonEmptyCollectionTesting.h" -#import "NINonRetainingCollections.h" -#import "NIOperations.h" -#import "NIPaths.h" -#import "NIPreprocessorMacros.h" -#import "NIRuntimeClassModifications.h" -#import "NISDKAvailability.h" -#import "NISnapshotRotation.h" -#import "NIState.h" -#import "NIViewRecycler.h" diff --git a/Pods/Nimbus/src/core/src/UIResponder+NimbusCore.h b/Pods/Nimbus/src/core/src/UIResponder+NimbusCore.h deleted file mode 100644 index 1d400a6..0000000 --- a/Pods/Nimbus/src/core/src/UIResponder+NimbusCore.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// +currentFirstResponder originally written by Jakob Egger, adapted by Jeff Verkoeyen. -// -// 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. -// - -#import - -// Documentation for these additions is found in the .m file. -@interface UIResponder (NimbusCore) - -+ (instancetype)nimbus_currentFirstResponder; - -@end diff --git a/Pods/Nimbus/src/core/src/UIResponder+NimbusCore.m b/Pods/Nimbus/src/core/src/UIResponder+NimbusCore.m deleted file mode 100644 index 328e16f..0000000 --- a/Pods/Nimbus/src/core/src/UIResponder+NimbusCore.m +++ /dev/null @@ -1,49 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// +currentFirstResponder originally written by Jakob Egger, adapted by Jeff Verkoeyen. -// -// 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. -// - -#import "UIResponder+NimbusCore.h" - -#import "NIPreprocessorMacros.h" - -// Adapted from http://stackoverflow.com/questions/5029267/is-there-any-way-of-asking-an-ios-view-which-of-its-children-has-first-responder/14135456#14135456 - -static __weak id sCurrentFirstResponder = nil; - -NI_FIX_CATEGORY_BUG(UIResponderNimbusCore) -/** - * For working with UIResponders. - */ -@implementation UIResponder (NimbusCore) - -/** - * Returns the current first responder by sending an action from the UIApplication. - * - * The implementation was adapted from http://stackoverflow.com/questions/5029267/is-there-any-way-of-asking-an-ios-view-which-of-its-children-has-first-responder/14135456#14135456 - */ -+ (instancetype)nimbus_currentFirstResponder { - sCurrentFirstResponder = nil; - [[UIApplication sharedApplication] sendAction:@selector(nimbus_findFirstResponder:) - to:nil from:nil forEvent:nil]; - return sCurrentFirstResponder; -} - -- (void)nimbus_findFirstResponder:(id)sender { - sCurrentFirstResponder = self; -} - -@end diff --git a/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView+Subclassing.h b/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView+Subclassing.h deleted file mode 100644 index 8776d06..0000000 --- a/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView+Subclassing.h +++ /dev/null @@ -1,123 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIPagingScrollView.h" - -// Methods that are meant to be subclassed. -@interface NIPagingScrollView (Subclassing) - -// Meant to be subclassed. Default implementations are stubs. -- (void)willDisplayPage:(UIView *)pageView; -- (void)didRecyclePage:(UIView *)pageView; -- (void)didReloadNumberOfPages; -- (void)didChangeCenterPageIndexFrom:(NSInteger)from to:(NSInteger)to; - -// Meant to be subclassed. -- (UIView *)loadPageAtIndex:(NSInteger)pageIndex; - -#pragma mark Accessing Child Views - -- (UIScrollView *)scrollView; -- (NSMutableSet *)visiblePages; // Set of UIView* - -@end - -// Methods that are not meant to be subclassed. -@interface NIPagingScrollView (ProtectedMethods) - -- (void)setCenterPageIndexIvar:(NSInteger)centerPageIndex; -- (void)recyclePageAtIndex:(NSInteger)pageIndex; -- (void)displayPageAtIndex:(NSInteger)pageIndex; -- (CGFloat)pageScrollableDimension; -- (void)layoutVisiblePages; - -@end - -/** - * Called before the page is about to be shown and after its frame has been set. - * - * Meant to be subclassed. By default this method does nothing. - * - * @fn NIPagingScrollView::willDisplayPage: - */ - -/** - * Called immediately after the page is removed from the paging scroll view. - * - * Meant to be subclassed. By default this method does nothing. - * - * @fn NIPagingScrollView::didRecyclePage: - */ - -/** - * Called immediately after the data source has been queried for its number of - * pages. - * - * Meant to be subclassed. By default this method does nothing. - * - * @fn NIPagingScrollView::didReloadNumberOfPages - */ - -/** - * Called when the visible page has changed. - * - * Meant to be subclassed. By default this method does nothing. - * - * @fn NIPagingScrollView::didChangeCenterPageIndexFrom:to: - */ - -/** - * Called when a page needs to be loaded before it is displayed. - * - * By default this method asks the data source for the page at the given index. - * A subclass may chose to modify the page index using a transformation method - * before calling super. - * - * @fn NIPagingScrollView::loadPageAtIndex: - */ - -/** - * Sets the centerPageIndex ivar without side effects. - * - * @fn NIPagingScrollView::setCenterPageIndexIvar: - */ - -/** - * Recycles the page at the given index. - * - * @fn NIPagingScrollView::recyclePageAtIndex: - */ - -/** - * Displays the page at the given index. - * - * @fn NIPagingScrollView::displayPageAtIndex: - */ - -/** - * Returns the page's scrollable dimension. - * - * This is the width of the paging scroll view for horizontal scroll views, or - * the height of the paging scroll view for vertical scroll views. - * - * @fn NIPagingScrollView::pageScrollableDimension - */ - -/** - * Updates the frames of all visible pages based on their page indices. - * - * @fn NIPagingScrollView::layoutVisiblePages - */ diff --git a/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView.h b/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView.h deleted file mode 100644 index a155dab..0000000 --- a/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView.h +++ /dev/null @@ -1,386 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// Copyright 2012 Manu Cornet (vertical layouts) -// -// 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. -// - -#import -#import - -#import "NimbusCore.h" - -/** - * numberOfPages will be this value until reloadData is called. - */ -extern const NSInteger NIPagingScrollViewUnknownNumberOfPages; - -/** - * The default number of pixels on the side of each page. - * - * Value: 10 - */ -extern const CGFloat NIPagingScrollViewDefaultPageMargin; - -typedef enum { - NIPagingScrollViewHorizontal = 0, - NIPagingScrollViewVertical, -} NIPagingScrollViewType; - -@protocol NIPagingScrollViewDataSource; -@protocol NIPagingScrollViewDelegate; -@protocol NIPagingScrollViewPage; -@class NIViewRecycler; - -/** - * The NIPagingScrollView class provides a UITableView-like interface for loading pages via a data - * source. - * - * @ingroup NimbusPagingScrollView - */ -@interface NIPagingScrollView : UIView - -#pragma mark Data Source - -- (void)reloadData; -@property (nonatomic, weak) id dataSource; -@property (nonatomic, weak) id delegate; - -// It is highly recommended that you use this method to manage view recycling. -- (UIView *)dequeueReusablePageWithIdentifier:(NSString *)identifier; - -#pragma mark State - -- (UIView *)centerPageView; -@property (nonatomic) NSInteger centerPageIndex; // Use moveToPageAtIndex:animated: to animate to a given page. - -@property (nonatomic, readonly) NSInteger numberOfPages; - -#pragma mark Configuring Presentation - -// Controls the border between pages. -@property (nonatomic) CGFloat pageMargin; -// Used to make the view smaller than the frame of the paging scroll view, thus showing -// neighboring pages, either horizontally or vertically depending on the configuration -// of the view. -@property (nonatomic) CGFloat pageInset; -@property (nonatomic) NIPagingScrollViewType type; // Default: NIPagingScrollViewHorizontal - -#pragma mark Visible Pages - -- (BOOL)hasNext; -- (BOOL)hasPrevious; -- (void)moveToNextAnimated:(BOOL)animated; -- (void)moveToPreviousAnimated:(BOOL)animated; -- (BOOL)moveToPageAtIndex:(NSInteger)pageIndex animated:(BOOL)animated updateVisiblePagesWhileScrolling:(BOOL)updateVisiblePagesWhileScrolling; - -// Short form for moveToPageAtIndex:pageIndex animated:animated updateVisiblePagesWhileScrolling:NO -- (BOOL)moveToPageAtIndex:(NSInteger)pageIndex animated:(BOOL)animated; - -#pragma mark Rotating the Scroll View - -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration; -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration; - -@end - -/** - * The delegate for NIPagingScrollView. - * - * @ingroup NimbusPagingScrollView - */ -@protocol NIPagingScrollViewDelegate -@optional - -#pragma mark Scrolling and Zooming /** @name [NIPhotoAlbumScrollViewDelegate] Scrolling and Zooming */ - -/** - * The user is scrolling between two photos. - */ -- (void)pagingScrollViewDidScroll:(NIPagingScrollView *)pagingScrollView; - -#pragma mark Changing Pages /** @name [NIPagingScrollViewDelegate] Changing Pages */ - -/** - * The current page will change. - * - * pagingScrollView.centerPageIndex will reflect the old page index, not the new - * page index. - */ -- (void)pagingScrollViewWillChangePages:(NIPagingScrollView *)pagingScrollView; - -/** - * The current page has changed. - * - * pagingScrollView.centerPageIndex will reflect the changed page index. - */ -- (void)pagingScrollViewDidChangePages:(NIPagingScrollView *)pagingScrollView; - -@end - -/** - * The data source for NIPagingScrollView. - * - * @ingroup NimbusPagingScrollView - */ -@protocol NIPagingScrollViewDataSource -@required - -#pragma mark Fetching Required Album Information /** @name [NIPagingScrollViewDataSource] Fetching Required Album Information */ - -/** - * Fetches the total number of pages in the scroll view. - * - * The value returned in this method will be cached by the scroll view until reloadData - * is called again. - */ -- (NSInteger)numberOfPagesInPagingScrollView:(NIPagingScrollView *)pagingScrollView; - -/** - * Fetches a page that will be displayed at the given page index. - * - * You should always try to reuse pages by calling dequeueReusablePageWithIdentifier: on the - * paging scroll view before allocating a new page. - */ -- (UIView *)pagingScrollView:(NIPagingScrollView *)pagingScrollView pageViewForIndex:(NSInteger)pageIndex; - -@end - -/** - * The protocol that a paging scroll view page should implement. - * - * By providing a protocol instead of a UIView base class we allow more flexibility when - * building pages. - * - * @ingroup NimbusPagingScrollView - */ -@protocol NIPagingScrollViewPage -@required - -/** - * The index of this page view. - */ -@property (nonatomic, assign) NSInteger pageIndex; - -@optional - -/** - * Called after the page has gone off-screen. - * - * This method should be used to reset any state information after a page goes off-screen. - * For example, in the Nimbus photo viewer we reset the zoom scale so that if the photo - * was zoomed in it will fit on the screen again when the user flips back and forth between - * two pages. - */ -- (void)pageDidDisappear; - -/** - * Called when the frame of the page is going to change. - * - * Use this method to maintain any state that may be affected by the frame changing. - * The Nimbus photo viewer uses this method to save and restore the zoom and center - * point. This makes the photo always appear to rotate around the center point of the screen - * rather than the center of the photo. - */ -- (void)setFrameAndMaintainState:(CGRect)frame; - -@end - -/** @name Data Source */ - -/** - * The data source for this page album view. - * - * This is the only means by which this paging view acquires any information about the - * album to be displayed. - * - * @fn NIPagingScrollView::dataSource - */ - -/** - * Force the view to reload its data by asking the data source for information. - * - * This must be called at least once after dataSource has been set in order for the view - * to gather any presentable information. - * - * This method is cheap because we only fetch new information about the currently displayed - * pages. If the number of pages shrinks then the current center page index will be decreased - * accordingly. - * - * @fn NIPagingScrollView::reloadData - */ - -/** - * Dequeues a reusable page from the set of recycled pages. - * - * If no pages have been recycled for the given identifier then this will return nil. - * In this case it is your responsibility to create a new page. - * - * @fn NIPagingScrollView::dequeueReusablePageWithIdentifier: - */ - -/** - * The delegate for this paging view. - * - * Any user interactions or state changes are sent to the delegate through this property. - * - * @fn NIPagingScrollView::delegate - */ - -/** @name Configuring Presentation */ - -/** - * The number of pixels on either side of each page. - * - * The space between each page will be 2x this value. - * - * By default this is NIPagingScrollViewDefaultPageMargin. - * - * @fn NIPagingScrollView::pageMargin - */ - -/** - * The type of paging scroll view to display. - * - * This property allows you to configure whether you want a horizontal or vertical paging scroll - * view. You should set this property before you present the scroll view and not modify it after. - * - * By default this is NIPagingScrollViewHorizontal. - * - * @fn NIPagingScrollView::type - */ - -/** @name State */ - -/** - * The current center page view. - * - * If no pages exist then this will return nil. - * - * @fn NIPagingScrollView::centerPageView - */ - -/** - * The current center page index. - * - * This is a zero-based value. If you intend to use this in a label such as "page ## of n" be - * sure to add one to this value. - * - * Setting this value directly will center the new page without any animation. - * - * @fn NIPagingScrollView::centerPageIndex - */ - -/** - * Change the center page index with optional animation. - * - * This method is deprecated in favor of - * @link NIPagingScrollView::moveToPageAtIndex:animated: moveToPageAtIndex:animated:@endlink - * - * @fn NIPagingScrollView::setCenterPageIndex:animated: - */ - -/** - * The total number of pages in this paging view, as gathered from the data source. - * - * This value is cached after reloadData has been called. - * - * Until reloadData is called the first time, numberOfPages will be - * NIPagingScrollViewUnknownNumberOfPages. - * - * @fn NIPagingScrollView::numberOfPages - */ - -/** @name Changing the Visible Page */ - -/** - * Returns YES if there is a next page. - * - * @fn NIPagingScrollView::hasNext - */ - -/** - * Returns YES if there is a previous page. - * - * @fn NIPagingScrollView::hasPrevious - */ - -/** - * Move to the next page if there is one. - * - * @fn NIPagingScrollView::moveToNextAnimated: - */ - -/** - * Move to the previous page if there is one. - * - * @fn NIPagingScrollView::moveToPreviousAnimated: - */ - -/** - * Move to the given page index with optional animation. - * - * @returns NO if a page change animation is already in effect and we couldn't change the page - * again. - * @fn NIPagingScrollView::moveToPageAtIndex:animated: - */ - -/** - * Move to the given page index with optional animation and option to enable page updates while - * scrolling. - * - * NOTE: Passing YES for moveToPageAtIndex:animated:updateVisiblePagesWhileScrolling will cause - * every page from the present page to the destination page to be loaded. This has the potential to - * cause choppy animations. - * - * @param updateVisiblePagesWhileScrolling If YES, will query the data source for any pages - * that become visible while the animation occurs. - * @returns NO if a page change animation is already in effect and we couldn't change the page - * again. - * @fn NIPagingScrollView::moveToPageAtIndex:animated:updateVisiblePagesWhileScrolling: - */ - -/** @name Rotating the Scroll View */ - -/** - * Stores the current state of the scroll view in preparation for rotation. - * - * This must be called in conjunction with willAnimateRotationToInterfaceOrientation:duration: - * in the methods by the same name from the view controller containing this view. - * - * @fn NIPagingScrollView::willRotateToInterfaceOrientation:duration: - */ - -/** - * Updates the frame of the scroll view while maintaining the current visible page's state. - * - * @fn NIPagingScrollView::willAnimateRotationToInterfaceOrientation:duration: - */ - -/** @name Subclassing */ - -/** - * The internal scroll view. - * - * Meant to be used by subclasses only. - * - * @fn NIPagingScrollView::pagingScrollView - */ - -/** - * The set of currently visible pages. - * - * Meant to be used by subclasses only. - * - * @fn NIPagingScrollView::visiblePages - */ diff --git a/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView.m b/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView.m deleted file mode 100644 index 9cfcc79..0000000 --- a/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollView.m +++ /dev/null @@ -1,760 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// Copyright 2012 Manu Cornet (vertical layouts) -// -// 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. -// - -#import "NIPagingScrollView.h" -#import "NIPagingScrollView+Subclassing.h" - -#import "NimbusCore.h" - -#import - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -const NSInteger NIPagingScrollViewUnknownNumberOfPages = -1; -const CGFloat NIPagingScrollViewDefaultPageMargin = 10; -const CGFloat NIPagingScrollViewDefaultPageInset = 0; - -@implementation NIPagingScrollView { - NIViewRecycler* _viewRecycler; - UIScrollView* _scrollView; - - NSMutableSet* _visiblePages; - - // Animating to Pages - NSInteger _animatingToPageIndex; - BOOL _isKillingAnimation; - NSInteger _queuedAnimationPageIndex; - BOOL _shouldUpdateVisiblePagesWhileScrolling; - - // Rotation State - NSInteger _firstVisiblePageIndexBeforeRotation; - CGFloat _percentScrolledIntoFirstVisiblePage; -} - -- (void)commonInit { - // Default state. - self.pageMargin = NIPagingScrollViewDefaultPageMargin; - self.pageInset = NIPagingScrollViewDefaultPageInset; - self.type = NIPagingScrollViewHorizontal; - - // Internal state - _animatingToPageIndex = -1; - _firstVisiblePageIndexBeforeRotation = -1; - _percentScrolledIntoFirstVisiblePage = -1; - _centerPageIndex = -1; - _numberOfPages = NIPagingScrollViewUnknownNumberOfPages; - - _viewRecycler = [[NIViewRecycler alloc] init]; - - // The internal scroll view that powers this paging scroll view. - _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; - _scrollView.pagingEnabled = YES; - _scrollView.scrollsToTop = NO; - - // Allows the scroll view to show adjacent pages... - _scrollView.clipsToBounds = NO; - // ...while still clipping contents to the bounds of the paging scroll view. - self.clipsToBounds = YES; - - _scrollView.autoresizingMask = UIViewAutoresizingFlexibleDimensions; - - _scrollView.delegate = self; - - _scrollView.showsVerticalScrollIndicator = NO; - _scrollView.showsHorizontalScrollIndicator = NO; - - [self addSubview:_scrollView]; -} - -- (id)initWithFrame:(CGRect)frame { - if ((self = [super initWithFrame:frame])) { - [self commonInit]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - if ((self = [super initWithCoder:aDecoder])) { - [self commonInit]; - } - return self; -} - -#pragma mark - Page Layout - -- (void)layoutSubviews { - [super layoutSubviews]; - _scrollView.frame = [self frameForPagingScrollView]; - - // Retain the current position. - CGPoint offset = [self frameForPageAtIndex:_centerPageIndex].origin; - _scrollView.contentOffset = [self contentOffsetFromPageOffset:offset]; - - _scrollView.contentSize = [self contentSizeForPagingScrollView]; - [self layoutVisiblePages]; -} - -// The following three methods are from Apple's ImageScrollView example application and have -// been used here because they are well-documented and concise. - -- (CGRect)frameForPagingScrollView { - CGRect frame = self.bounds; - - if (NIPagingScrollViewHorizontal == self.type) { - // We make the paging scroll view a little bit wider on the side edges so that there - // there is space between the pages when flipping through them. - frame = CGRectInset(frame, self.pageInset - self.pageMargin, 0); - - } else if (NIPagingScrollViewVertical == self.type) { - frame = CGRectInset(frame, 0, self.pageInset - self.pageMargin); - } - - return frame; -} - -- (CGRect)frameForPageAtIndex:(NSInteger)pageIndex { - // We have to use our paging scroll view's bounds, not frame, to calculate the page - // placement. When the device is in landscape orientation, the frame will still be in - // portrait because the pagingScrollView is the root view controller's view, so its - // frame is in window coordinate space, which is never rotated. Its bounds, however, - // will be in landscape because it has a rotation transform applied. - CGRect bounds = _scrollView.bounds; - CGRect pageFrame = bounds; - - if (NIPagingScrollViewHorizontal == self.type) { - pageFrame.origin.x = (bounds.size.width * pageIndex); - // We need to counter the extra spacing added to the paging scroll view in - // frameForPagingScrollView. - pageFrame = CGRectInset(pageFrame, self.pageMargin, 0); - - } else if (NIPagingScrollViewVertical == self.type) { - pageFrame.origin.y = (bounds.size.height * pageIndex); - pageFrame = CGRectInset(pageFrame, 0, self.pageMargin); - } - - return pageFrame; -} - -- (CGSize)contentSizeForPagingScrollView { - // We use the paging scroll view's bounds to calculate the contentSize, for the same reason - // outlined above. - CGRect bounds = _scrollView.bounds; - if (NIPagingScrollViewHorizontal == self.type) { - return CGSizeMake(bounds.size.width * self.numberOfPages, bounds.size.height); - - } else if (NIPagingScrollViewVertical == self.type) { - return CGSizeMake(bounds.size.width, bounds.size.height * self.numberOfPages); - } - - return CGSizeZero; -} - -- (CGPoint)contentOffsetFromPageOffset:(CGPoint)offset { - if (NIPagingScrollViewHorizontal == self.type) { - offset.x -= self.pageMargin; - - } else if (NIPagingScrollViewVertical == self.type) { - offset.y -= self.pageMargin; - } - - return offset; -} - -- (CGFloat)pageScrollableDimension { - if (NIPagingScrollViewHorizontal == self.type) { - return _scrollView.bounds.size.width; - - } else if (NIPagingScrollViewVertical == self.type) { - return _scrollView.bounds.size.height; - } - - return 0; -} - -- (CGPoint)contentOffsetFromOffset:(CGFloat)offset { - if (NIPagingScrollViewHorizontal == self.type) { - return CGPointMake(offset, 0); - - } else if (NIPagingScrollViewVertical == self.type) { - return CGPointMake(0, offset); - } - - return CGPointMake(0, 0); -} - -- (CGFloat)scrolledPageOffset { - if (NIPagingScrollViewHorizontal == self.type) { - return _scrollView.contentOffset.x; - - } else if (NIPagingScrollViewVertical == self.type) { - return _scrollView.contentOffset.y; - } - - return 0; -} - -#pragma mark - Visible Page Management - -- (BOOL)isDisplayingPageForIndex:(NSInteger)pageIndex { - BOOL foundPage = NO; - - // There will never be more than a handful (3 without insets) of visible pages in this array, so this lookup is - // effectively O(C) constant time. - for (UIView * page in _visiblePages) { - if (page.pageIndex == pageIndex) { - foundPage = YES; - break; - } - } - - return foundPage; -} - -- (NSInteger)currentVisiblePageIndex { - CGPoint contentOffset = _scrollView.contentOffset; - CGSize boundsSize = _scrollView.bounds.size; - - if (NIPagingScrollViewHorizontal == self.type) { - // Whatever image is currently displayed in the center of the screen is the currently - // visible image. - return NIBoundi((NSInteger)(NICGFloatFloor((contentOffset.x + boundsSize.width / 2) / boundsSize.width) - + 0.5f), - 0, self.numberOfPages - 1); - - } else if (NIPagingScrollViewVertical == self.type) { - return NIBoundi((NSInteger)(NICGFloatFloor((contentOffset.y + boundsSize.height / 2) / boundsSize.height) - + 0.5f), - 0, self.numberOfPages - 1); - } - - return 0; -} - -- (NSRange)rangeOfVisiblePages { - if (0 >= self.numberOfPages) { - return NSMakeRange(0, 0); - } - - NSInteger visibleRange = 1; - if (_pageInset != 0) { - CGSize boundsSize = _scrollView.bounds.size; - CGSize frameSize = self.frame.size; - visibleRange = (NSInteger)ceil(frameSize.width / (boundsSize.width + _pageMargin)); - } - - NSInteger currentVisiblePageIndex = [self currentVisiblePageIndex]; - - NSInteger firstVisiblePageIndex = NIBoundi(currentVisiblePageIndex - visibleRange, 0, self.numberOfPages - 1); - NSInteger lastVisiblePageIndex = NIBoundi(currentVisiblePageIndex + visibleRange, 0, self.numberOfPages - 1); - - return NSMakeRange(firstVisiblePageIndex, lastVisiblePageIndex - firstVisiblePageIndex + 1); -} - -- (void)willDisplayPage:(UIView *)pageView atIndex:(NSInteger)pageIndex { - pageView.pageIndex = pageIndex; - pageView.frame = [self frameForPageAtIndex:pageIndex]; - - [self willDisplayPage:pageView]; -} - -- (void)resetPage:(id)page { - if ([page respondsToSelector:@selector(pageDidDisappear)]) { - [page pageDidDisappear]; - } -} - -- (void)resetSurroundingPages { - for (id page in _visiblePages) { - if (page.pageIndex != self.centerPageIndex) { - [self resetPage:page]; - } - } -} - -- (UIView *)dequeueReusablePageWithIdentifier:(NSString *)identifier { - NIDASSERT(nil != identifier); - if (nil == identifier) { - return nil; - } - - return (UIView *)[_viewRecycler dequeueReusableViewWithIdentifier:identifier]; -} - -- (UIView *)loadPageAtIndex:(NSInteger)pageIndex { - UIView* page = [self.dataSource pagingScrollView:self pageViewForIndex:pageIndex]; - - NIDASSERT([page isKindOfClass:[UIView class]]); - NIDASSERT([page conformsToProtocol:@protocol(NIPagingScrollViewPage)]); - - if (nil == page || ![page isKindOfClass:[UIView class]] - || ![page conformsToProtocol:@protocol(NIPagingScrollViewPage)]) { - // Bail out! This page is malformed. - return nil; - } - - return page; -} - -- (void)displayPageAtIndex:(NSInteger)pageIndex { - UIView* page = [self loadPageAtIndex:pageIndex]; - if (nil == page) { - return; - } - - // This will only be called once, before the page is shown. - [self willDisplayPage:page atIndex:pageIndex]; - - [_scrollView addSubview:page]; - [_visiblePages addObject:page]; -} - -- (void)recyclePageAtIndex:(NSInteger)pageIndex { - for (UIView* page in [_visiblePages copy]) { - if (page.pageIndex == pageIndex) { - [_viewRecycler recycleView:page]; - [page removeFromSuperview]; - - [self didRecyclePage:page]; - - [_visiblePages removeObject:page]; - } - } -} - -- (void)preloadOffscreenPages { - NSRange rangeOfVisiblePages = [self rangeOfVisiblePages]; - for (NSUInteger pageIndex = rangeOfVisiblePages.location; - pageIndex < NSMaxRange(rangeOfVisiblePages); ++pageIndex) { - if (![self isDisplayingPageForIndex:pageIndex]) { - [self displayPageAtIndex:pageIndex]; - } - } -} - -- (void)updateVisiblePagesShouldNotifyDelegate:(BOOL)shouldNotifyDelegate { - // Before updating _centerPageIndex, notify delegate - if (shouldNotifyDelegate && (self.numberOfPages > 0) && - ([self currentVisiblePageIndex] != self.centerPageIndex) && - [self.delegate respondsToSelector:@selector(pagingScrollViewWillChangePages:)]) { - [self.delegate pagingScrollViewWillChangePages:self]; - } - - NSRange rangeOfVisiblePages = [self rangeOfVisiblePages]; - // Recycle no-longer-visible pages. We copy _visiblePages because we may modify it while we're - // iterating over it. - for (UIView* page in [_visiblePages copy]) { - if (!NSLocationInRange(page.pageIndex, rangeOfVisiblePages)) { - [_viewRecycler recycleView:page]; - [page removeFromSuperview]; - - [self didRecyclePage:page]; - - [_visiblePages removeObject:page]; - } - } - - NSInteger oldCenterPageIndex = self.centerPageIndex; - - if (self.numberOfPages > 0) { - _centerPageIndex = [self currentVisiblePageIndex]; - - [self didChangeCenterPageIndexFrom:oldCenterPageIndex to:_centerPageIndex]; - - if (_pageInset != 0) { - // Load all visible insetted pages immediately. - [self preloadOffscreenPages]; - } else { - // Prioritize displaying the currently visible page. - if (![self isDisplayingPageForIndex:_centerPageIndex]) { - [self displayPageAtIndex:_centerPageIndex]; - } - - // Add missing pages after displaying the current page. - [self performSelector:@selector(preloadOffscreenPages) - withObject:nil - afterDelay:0]; - } - } else { - _centerPageIndex = -1; - } - - if (shouldNotifyDelegate && oldCenterPageIndex != _centerPageIndex - && [self.delegate respondsToSelector:@selector(pagingScrollViewDidChangePages:)]) { - [self.delegate pagingScrollViewDidChangePages:self]; - } -} - -- (void)layoutVisiblePages { - for (UIView* page in _visiblePages) { - CGRect pageFrame = [self frameForPageAtIndex:page.pageIndex]; - if ([page respondsToSelector:@selector(setFrameAndMaintainState:)]) { - [page setFrameAndMaintainState:pageFrame]; - - } else { - [page setFrame:pageFrame]; - } - } -} - -#pragma mark - UIView - -- (void)setFrame:(CGRect)frame { - // We have to modify this method because it eventually leads to changing the content offset - // programmatically. When this happens we end up getting a scrollViewDidScroll: message - // during which we do not want to modify the visible pages because this is handled elsewhere. - [super setFrame:frame]; - - _scrollView.contentSize = [self contentSizeForPagingScrollView]; - [self layoutVisiblePages]; -} - -- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { - UIView *view = [super hitTest:point withEvent:event]; - // We must forward hits for the scrollView or else the smaller frame when - // it is inset will prevent touches outside the scrollView bounds. - if (view == self) { - return _scrollView; - } - return view; -} - -#pragma mark - UIScrollViewDelegate - -- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { - [self updateVisiblePagesShouldNotifyDelegate:YES]; - _isKillingAnimation = NO; - - if ([self.delegate respondsToSelector:_cmd]) { - [self.delegate scrollViewWillBeginDragging:scrollView]; - } -} - -- (void)scrollViewDidScroll:(UIScrollView *)scrollView { - if ([scrollView isTracking] && [scrollView isDragging]) { - if ([self.delegate respondsToSelector:@selector(pagingScrollViewDidScroll:)]) { - [self.delegate pagingScrollViewDidScroll:self]; - } - } - if (_shouldUpdateVisiblePagesWhileScrolling - && ![scrollView isTracking] && ![scrollView isDragging]) { - [self updateVisiblePagesShouldNotifyDelegate:YES]; - } - - if ([self.delegate respondsToSelector:_cmd]) { - [self.delegate scrollViewDidScroll:scrollView]; - } - - if (_isKillingAnimation) { - // The content size is calculated based on the number of pages and the scroll view frame. - CGPoint offset = [self frameForPageAtIndex:_centerPageIndex].origin; - offset = [self contentOffsetFromPageOffset:offset]; - _scrollView.contentOffset = offset; - } -} - -- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { - _isKillingAnimation = NO; - - if (!decelerate) { - [self updateVisiblePagesShouldNotifyDelegate:YES]; - [self resetSurroundingPages]; - } - - if ([self.delegate respondsToSelector:_cmd]) { - [self.delegate scrollViewDidEndDragging:scrollView willDecelerate:decelerate]; - } -} - -- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { - [self updateVisiblePagesShouldNotifyDelegate:YES]; - [self resetSurroundingPages]; - - if ([self.delegate respondsToSelector:_cmd]) { - [self.delegate scrollViewDidEndDecelerating:scrollView]; - } -} - -- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { - if (_animatingToPageIndex >= 0) { - [self didAnimateToPage:_animatingToPageIndex]; - - if ([self.delegate respondsToSelector:_cmd]) { - [self.delegate scrollViewDidEndScrollingAnimation:scrollView]; - } - } -} - -#pragma mark - Forward UIScrollViewDelegate Methods - - -- (BOOL)shouldForwardSelectorToDelegate:(SEL)aSelector { - struct objc_method_description description; - // Only forward the selector if it's part of the UIScrollViewDelegate protocol. - description = protocol_getMethodDescription(@protocol(UIScrollViewDelegate), - aSelector, - NO, - YES); - - BOOL isSelectorInScrollViewDelegate = (description.name != NULL && description.types != NULL); - return (isSelectorInScrollViewDelegate - && [self.delegate respondsToSelector:aSelector]); -} - -- (BOOL)respondsToSelector:(SEL)aSelector { - if ([super respondsToSelector:aSelector] == YES) { - return YES; - - } else { - return [self shouldForwardSelectorToDelegate:aSelector]; - } -} - -- (id)forwardingTargetForSelector:(SEL)aSelector { - if ([self shouldForwardSelectorToDelegate:aSelector]) { - return self.delegate; - - } else { - return nil; - } -} - -#pragma mark - Subclassing - - -- (void)willDisplayPage:(UIView *)pageView { - // No-op. -} - -- (void)didRecyclePage:(UIView *)pageView { - // No-op -} - -- (void)didReloadNumberOfPages { - // No-op -} - -- (void)didChangeCenterPageIndexFrom:(NSInteger)from to:(NSInteger)to { - // No-op -} - -- (void)setCenterPageIndexIvar:(NSInteger)centerPageIndex { - _centerPageIndex = centerPageIndex; -} - -#pragma mark - Public - - -- (void)reloadData { - _animatingToPageIndex = -1; - NIDASSERT(nil != _dataSource); - - // Remove any visible pages from the view before we release the sets. - for (UIView* page in _visiblePages) { - [_viewRecycler recycleView:page]; - [(UIView *)page removeFromSuperview]; - - [self didRecyclePage:page]; - } - - _visiblePages = nil; - - // If there is no data source then we can't do anything particularly interesting. - if (nil == _dataSource) { - _scrollView.contentSize = self.bounds.size; - _scrollView.contentOffset = CGPointZero; - - // May as well just get rid of all the views then. - [_viewRecycler removeAllViews]; - - return; - } - - _visiblePages = [[NSMutableSet alloc] init]; - - // Cache the number of pages. - _numberOfPages = [_dataSource numberOfPagesInPagingScrollView:self]; - _scrollView.frame = [self frameForPagingScrollView]; - _scrollView.contentSize = [self contentSizeForPagingScrollView]; - - [self didReloadNumberOfPages]; - - NSInteger oldCenterPageIndex = _centerPageIndex; - if (oldCenterPageIndex >= 0) { - _centerPageIndex = NIBoundi(_centerPageIndex, 0, self.numberOfPages - 1); - - if (![_scrollView isTracking] && ![_scrollView isDragging]) { - // The content size is calculated based on the number of pages and the scroll view frame. - CGPoint offset = [self frameForPageAtIndex:_centerPageIndex].origin; - offset = [self contentOffsetFromPageOffset:offset]; - _scrollView.contentOffset = offset; - - _isKillingAnimation = YES; - } - } - - // Begin requesting the page information from the data source. - [self updateVisiblePagesShouldNotifyDelegate:NO]; -} - -- (void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation - duration: (NSTimeInterval)duration { - // Here, our pagingScrollView bounds have not yet been updated for the new interface - // orientation. This is a good place to calculate the content offset that we will - // need in the new orientation. - CGFloat offset = [self scrolledPageOffset]; - CGFloat pageScrollableDimension = [self pageScrollableDimension]; - - if (offset >= 0) { - _firstVisiblePageIndexBeforeRotation = (NSInteger)NICGFloatFloor(offset / pageScrollableDimension); - _percentScrolledIntoFirstVisiblePage = ((offset - - (_firstVisiblePageIndexBeforeRotation * pageScrollableDimension)) - / pageScrollableDimension); - - } else { - _firstVisiblePageIndexBeforeRotation = 0; - _percentScrolledIntoFirstVisiblePage = offset / pageScrollableDimension; - } -} - -- (void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation - duration: (NSTimeInterval)duration { - // Recalculate contentSize based on current orientation. - _scrollView.contentSize = [self contentSizeForPagingScrollView]; - - [self layoutVisiblePages]; - - // Adjust contentOffset to preserve page location based on values collected prior to location. - CGFloat pageScrollableDimension = [self pageScrollableDimension]; - CGFloat newOffset = ((_firstVisiblePageIndexBeforeRotation * pageScrollableDimension) - + (_percentScrolledIntoFirstVisiblePage * pageScrollableDimension)); - _scrollView.contentOffset = [self contentOffsetFromOffset:newOffset]; -} - -- (BOOL)hasNext { - return (self.centerPageIndex < self.numberOfPages - 1); -} - -- (BOOL)hasPrevious { - return self.centerPageIndex > 0; -} - -- (void)didAnimateToPage:(NSInteger)pageIndex { - _shouldUpdateVisiblePagesWhileScrolling = NO; - _animatingToPageIndex = -1; - if (_queuedAnimationPageIndex >= 0 && _queuedAnimationPageIndex != pageIndex) { - [self moveToPageAtIndex:_queuedAnimationPageIndex animated:YES]; - return; - } - - // Reset the content offset once the animation completes, just to be sure that the - // viewer sits on a page bounds even if we rotate the device while animating. - CGPoint offset = [self frameForPageAtIndex:pageIndex].origin; - offset = [self contentOffsetFromPageOffset:offset]; - - _scrollView.contentOffset = offset; - - [self updateVisiblePagesShouldNotifyDelegate:YES]; -} - -- (BOOL)moveToPageAtIndex:(NSInteger)pageIndex animated:(BOOL)animated { - return [self moveToPageAtIndex:pageIndex animated:animated updateVisiblePagesWhileScrolling:NO]; -} - -- (BOOL)moveToPageAtIndex:(NSInteger)pageIndex animated:(BOOL)animated updateVisiblePagesWhileScrolling:(BOOL)updateVisiblePagesWhileScrolling { - if (_animatingToPageIndex >= 0) { - // Don't allow re-entry for sliding animations. - _queuedAnimationPageIndex = pageIndex; - return NO; - } - _shouldUpdateVisiblePagesWhileScrolling = updateVisiblePagesWhileScrolling; - _isKillingAnimation = NO; - _queuedAnimationPageIndex = -1; - - CGPoint offset = [self frameForPageAtIndex:pageIndex].origin; - offset = [self contentOffsetFromPageOffset:offset]; - - // The paging scroll view won't actually animate if the offsets are identical. - animated = animated && !CGPointEqualToPoint(offset, _scrollView.contentOffset); - - if (animated) { - _animatingToPageIndex = pageIndex; - } - [_scrollView setContentOffset:offset animated:animated]; - if (!animated) { - [self resetSurroundingPages]; - [self didAnimateToPage:pageIndex]; - } - return YES; -} - -- (void)moveToNextAnimated:(BOOL)animated { - if ([self hasNext]) { - NSInteger pageIndex = self.centerPageIndex + 1; - - [self moveToPageAtIndex:pageIndex animated:animated]; - } -} - -- (void)moveToPreviousAnimated:(BOOL)animated { - if ([self hasPrevious]) { - NSInteger pageIndex = self.centerPageIndex - 1; - - [self moveToPageAtIndex:pageIndex animated:animated]; - } -} - -- (UIView *)centerPageView { - for (UIView* page in _visiblePages) { - if (page.pageIndex == self.centerPageIndex) { - return page; - } - } - return nil; -} - -- (void)setCenterPageIndex:(NSInteger)centerPageIndex { - [self moveToPageAtIndex:centerPageIndex animated:NO]; -} - -- (void)setPageMargin:(CGFloat)pageMargin { - _pageMargin = pageMargin; - [self setNeedsLayout]; -} - -- (void)setPageInset:(CGFloat)pageInset { - _pageInset = pageInset; - [self setNeedsLayout]; -} - -- (void)setType:(NIPagingScrollViewType)type { - if (_type != type) { - _type = type; - _scrollView.scrollsToTop = (type == NIPagingScrollViewVertical); - } -} - -- (UIScrollView *)scrollView { - return _scrollView; -} - -- (NSMutableSet *)visiblePages { - return _visiblePages; -} - -@end diff --git a/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollViewPage.h b/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollViewPage.h deleted file mode 100644 index fca4f8d..0000000 --- a/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollViewPage.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import - -#import "NIPagingScrollView.h" - -/** - * A skeleton implementation of a page view. - * - * This view simply implements the required properties of NIPagingScrollViewPage. - * - * @ingroup NimbusPagingScrollView - */ -@interface NIPagingScrollViewPage : NIRecyclableView -@property (nonatomic) NSInteger pageIndex; -@end - -/** - * The page index. - * - * @fn NIPagingScrollViewPage::pageIndex - */ diff --git a/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollViewPage.m b/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollViewPage.m deleted file mode 100644 index 89c94cb..0000000 --- a/Pods/Nimbus/src/pagingscrollview/src/NIPagingScrollViewPage.m +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIPagingScrollViewPage.h" - -#import "NimbusCore.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -@implementation NIPagingScrollViewPage -@end diff --git a/Pods/Nimbus/src/pagingscrollview/src/NimbusPagingScrollView.h b/Pods/Nimbus/src/pagingscrollview/src/NimbusPagingScrollView.h deleted file mode 100644 index 5b0c0b1..0000000 --- a/Pods/Nimbus/src/pagingscrollview/src/NimbusPagingScrollView.h +++ /dev/null @@ -1,53 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import - -/** - * @defgroup NimbusPagingScrollView Nimbus Paging Scroll View - * @{ - * - *
- * - * A paging scroll view is a UIScrollView that scrolls horizontally and shows a series of - * pages that are efficiently recycled. - * - * The Nimbus paging scroll view is powered by a datasource that allows you to separate the - * data from the view. This makes it easy to efficiently recycle pages and only create as many - * pages of content as may be visible at any given point in time. Nimbus' implementation also - * provides helpful features such as keeping the center page centered when the device changes - * orientation. - * - * Paging scroll views are commonly used in many iOS applications. For example, Nimbus' Photos - * feature uses a paging scroll view to power its NIPhotoAlbumScrollView. - * - *

Building a Component with NIPagingScrollView

- * - * NIPagingScrollView works much like a UITableView in that you must implement a data source - * and optionally a delegate. The data source fetches information about the contents of the - * paging scroll view, such as the total number of pages and the view for a given page when it - * is required. The views that you return for pages must conform to the NIPagingScrollViewPage - * protocol. This is similar to UITableViewCell, but rather than subclass a view you can simply - * implement a protocol. If you would prefer not to implement the protocol, you can subclass - * NIPageView which implements the required methods of NIPagingScrollViewPage. - */ - -/**@}*/ - -#import "NIPagingScrollView.h" -#import "NIPagingScrollViewPage.h" - -#import "NimbusCore.h" diff --git a/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollView.h b/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollView.h deleted file mode 100644 index 3b9b396..0000000 --- a/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollView.h +++ /dev/null @@ -1,170 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIPhotoScrollViewDelegate.h" -#import "NIPhotoAlbumScrollViewDataSource.h" -#import "NIPhotoAlbumScrollViewDelegate.h" - -#import "NimbusPagingScrollView.h" - -#import -#import - -/** - * A paged scroll view that shows a collection of photos. - * - * @ingroup NimbusPhotos - * - * This view provides a light-weight implementation of a photo viewer, complete with - * pinch-to-zoom and swiping to change photos. It is designed to perform well with - * large sets of photos and large images that are loaded from either the network or - * disk. - * - * It is intended for this view to be used in conjunction with a view controller that - * implements the data source protocol and presents any required chrome. - * - * @see NIToolbarPhotoViewController - */ -@interface NIPhotoAlbumScrollView : NIPagingScrollView - -#pragma mark Data Source - -// For use in your pagingScrollView:pageForIndex: data source implementation. -- (UIView *)pagingScrollView:(NIPagingScrollView *)pagingScrollView pageViewForIndex:(NSInteger)pageIndex; - -@property (nonatomic, weak) id dataSource; -@property (nonatomic, weak) id delegate; - -#pragma mark Configuring Functionality - -@property (nonatomic, assign, getter=isZoomingEnabled) BOOL zoomingIsEnabled; -@property (nonatomic, assign, getter=isZoomingAboveOriginalSizeEnabled) BOOL zoomingAboveOriginalSizeIsEnabled; -@property (nonatomic, strong) UIColor* photoViewBackgroundColor; - -#pragma mark Configuring Presentation - -@property (nonatomic, strong) UIImage* loadingImage; - -#pragma mark Notifying the View of Loaded Photos - -- (void)didLoadPhoto: (UIImage *)image - atIndex: (NSInteger)photoIndex - photoSize: (NIPhotoScrollViewPhotoSize)photoSize; - -@end - - -/** @name Data Source */ - -/** - * The data source for this photo album view. - * - * This is the only means by which this photo album view acquires any information about the - * album to be displayed. - * - * @fn NIPhotoAlbumScrollView::dataSource - */ - -/** - * Use this method in your implementation of NIPhotoAlbumScrollViewDataSource's - * pagingScrollView:pageForIndex:. - * - * Example: - * -@code -- (id)pagingScrollView:(NIPagingScrollView *)pagingScrollView pageForIndex:(NSInteger)pageIndex { - return [self.photoAlbumView pagingScrollView:pagingScrollView pageForIndex:pageIndex]; -} -@endcode - * - * Automatically uses the paging scroll view's page recycling methods and creates - * NIPhotoScrollViews as needed. - * - * @fn NIPhotoAlbumScrollView::pagingScrollView:pageForIndex: - */ - -/** - * The delegate for this photo album view. - * - * Any user interactions or state changes are sent to the delegate through this property. - * - * @fn NIPhotoAlbumScrollView::delegate - */ - - -/** @name Configuring Functionality */ - -/** - * Whether zooming is enabled or not. - * - * Regardless of whether this is enabled, only original-sized images will be zoomable. - * This is because we often don't know how large the final image is so we can't - * calculate min and max zoom amounts correctly. - * - * By default this is YES. - * - * @fn NIPhotoAlbumScrollView::zoomingIsEnabled - */ - -/** - * Whether small photos can be zoomed at least until they fit the screen. - * - * @see NIPhotoScrollView::zoomingAboveOriginalSizeIsEnabled - * - * By default this is YES. - * - * @fn NIPhotoAlbumScrollView::zoomingAboveOriginalSizeIsEnabled - */ - -/** - * The background color of each photo's view. - * - * By default this is [UIColor blackColor]. - * - * @fn NIPhotoAlbumScrollView::photoViewBackgroundColor - */ - - -/** @name Configuring Presentation */ - -/** - * An image that is displayed while the photo is loading. - * - * This photo will be presented if no image is returned in the data source's implementation - * of photoAlbumScrollView:photoAtIndex:photoSize:isLoading:. - * - * Zooming is disabled when showing a loading image, regardless of the state of zoomingIsEnabled. - * - * By default this is nil. - * - * @fn NIPhotoAlbumScrollView::loadingImage - */ - - -/** @name Notifying the View of Loaded Photos */ - -/** - * Notify the scroll view that a photo has been loaded at a given index. - * - * You should notify the completed loading of thumbnails as well. Calling this method - * is fairly lightweight and will only update the images of the visible pages. Err on the - * side of calling this method too much rather than too little. - * - * The photo at the given index will only be replaced with the given image if photoSize - * is of a higher quality than the currently-displayed photo's size. - * - * @fn NIPhotoAlbumScrollView::didLoadPhoto:atIndex:photoSize: - */ diff --git a/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollView.m b/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollView.m deleted file mode 100644 index 79709d4..0000000 --- a/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollView.m +++ /dev/null @@ -1,221 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIPhotoAlbumScrollView.h" - -#import "NIPagingScrollView+Subclassing.h" -#import "NIPhotoScrollView.h" -#import "NIPhotoAlbumScrollViewDataSource.h" -#import "NimbusCore.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -@implementation NIPhotoAlbumScrollView { - // Configurable Properties - UIImage* _loadingImage; - BOOL _zoomingIsEnabled; - BOOL _zoomingAboveOriginalSizeIsEnabled; -} - -- (id)initWithFrame:(CGRect)frame { - if ((self = [super initWithFrame:frame])) { - // Default state. - self.zoomingIsEnabled = YES; - self.zoomingAboveOriginalSizeIsEnabled = YES; - } - return self; -} - -- (void)setBackgroundColor:(UIColor *)backgroundColor { - [super setBackgroundColor:backgroundColor]; - - self.scrollView.backgroundColor = backgroundColor; -} - -- (void)notifyDelegatePhotoDidLoadAtIndex:(NSInteger)photoIndex { - if (photoIndex == (self.centerPageIndex + 1) - && [self.delegate respondsToSelector:@selector(photoAlbumScrollViewDidLoadNextPhoto:)]) { - [self.delegate photoAlbumScrollViewDidLoadNextPhoto:self]; - - } else if (photoIndex == (self.centerPageIndex - 1) - && [self.delegate respondsToSelector:@selector(photoAlbumScrollViewDidLoadPreviousPhoto:)]) { - [self.delegate photoAlbumScrollViewDidLoadPreviousPhoto:self]; - } -} - -#pragma mark - Visible Page Management - - -- (void)willDisplayPage:(NIPhotoScrollView *)page { - // When we ask the data source for the image we expect the following to happen: - // 1) If the data source has any image at this index, it should return it and set the - // photoSize accordingly. - // 2) If the returned photo is not the highest quality available, the data source should - // start loading the high quality photo and set isLoading to YES. - // 3) If no photo was available, then the data source should start loading the photo - // at its highest available quality and nil should be returned. The loadingImage property - // will be displayed until the image is loaded. isLoading should be set to YES. - NIPhotoScrollViewPhotoSize photoSize = NIPhotoScrollViewPhotoSizeUnknown; - BOOL isLoading = NO; - CGSize originalPhotoDimensions = CGSizeZero; - UIImage* image = [self.dataSource photoAlbumScrollView: self - photoAtIndex: page.pageIndex - photoSize: &photoSize - isLoading: &isLoading - originalPhotoDimensions: &originalPhotoDimensions]; - - page.photoDimensions = originalPhotoDimensions; - // Only mark the view as loading if the center image is loading. - page.loading = (page.pageIndex == self.centerPageIndex) && isLoading; - - if (nil == image) { - page.zoomingIsEnabled = NO; - [page setImage:self.loadingImage photoSize:NIPhotoScrollViewPhotoSizeUnknown]; - - } else { - BOOL updateImage = photoSize > page.photoSize; - if (updateImage) { - [page setImage:image photoSize:photoSize]; - } - - // Configure this after the image is set otherwise if the page's image isn't there - // e.g. (after prepareForReuse), zooming will always be disabled - page.zoomingIsEnabled = ([self isZoomingEnabled] - && (NIPhotoScrollViewPhotoSizeOriginal == photoSize)); - - if (updateImage && NIPhotoScrollViewPhotoSizeOriginal == photoSize) { - [self notifyDelegatePhotoDidLoadAtIndex:page.pageIndex]; - } - } -} - -- (void)didRecyclePage:(UIView *)page { - // Give the data source the opportunity to kill any asynchronous operations for this - // now-recycled page. - if ([self.dataSource respondsToSelector: - @selector(photoAlbumScrollView:stopLoadingPhotoAtIndex:)]) { - [self.dataSource photoAlbumScrollView: self - stopLoadingPhotoAtIndex: page.pageIndex]; - } -} - -#pragma mark - NIPhotoScrollViewDelegate - - -- (void)photoScrollViewDidDoubleTapToZoom: (NIPhotoScrollView *)photoScrollView - didZoomIn: (BOOL)didZoomIn { - if ([self.delegate respondsToSelector:@selector(photoAlbumScrollView:didZoomIn:)]) { - [self.delegate photoAlbumScrollView:self didZoomIn:didZoomIn]; - } -} - -#pragma mark - Public - - -- (UIView *)pagingScrollView:(NIPagingScrollView *)pagingScrollView - pageViewForIndex:(NSInteger)pageIndex { - UIView* pageView = nil; - NSString* reuseIdentifier = @"photo"; - pageView = [pagingScrollView dequeueReusablePageWithIdentifier:reuseIdentifier]; - if (nil == pageView) { - pageView = [[NIPhotoScrollView alloc] init]; - pageView.reuseIdentifier = reuseIdentifier; - pageView.backgroundColor = self.photoViewBackgroundColor; - } - - NIPhotoScrollView* photoScrollView = (NIPhotoScrollView *)pageView; - photoScrollView.photoScrollViewDelegate = self; - photoScrollView.zoomingAboveOriginalSizeIsEnabled = [self isZoomingAboveOriginalSizeEnabled]; - - return pageView; -} - -- (void)didLoadPhoto: (UIImage *)image - atIndex: (NSInteger)pageIndex - photoSize: (NIPhotoScrollViewPhotoSize)photoSize { - // This modifies the UI and therefor MUST be executed on the main thread. - NIDASSERT([NSThread isMainThread]); - - for (NIPhotoScrollView* page in self.visiblePages) { - if (page.pageIndex == pageIndex) { - - // Only replace the photo if it's of a higher quality than one we're already showing. - if (photoSize > page.photoSize) { - page.loading = NO; - [page setImage:image photoSize:photoSize]; - - page.zoomingIsEnabled = ([self isZoomingEnabled] - && (NIPhotoScrollViewPhotoSizeOriginal == photoSize)); - - // Notify the delegate that the photo has been loaded. - if (NIPhotoScrollViewPhotoSizeOriginal == photoSize) { - [self notifyDelegatePhotoDidLoadAtIndex:pageIndex]; - } - } - break; - } - } -} - -- (void)setZoomingAboveOriginalSizeIsEnabled:(BOOL)enabled { - _zoomingAboveOriginalSizeIsEnabled = enabled; - - for (NIPhotoScrollView* page in self.visiblePages) { - page.zoomingAboveOriginalSizeIsEnabled = enabled; - } -} - -- (void)setPhotoViewBackgroundColor:(UIColor *)photoViewBackgroundColor { - if (_photoViewBackgroundColor != photoViewBackgroundColor) { - _photoViewBackgroundColor = photoViewBackgroundColor; - - for (UIView* page in self.visiblePages) { - page.backgroundColor = photoViewBackgroundColor; - } - } -} - -- (BOOL)hasNext { - return (self.centerPageIndex < self.numberOfPages - 1); -} - -- (BOOL)hasPrevious { - return self.centerPageIndex > 0; -} - -- (id)dataSource { - NIDASSERT([[super dataSource] conformsToProtocol:@protocol(NIPhotoAlbumScrollViewDataSource)]); - return (id)[super dataSource]; -} - -- (void)setDataSource:(id)dataSource { - [super setDataSource:(id)dataSource]; -} - -- (id)delegate { - id superDelegate = [super delegate]; - NIDASSERT(nil == superDelegate - || [superDelegate conformsToProtocol:@protocol(NIPhotoAlbumScrollViewDelegate)]); - return (id)superDelegate; -} - -- (void)setDelegate:(id)delegate { - [super setDelegate:(id)delegate]; -} - -@end diff --git a/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollViewDataSource.h b/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollViewDataSource.h deleted file mode 100644 index 8287a4a..0000000 --- a/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollViewDataSource.h +++ /dev/null @@ -1,93 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIPhotoScrollViewPhotoSize.h" - -#import "NimbusPagingScrollView.h" - -#import - -@class NIPhotoAlbumScrollView; - -/** - * The photo album scroll data source. - * - * @ingroup NimbusPhotos - * - * This data source emphasizes speed and memory efficiency by requesting images only when - * they're needed and encouraging immediate responses from the data source implementation. - * - * @see NIPhotoAlbumScrollView - */ -@protocol NIPhotoAlbumScrollViewDataSource - -@required - -#pragma mark Fetching Required Album Information /** @name [NIPhotoAlbumScrollViewDataSource] Fetching Required Album Information */ - -/** - * Fetches the highest-quality image available for the photo at the given index. - * - * Your goal should be to make this implementation return as fast as possible. Avoid - * hitting the disk or blocking on a network request. Aim to load images asynchronously. - * - * If you already have the highest-quality image in memory (like in an NIImageMemoryCache), - * then you can simply return the image and set photoSize to be - * NIPhotoScrollViewPhotoSizeOriginal. - * - * If the highest-quality image is not available when this method is called then you should - * spin off an asynchronous operation to load the image and set isLoading to YES. - * - * If you have a thumbnail in memory but not the full-size image yet, then you should return - * the thumbnail, set isLoading to YES, and set photoSize to NIPhotoScrollViewPhotoSizeThumbnail. - * - * Once the high-quality image finishes loading, call didLoadPhoto:atIndex:photoSize: with - * the image. - * - * This method will be called to prefetch the next and previous photos in the scroll view. - * The currently displayed photo will always be requested first. - * - * @attention The photo scroll view does not hold onto the UIImages for very long at all. - * It is up to the controller to decide on an adequate caching policy to ensure - * that images are kept in memory through the life of the photo album. - * In your implementation of the data source you should prioritize thumbnails - * being kept in memory over full-size images. When a memory warning is received, - * the original photos should be relinquished from memory first. - */ -- (UIImage *)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView - photoAtIndex: (NSInteger)photoIndex - photoSize: (NIPhotoScrollViewPhotoSize *)photoSize - isLoading: (BOOL *)isLoading - originalPhotoDimensions: (CGSize *)originalPhotoDimensions; - -@optional - -#pragma mark Optimizing Data Retrieval /** @name [NIPhotoAlbumScrollViewDataSource] Optimizing Data Retrieval */ - -/** - * Called when you should cancel any asynchronous loading requests for the given photo. - * - * When a photo is not immediately visible this method is called to allow the data - * source to minimize the number of active asynchronous operations in place. - * - * This method is optional, though recommended because it focuses the device's processing - * power on the most immediately accessible photos. - */ -- (void)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView - stopLoadingPhotoAtIndex: (NSInteger)photoIndex; - -@end - diff --git a/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollViewDelegate.h b/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollViewDelegate.h deleted file mode 100644 index 265e4c9..0000000 --- a/Pods/Nimbus/src/photos/src/NIPhotoAlbumScrollViewDelegate.h +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import - -#import "NimbusPagingScrollView.h" - -@class NIPhotoAlbumScrollView; - -/** - * The photo album scroll view delegate. - * - * @ingroup Photos-Protocols - * @see NIPhotoAlbumScrollView - */ -@protocol NIPhotoAlbumScrollViewDelegate - -@optional - -#pragma mark Scrolling and Zooming /** @name [NIPhotoAlbumScrollViewDelegate] Scrolling and Zooming */ - -/** - * The user double-tapped to zoom in or out. - */ -- (void)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView - didZoomIn: (BOOL)didZoomIn; - - -#pragma mark Data Availability /** @name [NIPhotoAlbumScrollViewDelegate] Data Availability */ - -/** - * The next photo in the album has been loaded and is ready to be displayed. - */ -- (void)photoAlbumScrollViewDidLoadNextPhoto:(NIPhotoAlbumScrollView *)photoAlbumScrollView; - -/** - * The previous photo in the album has been loaded and is ready to be displayed. - */ -- (void)photoAlbumScrollViewDidLoadPreviousPhoto:(NIPhotoAlbumScrollView *)photoAlbumScrollView; - -@end - diff --git a/Pods/Nimbus/src/photos/src/NIPhotoScrollView.h b/Pods/Nimbus/src/photos/src/NIPhotoScrollView.h deleted file mode 100644 index 7a85d04..0000000 --- a/Pods/Nimbus/src/photos/src/NIPhotoScrollView.h +++ /dev/null @@ -1,162 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIPagingScrollViewPage.h" -#import "NIPhotoScrollViewPhotoSize.h" - -#import -#import - -@protocol NIPhotoScrollViewDelegate; -@class NICenteringScrollView; - -/** - * A single photo view that supports zooming and rotation. - * - * @ingroup NimbusPhotos - */ -@interface NIPhotoScrollView : UIView - -#pragma mark Configuring Functionality - -@property (nonatomic, assign, getter=isZoomingEnabled) BOOL zoomingIsEnabled; // default: yes -@property (nonatomic, assign, getter=isZoomingAboveOriginalSizeEnabled) BOOL zoomingAboveOriginalSizeIsEnabled; // default: yes -@property (nonatomic, assign, getter=isDoubleTapToZoomEnabled) BOOL doubleTapToZoomIsEnabled; // default: yes -@property (nonatomic, assign) CGFloat maximumScale; // default: 0 (autocalculate) -@property (nonatomic, weak) id photoScrollViewDelegate; - -#pragma mark State - -- (UIImage *)image; -- (NIPhotoScrollViewPhotoSize)photoSize; -- (void)setImage:(UIImage *)image photoSize:(NIPhotoScrollViewPhotoSize)photoSize; -@property (nonatomic, assign, getter = isLoading) BOOL loading; - -@property (nonatomic, assign) NSInteger pageIndex; -@property (nonatomic, assign) CGSize photoDimensions; -@property (nonatomic, readonly, strong) UITapGestureRecognizer* doubleTapGestureRecognizer; - -@end - -/** @name Configuring Functionality */ - -/** - * Whether the photo is allowed to be zoomed. - * - * By default this is YES. - * - * @fn NIPhotoScrollView::zoomingIsEnabled - */ - -/** - * Whether small photos can be zoomed at least until they fit the screen. - * - * If this is disabled, images smaller than the view size can not be zoomed in beyond - * their original dimensions. - * - * If this is enabled, images smaller than the view size can be zoomed in only until - * they fit the view bounds. - * - * The default behavior in Photos.app allows small photos to be zoomed in. - * - * @attention This will allow photos to be zoomed in even if they don't have any more - * pixels to show, causing the photo to blur. This can look ok for photographs, - * but might not look ok for software design mockups. - * - * By default this is YES. - * - * @fn NIPhotoScrollView::zoomingAboveOriginalSizeIsEnabled - */ - -/** - * Whether double-tapping zooms in and out of the image. - * - * Available on iOS 3.2 and later. - * - * By default this is YES. - * - * @fn NIPhotoScrollView::doubleTapToZoomIsEnabled - */ - -/** - * The maximum scale of the image. - * - * By default this is 0, meaning the view will automatically determine the maximum scale. - * Setting this to a non-zero value will override the automatically-calculated maximum scale. - * - * @fn NIPhotoScrollView::maximumScale - */ - -/** - * The photo scroll view delegate. - * - * @fn NIPhotoScrollView::photoScrollViewDelegate - */ - - -/** @name State */ - -/** - * The currently-displayed photo. - * - * @fn NIPhotoScrollView::image - */ - -/** - * Set a new photo with a specific size. - * - * If image is nil then the photoSize will be overridden as NIPhotoScrollViewPhotoSizeUnknown. - * - * Resets the current zoom levels and zooms to fit the image. - * - * @fn NIPhotoScrollView::setImage:photoSize: - */ - -/** - * The index of this photo within a photo album. - * - * @fn NIPhotoScrollView::pageIndex - */ - -/** - * The current size of the photo. - * - * This is used to replace the photo only with successively higher-quality versions. - * - * @fn NIPhotoScrollView::photoSize - */ - -/** - * The largest dimensions of the photo. - * - * This is used to show the thumbnail at the final image size in case the final image size - * is smaller than the album's frame. Without this value we have to assume that the thumbnail - * will take up the full screen. If the final image doesn't take up the full screen, then - * the photo view will appear to "snap" to the smaller full-size image when the final image - * does load. - * - * CGSizeZero is used to signify an unknown final photo dimension. - * - * @fn NIPhotoScrollView::photoDimensions - */ - -/** - * The gesture recognizer for double-tapping zooms in and out of the image. - * - * This is used mainly for setting up dependencies between gesture recognizers. - * - * @fn NIPhotoScrollView::doubleTapGestureRecognizer - */ diff --git a/Pods/Nimbus/src/photos/src/NIPhotoScrollView.m b/Pods/Nimbus/src/photos/src/NIPhotoScrollView.m deleted file mode 100644 index 6512684..0000000 --- a/Pods/Nimbus/src/photos/src/NIPhotoScrollView.m +++ /dev/null @@ -1,512 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIPhotoScrollView.h" - -#import "NIPhotoScrollViewDelegate.h" - -#import "NimbusCore.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -/** - * A UIScrollView that centers the zooming view's frame as the user zooms. - * - * We must update the zooming view's frame within the scroll view's layoutSubviews, - * thus why we've subclassed UIScrollView. - */ -@interface NICenteringScrollView : UIScrollView -@end - - -@implementation NICenteringScrollView - - -#pragma mark - UIView - - -- (void)layoutSubviews { - [super layoutSubviews]; - - // Center the image as it becomes smaller than the size of the screen. - - UIView* zoomingSubview = [self.delegate viewForZoomingInScrollView:self]; - CGSize boundsSize = self.bounds.size; - CGRect frameToCenter = zoomingSubview.frame; - - // Center horizontally. - if (frameToCenter.size.width < boundsSize.width) { - frameToCenter.origin.x = NICGFloatFloor((boundsSize.width - frameToCenter.size.width) / 2); - - } else { - frameToCenter.origin.x = 0; - } - - // Center vertically. - if (frameToCenter.size.height < boundsSize.height) { - frameToCenter.origin.y = NICGFloatFloor((boundsSize.height - frameToCenter.size.height) / 2); - - } else { - frameToCenter.origin.y = 0; - } - - zoomingSubview.frame = frameToCenter; -} - -@end - -@interface NIPhotoScrollView () -@property (nonatomic, assign) NIPhotoScrollViewPhotoSize photoSize; -- (void)setMaxMinZoomScalesForCurrentBounds; -@end - -@implementation NIPhotoScrollView { - // The photo view to be zoomed. - UIImageView* _imageView; - // The scroll view. - NICenteringScrollView* _scrollView; - UIActivityIndicatorView* _loadingView; - - // Photo Information - NIPhotoScrollViewPhotoSize _photoSize; - CGSize _photoDimensions; - - // Configurable State - BOOL _zoomingIsEnabled; - BOOL _zoomingAboveOriginalSizeIsEnabled; - - UITapGestureRecognizer* _doubleTapGestureRecognizer; -} - -@synthesize reuseIdentifier; - -- (id)initWithFrame:(CGRect)frame { - if ((self = [super initWithFrame:frame])) { - // Default configuration. - self.zoomingIsEnabled = YES; - self.zoomingAboveOriginalSizeIsEnabled = YES; - self.doubleTapToZoomIsEnabled = YES; - - // Autorelease so that we don't have to worry about releasing the subviews in dealloc. - _scrollView = [[NICenteringScrollView alloc] initWithFrame:self.bounds]; - _scrollView.autoresizingMask = (UIViewAutoresizingFlexibleWidth - | UIViewAutoresizingFlexibleHeight); - - _loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; - [_loadingView sizeToFit]; - _loadingView.frame = NIFrameOfCenteredViewWithinView(_loadingView, self); - _loadingView.autoresizingMask = UIViewAutoresizingFlexibleMargins; - - // We implement viewForZoomingInScrollView: and return the image view for zooming. - _scrollView.delegate = self; - - // Disable the scroll indicators. - _scrollView.showsVerticalScrollIndicator = NO; - _scrollView.showsHorizontalScrollIndicator = NO; - - // Photo viewers should feel sticky when you're panning around, not smooth and slippery - // like a UITableView. - _scrollView.decelerationRate = UIScrollViewDecelerationRateFast; - - // Ensure that empty areas of the scroll view are draggable. - self.backgroundColor = [UIColor blackColor]; - _scrollView.backgroundColor = self.backgroundColor; - - _imageView = [[UIImageView alloc] initWithFrame:CGRectZero]; - - [_scrollView addSubview:_imageView]; - [self addSubview:_scrollView]; - [self addSubview:_loadingView]; - } - return self; -} - -- (void)setBackgroundColor:(UIColor *)backgroundColor { - [super setBackgroundColor:backgroundColor]; - - _scrollView.backgroundColor = backgroundColor; -} - -#pragma mark - UIScrollView - - -- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { - return _imageView; -} - -#pragma mark - Gesture Recognizers - - -- (CGRect)rectAroundPoint:(CGPoint)point atZoomScale:(CGFloat)zoomScale { - NIDASSERT(zoomScale > 0); - - // Define the shape of the zoom rect. - CGSize boundsSize = self.bounds.size; - - // Modify the size according to the requested zoom level. - // For example, if we're zooming in to 0.5 zoom, then this will increase the bounds size - // by a factor of two. - CGSize scaledBoundsSize = CGSizeMake(boundsSize.width / zoomScale, - boundsSize.height / zoomScale); - - CGRect rect = CGRectMake(point.x - scaledBoundsSize.width / 2, - point.y - scaledBoundsSize.height / 2, - scaledBoundsSize.width, - scaledBoundsSize.height); - - // When the image is zoomed out there is a bit of empty space around the image due - // to the fact that it's centered on the screen. When we created the rect around the - // point we need to take this "space" into account. - - // 1: get the frame of the image in this view's coordinates. - CGRect imageScaledFrame = [self convertRect:_imageView.frame toView:self]; - - // 2: Offset the frame by the excess amount. This will ensure that the zoomed location - // is always centered on the tap location. We only allow positive values because a - // negative value implies that there isn't actually any offset. - rect = CGRectOffset(rect, -MAX(0, imageScaledFrame.origin.x), -MAX(0, imageScaledFrame.origin.y)); - - return rect; -} - -- (void)didDoubleTap:(UITapGestureRecognizer *)tapGesture { - BOOL isCompletelyZoomedIn = (_scrollView.maximumZoomScale <= _scrollView.zoomScale + FLT_EPSILON); - - BOOL didZoomIn; - - _scrollView.scrollEnabled = true; - - if (isCompletelyZoomedIn) { - // Zoom the photo back out. - [_scrollView setZoomScale:_scrollView.minimumZoomScale animated:YES]; - - didZoomIn = NO; - - } else { - // Zoom into the tap point. - CGPoint tapCenter = [tapGesture locationInView:_imageView]; - - CGRect maxZoomRect = [self rectAroundPoint:tapCenter atZoomScale:_scrollView.maximumZoomScale]; - [_scrollView zoomToRect:maxZoomRect animated:YES]; - - didZoomIn = YES; - } - - if ([self.photoScrollViewDelegate respondsToSelector: - @selector(photoScrollViewDidDoubleTapToZoom:didZoomIn:)]) { - [self.photoScrollViewDelegate photoScrollViewDidDoubleTapToZoom:self didZoomIn:didZoomIn]; - } -} - -#pragma mark - NIPagingScrollViewPage - - -- (void)prepareForReuse { - _imageView.image = nil; - self.photoSize = NIPhotoScrollViewPhotoSizeUnknown; - _scrollView.zoomScale = 1; - _scrollView.contentSize = self.bounds.size; -} - -- (void)pageDidDisappear { - _scrollView.zoomScale = _scrollView.minimumZoomScale; -} - -#pragma mark - Public - - -- (void)setImage:(UIImage *)image photoSize:(NIPhotoScrollViewPhotoSize)photoSize { - _imageView.image = image; - [_imageView sizeToFit]; - - if (nil == image) { - self.photoSize = NIPhotoScrollViewPhotoSizeUnknown; - - } else { - self.photoSize = photoSize; - } - - // The min/max zoom values assume that the content size is the image size. The max zoom will - // be a value that allows the image to be seen at a 1-to-1 pixel resolution, while the min - // zoom will be small enough to fit the image on the screen perfectly. - if (nil != image) { - _scrollView.contentSize = image.size; - - } else { - _scrollView.contentSize = self.bounds.size; - } - - [self setMaxMinZoomScalesForCurrentBounds]; - - // Start off with the image fully-visible on the screen. - _scrollView.zoomScale = _scrollView.minimumZoomScale; - - [self setNeedsLayout]; -} - -- (void)setLoading:(BOOL)loading { - _loading = loading; - - if (loading) { - [_loadingView startAnimating]; - } else { - [_loadingView stopAnimating]; - } -} - -- (UIImage *)image { - return _imageView.image; -} - -- (void)setZoomingIsEnabled:(BOOL)enabled { - _zoomingIsEnabled = enabled; - - if (nil != _imageView.image) { - [self setMaxMinZoomScalesForCurrentBounds]; - - // Fit the image on screen. - _scrollView.zoomScale = _scrollView.minimumZoomScale; - - // Disable zoom bouncing if zooming is disabled, otherwise the view will allow pinching. - _scrollView.bouncesZoom = enabled; - - } else { - // Reset to the defaults if there is no set image yet. - _scrollView.zoomScale = 1; - _scrollView.minimumZoomScale = 1; - _scrollView.maximumZoomScale = 1; - _scrollView.bouncesZoom = NO; - } -} - -- (void)setDoubleTapToZoomIsEnabled:(BOOL)enabled { - if (enabled && nil == _doubleTapGestureRecognizer) { - _doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didDoubleTap:)]; - _doubleTapGestureRecognizer.numberOfTapsRequired = 2; - [self addGestureRecognizer:_doubleTapGestureRecognizer]; - } - - _doubleTapGestureRecognizer.enabled = enabled; -} - -- (BOOL)isDoubleTapToZoomEnabled { - return [_doubleTapGestureRecognizer isEnabled]; -} - -- (CGFloat)scaleForSize:(CGSize)size boundsSize:(CGSize)boundsSize useMinimalScale:(BOOL)minimalScale { - CGFloat xScale = boundsSize.width / size.width; // The scale needed to perfectly fit the image width-wise. - CGFloat yScale = boundsSize.height / size.height; // The scale needed to perfectly fit the image height-wise. - CGFloat minScale = minimalScale ? MIN(xScale, yScale) : MAX(xScale, yScale); // Use the minimum of these to allow the image to become fully visible, or the maximum to get fullscreen size - - return minScale; -} - -/** - * Calculate the min and max scale for the given dimensions and photo size. - * - * minScale will fit the photo to the bounds, unless it is too small in which case it will - * show the image at a 1-to-1 resolution. - * - * maxScale will be whatever value shows the image at a 1-to-1 resolution, UNLESS - * isZoomingAboveOriginalSizeEnabled is enabled, in which case maxScale will be calculated - * such that the image completely fills the bounds. - * - * Exception: If the photo size is unknown (this is a loading image, for example) then - * the minimum scale will be set without considering the screen scale. This allows the - * loading image to draw with its own image scale if it's a high-res @2x image. - */ -- (void)minAndMaxScaleForDimensions: (CGSize)dimensions - boundsSize: (CGSize)boundsSize - photoScale: (CGFloat)photoScale - photoSize: (NIPhotoScrollViewPhotoSize)photoSize - minScale: (CGFloat *)pMinScale - maxScale: (CGFloat *)pMaxScale { - NIDASSERT(nil != pMinScale); - NIDASSERT(nil != pMaxScale); - if (nil == pMinScale - || nil == pMaxScale) { - return; - } - - CGFloat minScale = [self scaleForSize: dimensions - boundsSize: boundsSize - useMinimalScale: YES]; - - // On high resolution screens we have double the pixel density, so we will be seeing - // every pixel if we limit the maximum zoom scale to 0.5. - // If the photo size is unknown, it's likely that we're showing the loading image and - // don't want to shrink it down with the zoom because it should be a scaled image. - CGFloat maxScale = ((NIPhotoScrollViewPhotoSizeUnknown == photoSize) - ? 1 - : (photoScale / NIScreenScale())); - - if (NIPhotoScrollViewPhotoSizeThumbnail != photoSize) { - // Don't let minScale exceed maxScale. (If the image is smaller than the screen, we - // don't want to force it to be zoomed.) - // todo marco minScale = MIN(minScale, maxScale); - } - - // At this point if the image is small, then minScale and maxScale will be the same because - // we don't want to allow the photo to be zoomed. - - // If zooming above the original size IS enabled, however, expand the max zoom to - // whatever value would make the image fit the view perfectly. - if ([self isZoomingAboveOriginalSizeEnabled]) { - CGFloat idealMaxScale = [self scaleForSize: dimensions - boundsSize: boundsSize - useMinimalScale: NO]; - maxScale = MAX(maxScale, idealMaxScale); - } - - *pMinScale = minScale; - *pMaxScale = maxScale; -} - -- (void)setMaxMinZoomScalesForCurrentBounds { - CGSize imageSize = _imageView.bounds.size; - - // Avoid crashing if the image has no dimensions. - if (imageSize.width <= 0 || imageSize.height <= 0) { - _scrollView.maximumZoomScale = 1; - _scrollView.minimumZoomScale = 1; - return; - } - - // The following code is from Apple's ImageScrollView example application and has been used - // here because it is well-documented and concise. - - CGSize boundsSize = _scrollView.bounds.size; - - CGFloat minScale = 0; - CGFloat maxScale = 0; - - // Calculate the min/max scale for the image to be presented. - [self minAndMaxScaleForDimensions: imageSize - boundsSize: boundsSize - photoScale: _imageView.image.scale - photoSize: self.photoSize - minScale: &minScale - maxScale: &maxScale]; - - // When we show thumbnails for images that are too small for the bounds, we try to use - // the known photo dimensions to scale the minimum scale to match what the final image - // would be. This avoids any "snapping" effects from stretching the thumbnail too large. - if ((NIPhotoScrollViewPhotoSizeThumbnail == self.photoSize) - && !CGSizeEqualToSize(self.photoDimensions, CGSizeZero)) { - CGFloat scaleToFitOriginal = 0; - CGFloat originalMaxScale = 0; - // Calculate the original-sized image's min/max scale. - [self minAndMaxScaleForDimensions: self.photoDimensions - boundsSize: boundsSize - photoScale: _imageView.image.scale - photoSize: NIPhotoScrollViewPhotoSizeOriginal - minScale: &scaleToFitOriginal - maxScale: &originalMaxScale]; - - if (scaleToFitOriginal + FLT_EPSILON >= (1.0 / NIScreenScale())) { - // If the final image will be smaller than the view then we want to use that - // scale as the "true" scale and adjust it relatively to the thumbnail's dimensions. - // This ensures that the thumbnail will always be the same visual size as the original - // image, giving us that sexy "crisping" effect when the thumbnail is loaded. - CGFloat relativeSize = self.photoDimensions.width / imageSize.width; - minScale = scaleToFitOriginal * relativeSize; - } - } - - // If zooming is disabled then we flatten the range for zooming to only allow the min zoom. - if (self.isZoomingEnabled && NIPhotoScrollViewPhotoSizeOriginal == self.photoSize && self.maximumScale > 0) { - _scrollView.maximumZoomScale = self.maximumScale; - } else { - _scrollView.maximumZoomScale = self.isZoomingEnabled ? maxScale : minScale; - } - _scrollView.minimumZoomScale = minScale; -} - -#pragma mark Saving/Restoring Offset and Scale - -// Parts of the following code are from Apple's ImageScrollView example application and -// have been used here because they are well-documented and concise. - - -// Fetch the visual center point of this view in the image view's coordinate space. -- (CGPoint)pointToCenterAfterRotation { - CGRect bounds = _scrollView.bounds; - CGPoint boundsCenter = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds)); - return [self convertPoint:boundsCenter toView:_imageView]; -} - -- (CGFloat)scaleToRestoreAfterRotation { - CGFloat contentScale = _scrollView.zoomScale; - - // If we're at the minimum zoom scale, preserve that by returning 0, which - // will be converted to the minimum allowable scale when the scale is restored. - if (contentScale <= _scrollView.minimumZoomScale + FLT_EPSILON) { - contentScale = 0; - } - - return contentScale; -} - -- (CGPoint)maximumContentOffset { - CGSize contentSize = _scrollView.contentSize; - CGSize boundsSize = _scrollView.bounds.size; - return CGPointMake(contentSize.width - boundsSize.width, - contentSize.height - boundsSize.height); -} - -- (CGPoint)minimumContentOffset { - return CGPointZero; -} - -- (void)restoreCenterPoint:(CGPoint)oldCenter scale:(CGFloat)oldScale { - // Step 1: restore zoom scale, making sure it is within the allowable range. - _scrollView.zoomScale = NIBoundf(oldScale, - _scrollView.minimumZoomScale, _scrollView.maximumZoomScale); - - // Step 2: restore center point, making sure it is within the allowable range. - - // 2a: convert our desired center point back to the scroll view's coordinate space from the - // image's coordinate space. - CGPoint boundsCenter = [self convertPoint:oldCenter fromView:_imageView]; - - // 2b: calculate the content offset that would yield that center point - CGPoint offset = CGPointMake(boundsCenter.x - _scrollView.bounds.size.width / 2.0f, - boundsCenter.y - _scrollView.bounds.size.height / 2.0f); - - // 2c: restore offset, adjusted to be within the allowable range - CGPoint maxOffset = [self maximumContentOffset]; - CGPoint minOffset = [self minimumContentOffset]; - offset.x = NIBoundf(offset.x, minOffset.x, maxOffset.x); - offset.y = NIBoundf(offset.y, minOffset.y, maxOffset.y); - _scrollView.contentOffset = offset; -} - -#pragma mark Saving/Restoring Offset and Scale - - -- (void)setFrameAndMaintainState:(CGRect)frame { - CGPoint restorePoint = [self pointToCenterAfterRotation]; - CGFloat restoreScale = [self scaleToRestoreAfterRotation]; - self.frame = frame; - [self setMaxMinZoomScalesForCurrentBounds]; - [self restoreCenterPoint:restorePoint scale:restoreScale]; - - [_scrollView setNeedsLayout]; -} - -@end diff --git a/Pods/Nimbus/src/photos/src/NIPhotoScrollViewDelegate.h b/Pods/Nimbus/src/photos/src/NIPhotoScrollViewDelegate.h deleted file mode 100644 index 64cdff5..0000000 --- a/Pods/Nimbus/src/photos/src/NIPhotoScrollViewDelegate.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import - -@class NIPhotoScrollView; - -/** - * The photo scroll view delegate. - * - * @ingroup NimbusPhotos - */ -@protocol NIPhotoScrollViewDelegate - -@optional - -#pragma mark Zooming /** @name [NIPhotoScrollViewDelegate] Zooming */ - -/** - * The user has double-tapped the photo to zoom either in or out. - * - * @param photoScrollView The photo scroll view that was tapped. - * @param didZoomIn YES if the photo was zoomed in. NO if the photo was zoomed out. - */ -- (void)photoScrollViewDidDoubleTapToZoom: (NIPhotoScrollView *)photoScrollView - didZoomIn: (BOOL)didZoomIn; - -@end diff --git a/Pods/Nimbus/src/photos/src/NIPhotoScrollViewPhotoSize.h b/Pods/Nimbus/src/photos/src/NIPhotoScrollViewPhotoSize.h deleted file mode 100644 index 2955cd2..0000000 --- a/Pods/Nimbus/src/photos/src/NIPhotoScrollViewPhotoSize.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import - -/** - * Contextual information about the size of the photo. - */ -typedef enum { - // Unknown photo size. - NIPhotoScrollViewPhotoSizeUnknown, - - // A smaller version of the image. - NIPhotoScrollViewPhotoSizeThumbnail, - - // The full-size image. - NIPhotoScrollViewPhotoSizeOriginal, -} NIPhotoScrollViewPhotoSize; diff --git a/Pods/Nimbus/src/photos/src/NIPhotoScrubberView.h b/Pods/Nimbus/src/photos/src/NIPhotoScrubberView.h deleted file mode 100644 index 04794b0..0000000 --- a/Pods/Nimbus/src/photos/src/NIPhotoScrubberView.h +++ /dev/null @@ -1,168 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import -#import - -#import "NIPreprocessorMacros.h" /* for weak */ - -@protocol NIPhotoScrubberViewDataSource; -@protocol NIPhotoScrubberViewDelegate; - -/** - * A control built for quickly skimming through a collection of images. - * - * @ingroup NimbusPhotos - * - * The user interacts with the scrubber by "scrubbing" their finger along the control, - * or more simply, touching the control and moving their finger along a single axis. - * Scrubbers can be seen in the Photos.app on the iPad. - * - * The thumbnails displayed in a scrubber will be a subset of the overall set of photos. - * The wider the scrubber, the more thumbnails will be shown. The displayed thumbnails will - * be chosen at constant intervals in the album, with a larger "selected" thumbnail image - * that will show whatever image is currently selected. This larger thumbnail will be - * positioned relatively within the scrubber to show the user what the current selection - * is in a physically intuitive way. - * - * This view is a completely independent view from the photo scroll view so you can choose - * to use this in your already built photo viewer. - * - * @image html scrubber1.png "Screenshot of NIPhotoScrubberView on the iPad." - * - * @see NIPhotoScrubberViewDataSource - * @see NIPhotoScrubberViewDelegate - */ -@interface NIPhotoScrubberView : UIView - -#pragma mark Data Source /** @name Data Source */ - -/** - * The data source for this scrubber view. - */ -@property (nonatomic, weak) id dataSource; - -/** - * Forces the scrubber view to reload all of its data. - * - * This must be called at least once after dataSource has been set in order for the view - * to gather any presentable information. - * - * This method is expensive. It will reset the state of the view and remove all existing - * thumbnails before requesting the new information from the data source. - */ -- (void)reloadData; - -/** - * Notify the scrubber view that a thumbnail has been loaded at a given index. - * - * This method is cheap, so do not be afraid to call it whenever a thumbnail loads. - * It will only modify visible thumbnails. - */ -- (void)didLoadThumbnail: (UIImage *)image - atIndex: (NSInteger)photoIndex; - -#pragma mark Delegate /** @name Delegate */ - -/** - * The delegate for this scrubber view. - */ -@property (nonatomic, weak) id delegate; - -#pragma mark Accessing Selection /** @name Accessing Selection */ - -/** - * The selected photo index. - */ -@property (nonatomic, assign) NSInteger selectedPhotoIndex; - -/** - * Set the selected photo with animation. - */ -- (void)setSelectedPhotoIndex:(NSInteger)photoIndex animated:(BOOL)animated; - -@end - -/** - * The data source for the photo scrubber. - * - * @ingroup NimbusPhotos - * - *

Performance Considerations

- * - * A scrubber view's purpose is for instantly flipping through an album of photos. As such, - * it's crucial that your implementation of the data source performs blazingly fast. When - * the scrubber requests a thumbnail from you you should *not* be hitting the disk or blocking - * on a network call. If you don't have the thumbnail available at that exact moment, fire - * off an asynchronous load request (using NIReadFileFromDiskOperation or NIHTTPRequest) - * and return nil. Once the thumbnail is loaded, call didLoadThumbnail:atIndex: to notify - * the scrubber that it can display the thumbnail now. - * - * It is not recommended to use high-res images for your scrubber thumbnails. This is because - * the scrubber will keep a large set of images in memory and if you're giving it - * high-resolution images then you'll find that your app quickly burns through memory. - * If you don't have access to thumbnails from whatever API you're using then you should consider - * not using a scrubber. - * - * @see NIPhotoScrubberView - */ -@protocol NIPhotoScrubberViewDataSource - -@required - -#pragma mark Fetching Required Information /** @name Fetching Required Information */ - -/** - * Fetches the total number of photos in the scroll view. - * - * The value returned in this method will be cached by the scroll view until reloadData - * is called again. - */ -- (NSInteger)numberOfPhotosInScrubberView:(NIPhotoScrubberView *)photoScrubberView; - -/** - * Fetch the thumbnail image for the given photo index. - * - * Please read and understand the performance considerations for this data source. - */ -- (UIImage *)photoScrubberView: (NIPhotoScrubberView *)photoScrubberView - thumbnailAtIndex: (NSInteger)thumbnailIndex; - -@end - -/** - * The delegate for the photo scrubber. - * - * @ingroup NimbusPhotos - * - * Sends notifications of state changes. - * - * @see NIPhotoScrubberView - */ -@protocol NIPhotoScrubberViewDelegate - -@optional - -#pragma mark Selection Changes /** @name Selection Changes */ - -/** - * The photo scrubber changed its selection. - * - * Use photoScrubberView.selectedPhotoIndex to access the current selection. - */ -- (void)photoScrubberViewDidChangeSelection:(NIPhotoScrubberView *)photoScrubberView; - -@end diff --git a/Pods/Nimbus/src/photos/src/NIPhotoScrubberView.m b/Pods/Nimbus/src/photos/src/NIPhotoScrubberView.m deleted file mode 100644 index ef949a5..0000000 --- a/Pods/Nimbus/src/photos/src/NIPhotoScrubberView.m +++ /dev/null @@ -1,465 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIPhotoScrubberView.h" - -#import "NimbusCore.h" - -#import - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -static const NSInteger NIPhotoScrubberViewUnknownTag = -1; - -@interface NIPhotoScrubberView() - -/** - * @internal - * - * A method to encapsulate initilization logic that can be shared by different init methods. - */ -- (void)initializeScrubber; - -/** - * @internal - * - * A lightweight method for updating all of the visible thumbnails in the scrubber. - * - * This method will force the scrubber to lay itself out, calculate how many thumbnails might - * be visible, and then lay out the thumbnails and fetch any thumbnail images it can find. - * - * This method should never take much time to run, so it can safely be used in layoutSubviews. - */ -- (void)updateVisiblePhotos; - -/** - * @internal - * - * Returns a new, autoreleased image view in the style of this photo scrubber. - * - * This implementation returns an image with a 1px solid white border and a black background. - */ -- (UIImageView *)photoView; - -@end - - -@implementation NIPhotoScrubberView { - NSMutableArray* _visiblePhotoViews; - NSMutableSet* _recycledPhotoViews; - - UIView* _containerView; - UIImageView* _selectionView; - - // State - NSInteger _selectedPhotoIndex; - - // Cached data source values - NSInteger _numberOfPhotos; - - // Cached display values - NSInteger _numberOfVisiblePhotos; -} - -- (id)initWithFrame:(CGRect)frame { - if ((self = [super initWithFrame:frame])) { - [self initializeScrubber]; - } - - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - if ((self = [super initWithCoder:aDecoder])) { - [self initializeScrubber]; - } - - return self; -} - -- (void)initializeScrubber { - // Only one finger should be allowed to interact with the scrubber at a time. - self.multipleTouchEnabled = NO; - - _containerView = [[UIView alloc] init]; - _containerView.layer.borderColor = [UIColor colorWithWhite:1 alpha:0.1f].CGColor; - _containerView.layer.borderWidth = 1; - _containerView.backgroundColor = [UIColor colorWithWhite:1 alpha:0.3f]; - _containerView.userInteractionEnabled = NO; - [self addSubview:_containerView]; - - _selectionView = [self photoView]; - [self addSubview:_selectionView]; - - _selectedPhotoIndex = -1; -} - -#pragma mark - View Creation - - -- (UIImageView *)photoView { - UIImageView* imageView = [[UIImageView alloc] init]; - - imageView.layer.borderColor = [UIColor whiteColor].CGColor; - imageView.layer.borderWidth = 1; - imageView.backgroundColor = [UIColor blackColor]; - imageView.clipsToBounds = YES; - - imageView.userInteractionEnabled = NO; - - imageView.contentMode = UIViewContentModeScaleAspectFill; - - imageView.tag = NIPhotoScrubberViewUnknownTag; - - return imageView; -} - -#pragma mark - Layout - - -- (CGSize)photoSize { - CGSize boundsSize = self.bounds.size; - - // These numbers are roughly estimated from the Photos.app's scrubber. - CGFloat photoWidth = NICGFloatFloor(boundsSize.height / 0.6f); - CGFloat photoHeight = NICGFloatFloor(photoWidth * 0.75f); - - return CGSizeMake(photoWidth, photoHeight); -} - -- (CGSize)selectionSize { - CGSize boundsSize = self.bounds.size; - - // These numbers are roughly estimated from the Photos.app's scrubber. - CGFloat selectionWidth = NICGFloatFloor(boundsSize.height / 0.3f); - CGFloat selectionHeight = NICGFloatFloor(selectionWidth * 0.75f); - - return CGSizeMake(selectionWidth, selectionHeight); -} - -// The amount of space on either side of the scrubber's left and right edges. -- (CGFloat)horizontalMargins { - CGSize photoSize = [self photoSize]; - return NICGFloatFloor(photoSize.width / 2); -} - -- (CGFloat)spaceBetweenPhotos { - return 1; -} - -// The maximum number of pixels that the scrubber can utilize. The scrubber layer's border -// is contained within this width and must be considered when laying out the thumbnails. -- (CGFloat)maxContentWidth { - CGSize boundsSize = self.bounds.size; - CGFloat horizontalMargins = [self horizontalMargins]; - - CGFloat maxContentWidth = (boundsSize.width - - horizontalMargins * 2); - return maxContentWidth; -} - -- (NSInteger)numberOfVisiblePhotos { - CGSize photoSize = [self photoSize]; - CGFloat spaceBetweenPhotos = [self spaceBetweenPhotos]; - - // Here's where we take into account the container layer's border because we don't want to - // display thumbnails on top of the border. - CGFloat maxContentWidth = ([self maxContentWidth] - - _containerView.layer.borderWidth * 2); - - NSInteger numberOfPhotosThatFit = (NSInteger)floor((maxContentWidth + spaceBetweenPhotos) - / (photoSize.width + spaceBetweenPhotos)); - return MIN(_numberOfPhotos, numberOfPhotosThatFit); -} - -- (CGRect)frameForSelectionAtIndex:(NSInteger)photoIndex { - CGSize photoSize = [self photoSize]; - CGSize selectionSize = [self selectionSize]; - - CGFloat containerWidth = _containerView.bounds.size.width; - // TODO (jverkoey July 21, 2011): I need to figure out why this is necessary. - // Basically, when there are a lot of photos it seems like the selection frame - // slowly gets offset from the thumbnail frame it's supposed to be representing until by the end - // it's off the right edge by a noticeable amount. Trimming off some fat from the right - // edge seems to fix this. - if (_numberOfVisiblePhotos < _numberOfPhotos) { - containerWidth -= photoSize.width / 2; - } - - // Calculate the offset into the container view based on index/numberOfPhotos. - CGFloat relativeOffset = NICGFloatFloor((((CGFloat)photoIndex * containerWidth) - / (CGFloat)MAX(1, _numberOfPhotos))); - - return CGRectMake(NICGFloatFloor(_containerView.frame.origin.x - + relativeOffset - + photoSize.width / 2 - selectionSize.width / 2), - NICGFloatFloor(_containerView.center.y - selectionSize.height / 2), - selectionSize.width, selectionSize.height); -} - -- (CGRect)frameForThumbAtIndex:(NSInteger)thumbIndex { - CGSize photoSize = [self photoSize]; - CGFloat spaceBetweenPhotos = [self spaceBetweenPhotos]; - return CGRectMake(_containerView.layer.borderWidth - + (photoSize.width + spaceBetweenPhotos) * thumbIndex, - _containerView.layer.borderWidth, - photoSize.width, photoSize.height); -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - CGSize boundsSize = self.bounds.size; - - CGSize photoSize = [self photoSize]; - CGFloat spaceBetweenPhotos = [self spaceBetweenPhotos]; - CGFloat maxContentWidth = [self maxContentWidth]; - - // Update the total number of visible photos. - _numberOfVisiblePhotos = [self numberOfVisiblePhotos]; - - // Hide views if there isn't any interesting information to show. - _containerView.hidden = (0 == _numberOfVisiblePhotos); - _selectionView.hidden = (_selectedPhotoIndex < 0 || _containerView.hidden); - - // Calculate the container width using the number of visible photos. - CGFloat containerWidth = ((_numberOfVisiblePhotos * photoSize.width) - + (MAX(0, _numberOfVisiblePhotos - 1) * spaceBetweenPhotos) - + _containerView.layer.borderWidth * 2); - - // Then we center the container in the content area. - CGFloat containerMargins = MAX(0, NICGFloatFloor((maxContentWidth - containerWidth) / 2)); - CGFloat horizontalMargins = [self horizontalMargins]; - CGFloat containerHeight = photoSize.height + _containerView.layer.borderWidth * 2; - - CGFloat containerLeftMargin = horizontalMargins + containerMargins; - CGFloat containerTopMargin = NICGFloatFloor((boundsSize.height - containerHeight) / 2); - - _containerView.frame = CGRectMake(containerLeftMargin, - containerTopMargin, - containerWidth, - containerHeight); - - // Don't bother updating the selected photo index if there isn't a selection; the - // selection view will be hidden anyway. - if (_selectedPhotoIndex >= 0) { - _selectionView.frame = [self frameForSelectionAtIndex:_selectedPhotoIndex]; - } - - // Update the frames for all of the thumbnails. - [self updateVisiblePhotos]; -} - -// Transforms an index into the number of visible photos into an index into the total -// number of photos. -- (NSInteger)photoIndexAtScrubberIndex:(NSInteger)scrubberIndex { - return (NSInteger)(NICGFloatCeil((CGFloat)(scrubberIndex * _numberOfPhotos) - / (CGFloat)_numberOfVisiblePhotos) - + 0.5f); -} - -- (void)updateVisiblePhotos { - if (nil == self.dataSource) { - return; - } - - // This will update the number of visible photos if the layout did indeed change. - [self layoutIfNeeded]; - - // Recycle any views that we no longer need. - while ([_visiblePhotoViews count] > (NSUInteger)_numberOfVisiblePhotos) { - UIView* photoView = [_visiblePhotoViews lastObject]; - [photoView removeFromSuperview]; - - [_recycledPhotoViews addObject:photoView]; - - [_visiblePhotoViews removeLastObject]; - } - - // Lay out the visible photos. - for (NSUInteger ix = 0; ix < (NSUInteger)_numberOfVisiblePhotos; ++ix) { - UIImageView* photoView = nil; - - // We must first get the photo view at this index. - - // If there aren't enough visible photo views then try to recycle another view. - if (ix >= [_visiblePhotoViews count]) { - photoView = [_recycledPhotoViews anyObject]; - if (nil == photoView) { - // Couldn't recycle the view, so create a new one. - photoView = [self photoView]; - - } else { - [_recycledPhotoViews removeObject:photoView]; - } - [_containerView addSubview:photoView]; - [_visiblePhotoViews addObject:photoView]; - - } else { - photoView = [_visiblePhotoViews objectAtIndex:ix]; - } - - NSInteger photoIndex = [self photoIndexAtScrubberIndex:ix]; - - // Only request the thumbnail if this thumbnail's photo index has changed. Otherwise - // we assume that this photo either already has the thumbnail or it's still loading. - if (photoView.tag != photoIndex) { - photoView.tag = photoIndex; - - UIImage* image = [self.dataSource photoScrubberView:self thumbnailAtIndex:photoIndex]; - photoView.image = image; - - if (_selectedPhotoIndex == photoIndex) { - _selectionView.image = image; - } - } - - photoView.frame = [self frameForThumbAtIndex:ix]; - } -} - -#pragma mark - Changing Selection - - -- (NSInteger)photoIndexAtPoint:(CGPoint)point { - NSInteger photoIndex; - - if (point.x <= 0) { - // Beyond the left edge - photoIndex = 0; - - } else if (point.x >= _containerView.bounds.size.width) { - // Beyond the right edge - photoIndex = (_numberOfPhotos - 1); - - } else { - // Somewhere in between - photoIndex = (NSInteger)(NICGFloatFloor((point.x / _containerView.bounds.size.width) * _numberOfPhotos) - + 0.5f); - } - - return photoIndex; -} - -- (void)updateSelectionWithPoint:(CGPoint)point { - NSInteger photoIndex = [self photoIndexAtPoint:point]; - - if (photoIndex != _selectedPhotoIndex) { - [self setSelectedPhotoIndex:photoIndex]; - - if ([self.delegate respondsToSelector:@selector(photoScrubberViewDidChangeSelection:)]) { - [self.delegate photoScrubberViewDidChangeSelection:self]; - } - } -} - -#pragma mark - UIResponder - - -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - [super touchesBegan:touches withEvent:event]; - - UITouch* touch = [touches anyObject]; - CGPoint touchPoint = [touch locationInView:_containerView]; - - [self updateSelectionWithPoint:touchPoint]; -} - -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - [super touchesMoved:touches withEvent:event]; - - UITouch* touch = [touches anyObject]; - CGPoint touchPoint = [touch locationInView:_containerView]; - - [self updateSelectionWithPoint:touchPoint]; -} - -#pragma mark - Public - - -- (void)didLoadThumbnail: (UIImage *)image - atIndex: (NSInteger)photoIndex { - for (UIImageView* thumbView in _visiblePhotoViews) { - if (thumbView.tag == photoIndex) { - thumbView.image = image; - break; - } - } - - // Update the selected thumbnail if it's the one that just received a photo. - if (_selectedPhotoIndex == photoIndex) { - _selectionView.image = image; - } -} - -- (void)reloadData { - NIDASSERT(nil != _dataSource); - - // Remove any visible photos from the view before we release the sets. - for (UIView* photoView in _visiblePhotoViews) { - [photoView removeFromSuperview]; - } - - // If there is no data source then we can't do anything particularly interesting. - if (nil == _dataSource) { - return; - } - - _visiblePhotoViews = [[NSMutableArray alloc] init]; - _recycledPhotoViews = [[NSMutableSet alloc] init]; - - // Cache the number of photos. - _numberOfPhotos = [_dataSource numberOfPhotosInScrubberView:self]; - - [self setNeedsLayout]; - - // This will call layoutIfNeeded and layoutSubviews will then be called because we - // set the needsLayout flag. - [self updateVisiblePhotos]; -} - -- (void)setSelectedPhotoIndex:(NSInteger)photoIndex animated:(BOOL)animated { - if (_selectedPhotoIndex != photoIndex) { - // Don't animate the selection if it was previously invalid. - animated = animated && (_selectedPhotoIndex >= 0); - - _selectedPhotoIndex = photoIndex; - - if (animated) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.2]; - [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; - [UIView setAnimationBeginsFromCurrentState:YES]; - } - - _selectionView.frame = [self frameForSelectionAtIndex:_selectedPhotoIndex]; - - if (animated) { - [UIView commitAnimations]; - } - - _selectionView.image = [self.dataSource photoScrubberView: self - thumbnailAtIndex: _selectedPhotoIndex]; - } -} - -- (void)setSelectedPhotoIndex:(NSInteger)photoIndex { - [self setSelectedPhotoIndex:photoIndex animated:NO]; -} - -@end diff --git a/Pods/Nimbus/src/photos/src/NIToolbarPhotoViewController.h b/Pods/Nimbus/src/photos/src/NIToolbarPhotoViewController.h deleted file mode 100644 index 051a43c..0000000 --- a/Pods/Nimbus/src/photos/src/NIToolbarPhotoViewController.h +++ /dev/null @@ -1,201 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import -#import - -#import "NIPhotoAlbumScrollView.h" -#import "NIPhotoScrubberView.h" - -@class NIPhotoAlbumScrollView; - -/** - * A simple photo album view controller implementation with a toolbar. - * - * @ingroup NimbusPhotos - * - * This controller does not implement the photo album data source, it simply implements - * some of the most common UI elements that are associated with a photo viewer. - * - * For an example of implementing the data source, see the photos examples in the - * examples directory. - * - *

Implementing Delegate Methods

- * - * This view controller already implements NIPhotoAlbumScrollViewDelegate. If you want to - * implement methods of this delegate you should take care to call the super implementation - * if necessary. The following methods have implementations in this class: - * - * - photoAlbumScrollViewDidScroll: - * - photoAlbumScrollView:didZoomIn: - * - photoAlbumScrollViewDidChangePages: - * - * - *

Recommended Configurations

- * - *

Default: Zooming enabled with translucent toolbar

- * - * The default settings are good for showing a photo album that takes up the entire screen. - * The photos will be visible beneath the toolbar because it is translucent. The chrome will - * be hidden whenever the user starts interacting with the photos. - * - * @code - * toolbarIsTranslucent = YES; - * hidesChromeWhenScrolling = YES; - * chromeCanBeHidden = YES; - * @endcode - * - *

Zooming disabled with opaque toolbar

- * - * The following settings are good for viewing photo albums when you want to keep the chrome - * visible at all times without zooming enabled. - * - * @code - * toolbarIsTranslucent = NO; - * chromeCanBeHidden = NO; - * photoAlbumView.zoomingIsEnabled = NO; - * @endcode - */ -@interface NIToolbarPhotoViewController : UIViewController - -#pragma mark Configuring Functionality - -@property (nonatomic, assign, getter=isToolbarTranslucent) BOOL toolbarIsTranslucent; // default: yes -@property (nonatomic, assign) BOOL hidesChromeWhenScrolling; // default: yes -@property (nonatomic, assign) BOOL chromeCanBeHidden; // default: yes -@property (nonatomic, assign) BOOL animateMovingToNextAndPreviousPhotos; // default: no -@property (nonatomic, assign, getter=isScrubberEnabled) BOOL scrubberIsEnabled; // default: ipad yes - iphone no - -#pragma mark Views - -@property (nonatomic, readonly, strong) UIToolbar* toolbar; -@property (nonatomic, readonly, strong) NIPhotoAlbumScrollView* photoAlbumView; -@property (nonatomic, readonly, strong) NIPhotoScrubberView* photoScrubberView; -- (void)refreshChromeState; - -#pragma mark Toolbar Buttons - -@property (nonatomic, readonly, strong) UIBarButtonItem* nextButton; -@property (nonatomic, readonly, strong) UIBarButtonItem* previousButton; - -#pragma mark Subclassing - -- (void)setChromeVisibility:(BOOL)isVisible animated:(BOOL)animated; -- (void)setChromeTitle; - -@end - -/** @name Configuring Functionality */ - -/** - * Whether the toolbar is translucent and shows photos beneath it or not. - * - * If this is enabled, the toolbar will be translucent and the photo view will - * take up the entire view controller's bounds. - * - * If this is disabled, the photo will only occupy the remaining space above the - * toolbar. The toolbar will also not be hidden when the chrome is dismissed. This is by design - * because dismissing the toolbar when photos can't be displayed beneath it would leave - * an empty space below the album. - * - * By default this is YES. - * - * @fn NIToolbarPhotoViewController::toolbarIsTranslucent - */ - -/** - * Whether or not to hide the chrome when the user begins interacting with the photo. - * - * If this is enabled, then the chrome will be hidden when the user starts swiping from - * one photo to another. - * - * The chrome is the toolbar and the system status bar. - * - * By default this is YES. - * - * @attention This will be set to NO if toolbarCanBeHidden is set to NO. - * - * @fn NIToolbarPhotoViewController::hidesChromeWhenScrolling - */ - -/** - * Whether or not to allow hiding the chrome. - * - * If this is enabled then the user will be able to single-tap to dismiss or show the - * toolbar. - * - * The chrome is the toolbar and the system status bar. - * - * If this is disabled then the chrome will always be visible. - * - * By default this is YES. - * - * @attention Setting this to NO will also disable hidesToolbarWhenScrolling. - * - * @fn NIToolbarPhotoViewController::chromeCanBeHidden - */ - -/** - * Whether to animate moving to a next or previous photo when the user taps the button. - * - * By default this is NO. - * - * @fn NIToolbarPhotoViewController::animateMovingToNextAndPreviousPhotos - */ - -/** - * Whether to show a scrubber in the toolbar instead of next/previous buttons. - * - * By default this is YES on the iPad and NO on the iPhone. - * - * @fn NIToolbarPhotoViewController::scrubberIsEnabled - */ - - -/** @name Views */ - -/** - * The toolbar view. - * - * @fn NIToolbarPhotoViewController::toolbar - */ - -/** - * The photo album view. - * - * @fn NIToolbarPhotoViewController::photoAlbumView - */ - -/** - * The photo scrubber view. - * - * @fn NIToolbarPhotoViewController::photoScrubberView - */ - - -/** @name Toolbar Buttons */ - -/** - * The 'next' button. - * - * @fn NIToolbarPhotoViewController::nextButton - */ - -/** - * The 'previous' button. - * - * @fn NIToolbarPhotoViewController::previousButton - */ diff --git a/Pods/Nimbus/src/photos/src/NIToolbarPhotoViewController.m b/Pods/Nimbus/src/photos/src/NIToolbarPhotoViewController.m deleted file mode 100644 index 6ecf0e3..0000000 --- a/Pods/Nimbus/src/photos/src/NIToolbarPhotoViewController.m +++ /dev/null @@ -1,533 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -#import "NIToolbarPhotoViewController.h" - -#import "NIPhotoAlbumScrollView.h" - -#import "NimbusCore.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "Nimbus requires ARC support." -#endif - -@implementation NIToolbarPhotoViewController { - // Views - UIToolbar* _toolbar; - NIPhotoAlbumScrollView* _photoAlbumView; - - // Scrubber View - NIPhotoScrubberView* _photoScrubberView; - - // Toolbar Buttons - UIBarButtonItem* _nextButton; - UIBarButtonItem* _previousButton; - - // Gestures - UITapGestureRecognizer* _tapGesture; - - // State - BOOL _isAnimatingChrome; - BOOL _isChromeHidden; - BOOL _prefersStatusBarHidden; - - // Configuration - BOOL _toolbarIsTranslucent; - BOOL _hidesChromeWhenScrolling; - BOOL _chromeCanBeHidden; - BOOL _animateMovingToNextAndPreviousPhotos; - BOOL _scrubberIsEnabled; -} - - -- (void)shutdown_NIToolbarPhotoViewController { - _toolbar = nil; - _photoAlbumView = nil; - _nextButton = nil; - _previousButton = nil; - _photoScrubberView = nil; - _tapGesture = nil; -} - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { - // Default Configuration Settings - self.toolbarIsTranslucent = YES; - self.hidesChromeWhenScrolling = YES; - self.chromeCanBeHidden = YES; - self.animateMovingToNextAndPreviousPhotos = NO; - if ([self respondsToSelector:@selector(setAutomaticallyAdjustsScrollViewInsets:)]) { - self.automaticallyAdjustsScrollViewInsets = NO; - } - - // The scrubber is better use of the extra real estate on the iPad. - // If you ask me, though, the scrubber works pretty well on the iPhone too. It's up - // to you if you want to use it in your own implementations. - self.scrubberIsEnabled = NIIsPad(); - - // Allow the photos to display beneath the status bar. - self.wantsFullScreenLayout = YES; - } - return self; -} - -- (void)addTapGestureToView { - if ([self isViewLoaded]) { - if (nil == _tapGesture) { - _tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTap)]; - [self.photoAlbumView addGestureRecognizer:_tapGesture]; - } - } - - _tapGesture.enabled = YES; -} - -- (void)updateToolbarItems { - UIBarItem* flexibleSpace = - [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace - target: nil - action: nil]; - - if ([self isScrubberEnabled]) { - _nextButton = nil; - _previousButton = nil; - - if (nil == _photoScrubberView) { - CGRect scrubberFrame = CGRectMake(0, 0, - self.toolbar.bounds.size.width, - self.toolbar.bounds.size.height); - _photoScrubberView = [[NIPhotoScrubberView alloc] initWithFrame:scrubberFrame]; - _photoScrubberView.autoresizingMask = (UIViewAutoresizingFlexibleWidth - | UIViewAutoresizingFlexibleHeight); - _photoScrubberView.delegate = self; - } - - UIBarButtonItem* scrubberItem = - [[UIBarButtonItem alloc] initWithCustomView:self.photoScrubberView]; - self.toolbar.items = [NSArray arrayWithObjects: - flexibleSpace, scrubberItem, flexibleSpace, - nil]; - - [_photoScrubberView setSelectedPhotoIndex:self.photoAlbumView.centerPageIndex]; - - } else { - _photoScrubberView = nil; - - if (nil == _nextButton) { - UIImage* nextIcon = [UIImage imageWithContentsOfFile: - NIPathForBundleResource(nil, @"NimbusPhotos.bundle/gfx/next.png")]; - - // We weren't able to find the next or previous icons in your application's resources. - // Ensure that you've dragged the NimbusPhotos.bundle from src/photos/resources into your - // application with the "Create Folder References" option selected. You can verify that - // you've done this correctly by expanding the NimbusPhotos.bundle file in your project - // and verifying that the 'gfx' directory is blue. Also verify that the bundle is being - // copied in the Copy Bundle Resources phase. - NIDASSERT(nil != nextIcon); - - _nextButton = [[UIBarButtonItem alloc] initWithImage: nextIcon - style: UIBarButtonItemStylePlain - target: self - action: @selector(didTapNextButton)]; - - } - - if (nil == _previousButton) { - UIImage* previousIcon = [UIImage imageWithContentsOfFile: - NIPathForBundleResource(nil, @"NimbusPhotos.bundle/gfx/previous.png")]; - - // We weren't able to find the next or previous icons in your application's resources. - // Ensure that you've dragged the NimbusPhotos.bundle from src/photos/resources into your - // application with the "Create Folder References" option selected. You can verify that - // you've done this correctly by expanding the NimbusPhotos.bundle file in your project - // and verifying that the 'gfx' directory is blue. Also verify that the bundle is being - // copied in the Copy Bundle Resources phase. - NIDASSERT(nil != previousIcon); - - _previousButton = [[UIBarButtonItem alloc] initWithImage: previousIcon - style: UIBarButtonItemStylePlain - target: self - action: @selector(didTapPreviousButton)]; - } - - self.toolbar.items = [NSArray arrayWithObjects: - flexibleSpace, self.previousButton, - flexibleSpace, self.nextButton, - flexibleSpace, - nil]; - } - -} - -- (void)loadView { - [super loadView]; - - self.view.backgroundColor = [UIColor blackColor]; - - CGRect bounds = self.view.bounds; - - // Toolbar Setup - - CGFloat toolbarHeight = NIToolbarHeightForOrientation(NIInterfaceOrientation()); - CGRect toolbarFrame = CGRectMake(0, bounds.size.height - toolbarHeight, - bounds.size.width, toolbarHeight); - - _toolbar = [[UIToolbar alloc] initWithFrame:toolbarFrame]; - _toolbar.barStyle = UIBarStyleBlack; - _toolbar.translucent = self.toolbarIsTranslucent; - _toolbar.autoresizingMask = (UIViewAutoresizingFlexibleWidth - | UIViewAutoresizingFlexibleTopMargin); - - [self updateToolbarItems]; - - // Photo Album View Setup - - CGRect photoAlbumFrame = bounds; - if (!self.toolbarIsTranslucent) { - photoAlbumFrame = NIRectContract(bounds, 0, toolbarHeight); - } - _photoAlbumView = [[NIPhotoAlbumScrollView alloc] initWithFrame:photoAlbumFrame]; - _photoAlbumView.autoresizingMask = (UIViewAutoresizingFlexibleWidth - | UIViewAutoresizingFlexibleHeight); - _photoAlbumView.delegate = self; - - [self.view addSubview:_photoAlbumView]; - [self.view addSubview:_toolbar]; - - if (self.hidesChromeWhenScrolling || self.chromeCanBeHidden) { - [self addTapGestureToView]; - } -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - [[UIApplication sharedApplication] setStatusBarStyle: (NIIsPad() - ? UIStatusBarStyleBlackOpaque - : UIStatusBarStyleBlackTranslucent) - animated: animated]; - - UINavigationBar* navBar = self.navigationController.navigationBar; - navBar.barStyle = UIBarStyleBlack; - navBar.translucent = self.toolbarIsTranslucent; - - _previousButton.enabled = [self.photoAlbumView hasPrevious]; - _nextButton.enabled = [self.photoAlbumView hasNext]; -} - -#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0 -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { - return NIIsSupportedOrientation(toInterfaceOrientation); -} -#endif - - -- (void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation - duration: (NSTimeInterval)duration { - [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; - - [self.photoAlbumView willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; -} - -- (void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation - duration: (NSTimeInterval)duration { - [self.photoAlbumView willAnimateRotationToInterfaceOrientation: toInterfaceOrientation - duration: duration]; - - [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation - duration:duration]; - - CGRect toolbarFrame = self.toolbar.frame; - toolbarFrame.size.height = NIToolbarHeightForOrientation(toInterfaceOrientation); - toolbarFrame.origin.y = self.view.bounds.size.height - toolbarFrame.size.height; - self.toolbar.frame = toolbarFrame; - - if (!self.toolbarIsTranslucent) { - CGRect photoAlbumFrame = self.photoAlbumView.frame; - photoAlbumFrame.size.height = self.view.bounds.size.height - toolbarFrame.size.height; - self.photoAlbumView.frame = photoAlbumFrame; - } -} - -- (UIView *)rotatingFooterView { - return self.toolbar.hidden ? nil : self.toolbar; -} - -- (void)didHideChrome { - _isAnimatingChrome = NO; - if (self.toolbarIsTranslucent) { - self.toolbar.hidden = YES; - } - - [self.navigationController setNavigationBarHidden:YES animated:NO]; - _isChromeHidden = YES; -} - -- (void)didShowChrome { - _isAnimatingChrome = NO; - - _isChromeHidden = NO; -} - -- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation { - return UIStatusBarAnimationSlide; -} - -- (BOOL)prefersStatusBarHidden { - return _prefersStatusBarHidden; -} - -- (void)setChromeVisibility:(BOOL)isVisible animated:(BOOL)animated { - if (_isAnimatingChrome - || (!isVisible && _isChromeHidden) - || (isVisible && !_isChromeHidden) - || !self.chromeCanBeHidden) { - // Nothing to do here. - return; - } - - CGRect toolbarFrame = self.toolbar.frame; - CGRect bounds = self.view.bounds; - - if (self.toolbarIsTranslucent) { - // Reset the toolbar's initial position. - if (!isVisible) { - toolbarFrame.origin.y = bounds.size.height - toolbarFrame.size.height; - - } else { - // Ensure that the toolbar is visible through the animation. - self.toolbar.hidden = NO; - - toolbarFrame.origin.y = bounds.size.height; - } - self.toolbar.frame = toolbarFrame; - } - - // Show/hide the system chrome. - BOOL isStatusBarAppearanceSupported = [self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]; - if (!isStatusBarAppearanceSupported) { - [[UIApplication sharedApplication] setStatusBarHidden:!isVisible - withAnimation:(animated - ? UIStatusBarAnimationSlide - : UIStatusBarAnimationNone)]; - } - - if (self.toolbarIsTranslucent) { - // Place the toolbar at its final location. - if (isVisible) { - // Slide up. - toolbarFrame.origin.y = bounds.size.height - toolbarFrame.size.height; - - } else { - // Slide down. - toolbarFrame.origin.y = bounds.size.height; - } - } - - // If there is a navigation bar, place it at its final location. - CGRect navigationBarFrame = self.navigationController.navigationBar.frame; - - if (animated) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDelegate:self]; - [UIView setAnimationDidStopSelector:(isVisible - ? @selector(didShowChrome) - : @selector(didHideChrome))]; - - // Ensure that the animation matches the status bar's. - [UIView setAnimationDuration:NIStatusBarAnimationDuration()]; - [UIView setAnimationCurve:NIStatusBarAnimationCurve()]; - } - - if (isStatusBarAppearanceSupported) { - _prefersStatusBarHidden = !isVisible; - [self setNeedsStatusBarAppearanceUpdate]; - } - - if (nil != self.navigationController.navigationBar) { - if (isVisible) { - [UIView setAnimationsEnabled:NO]; - [self.navigationController setNavigationBarHidden:NO animated:NO]; - navigationBarFrame.origin.y = 0; - self.navigationController.navigationBar.frame = navigationBarFrame; - self.navigationController.navigationBar.alpha = 0; - [UIView setAnimationsEnabled:YES]; - - navigationBarFrame.origin.y = NIStatusBarHeight(); - - } else { - navigationBarFrame.origin.y = 0; - } - } - - if (self.toolbarIsTranslucent) { - self.toolbar.frame = toolbarFrame; - } - if (nil != self.navigationController.navigationBar) { - self.navigationController.navigationBar.frame = navigationBarFrame; - self.navigationController.navigationBar.alpha = (isVisible ? 1 : 0); - } - - if (animated) { - _isAnimatingChrome = YES; - [UIView commitAnimations]; - - } else if (!isVisible) { - [self didHideChrome]; - - } else if (isVisible) { - [self didShowChrome]; - } -} - -- (void)toggleChromeVisibility { - [self setChromeVisibility:(_isChromeHidden || _isAnimatingChrome) animated:YES]; -} - -#pragma mark - UIGestureRecognizer - - -- (void)didTap { - SEL selector = @selector(toggleChromeVisibility); - if (self.photoAlbumView.zoomingIsEnabled) { - // Cancel any previous delayed performs so that we don't stack them. - [NSObject cancelPreviousPerformRequestsWithTarget:self selector:selector object:nil]; - - // We need to delay taking action on the first tap in case a second tap comes in, causing - // a double-tap gesture to be recognized and the photo to be zoomed. - [self performSelector: selector - withObject: nil - afterDelay: 0.3]; - - } else { - // When zooming is disabled, double-tap-to-zoom is also disabled so we don't have to - // be as careful; just toggle the chrome immediately. - [self toggleChromeVisibility]; - } -} - -- (void)refreshChromeState { - self.previousButton.enabled = [self.photoAlbumView hasPrevious]; - self.nextButton.enabled = [self.photoAlbumView hasNext]; - - [self setChromeTitle]; -} - -- (void)setChromeTitle { - self.title = [NSString stringWithFormat:@"%zd of %zd", - (self.photoAlbumView.centerPageIndex + 1), - self.photoAlbumView.numberOfPages]; -} - -#pragma mark - NIPhotoAlbumScrollViewDelegate - - -- (void)pagingScrollViewDidScroll:(NIPagingScrollView *)pagingScrollView { - if (self.hidesChromeWhenScrolling) { - [self setChromeVisibility:NO animated:YES]; - } -} - -- (void)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView - didZoomIn: (BOOL)didZoomIn { - // This delegate method is called after a double-tap gesture, so cancel any pending - // single-tap gestures. - [NSObject cancelPreviousPerformRequestsWithTarget: self - selector: @selector(toggleChromeVisibility) - object: nil]; -} - -- (void)pagingScrollViewDidChangePages:(NIPagingScrollView *)pagingScrollView { - // We animate the scrubber when the chrome won't disappear as a nice touch. - // We don't bother animating if the chrome disappears when scrolling because the user - // will barely see the animation happen. - [self.photoScrubberView setSelectedPhotoIndex: [pagingScrollView centerPageIndex] - animated: !self.hidesChromeWhenScrolling]; - - [self refreshChromeState]; -} - -#pragma mark - NIPhotoScrubberViewDelegate - - -- (void)photoScrubberViewDidChangeSelection:(NIPhotoScrubberView *)photoScrubberView { - [self.photoAlbumView moveToPageAtIndex:photoScrubberView.selectedPhotoIndex animated:NO]; - - [self refreshChromeState]; -} - -#pragma mark - Actions - - -- (void)didTapNextButton { - [self.photoAlbumView moveToNextAnimated:self.animateMovingToNextAndPreviousPhotos]; - - [self refreshChromeState]; -} - -- (void)didTapPreviousButton { - [self.photoAlbumView moveToPreviousAnimated:self.animateMovingToNextAndPreviousPhotos]; - - [self refreshChromeState]; -} - -#pragma mark - Public - - -- (void)settoolbarIsTranslucent:(BOOL)enabled { - _toolbarIsTranslucent = enabled; - - self.toolbar.translucent = enabled; -} - -- (void)setHidesChromeWhenScrolling:(BOOL)hidesToolbar { - _hidesChromeWhenScrolling = hidesToolbar; - - if (hidesToolbar) { - [self addTapGestureToView]; - - } else { - [_tapGesture setEnabled:_chromeCanBeHidden]; - } -} - -- (void)setChromeCanBeHidden:(BOOL)canBeHidden { - _chromeCanBeHidden = canBeHidden; - - if (canBeHidden) { - [self addTapGestureToView]; - - } else { - self.hidesChromeWhenScrolling = NO; - - if ([self isViewLoaded]) { - // Ensure that the chrome is visible. - [self setChromeVisibility:YES animated:NO]; - } - } -} - -- (void)setScrubberIsEnabled:(BOOL)enabled { - if (_scrubberIsEnabled != enabled) { - _scrubberIsEnabled = enabled; - - if ([self isViewLoaded]) { - [self updateToolbarItems]; - } - } -} - -@end diff --git a/Pods/Nimbus/src/photos/src/NimbusPhotos.h b/Pods/Nimbus/src/photos/src/NimbusPhotos.h deleted file mode 100644 index 37569ac..0000000 --- a/Pods/Nimbus/src/photos/src/NimbusPhotos.h +++ /dev/null @@ -1,122 +0,0 @@ -// -// Copyright 2011-2014 NimbusKit -// -// 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. -// - -/** - * @defgroup NimbusPhotos Nimbus Photos - * @{ - * - *
- * - * Photo viewers are a common, non-trivial feature in many types of iOS apps ranging from - * simple photo viewers to apps that fetch photos from an API. The Nimbus photo album viewer - * is designed to consume minimal amounts of memory and encourage the use of threads to provide - * a high quality user experience that doesn't include any blocking of the UI while images - * are loaded from disk or the network. The photo viewer pre-caches images in an album to either - * side of the current image so that the user will ideally always have a high-quality - * photo experience. - * - *

Adding the Photos Feature to Your Application

- * - * The Nimbus Photos feature uses a small number of custom photos that are stored in the - * NimbusPhotos bundle. You must add this bundle to your application, ensuring that you select - * the "Create Folder References" option and that the bundle is copied in the - * "Copy Bundle Resources" phase. - * - * The bundle can be found at src/photos/resources/NimbusPhotos.bundle. - * - * - *

Feature Breakdown

- * - * NIPhotoAlbumScrollView - A paged scroll view that implements a data source similar to that - * of UITableView. This scroll view consumes minimal amounts of memory and is built to be fast - * and responsive. - * - * NIPhotoScrollView - A single page within the NIPhotoAlbumScrollView. This view implements - * the zooming and rotation functionality for a photo. - * - * NIPhotoScrubberView - A scrubber view for skimming through a set of photos. This view - * made its debut by Apple on the iPad in Photos.app. Nimbus' implementation of this view - * is built to be responsive and consume little memory. - * - * NIToolbarPhotoViewController - A skeleton implementation of a view controller that includes - * multiple configurable properties. This controller will show a scrubber on the iPad and - * next/previous arrows on the iPhone. It also provides support for hiding and showing the - * app's chrome. If you wish to use this controller you must simply implement the data source - * for the photo album. NetworkPhotoAlbum in the examples/photos directory demos building - * a data source that fetches its information from the network. - * - * - *

Architecture

- * - * The architectural design of the photo album view takes inspiration from UITableView. Images - * are requested only when they might become visible and are released when they become - * inaccessible again. Each page of the photo album view is a recycled NIPhotoScrollView. - * These page views handle zooming and panning within a given photo. The photo album view - * NIPhotoAlbumScrollView contains a paging scroll view of these page views and provides - * interfaces for maintaining the orientation during rotations. - * - * The view controller NIToolbarPhotoViewController is provided as a basic implementation of - * functionality that is expected from a photo viewer. This includes: a toolbar with next and - * previous arrows; auto-rotation support; and toggling the chrome. - * - *

NIPhotoAlbumScrollView

- * - * NIPhotoAlbumScrollView is the meat of the Nimbus photo viewer's functionality. Contained - * within this view are pages of NIPhotoScrollView views. In your view controller you are - * expected to implement the NIPhotoAlbumScrollViewDataSource in order to provide the photo - * album view with the necessary information for presenting an album. - * - * - *

Example Applications

- * - *

Network Photo Albums

- * - * View the README on GitHub - * - * This sample application demos the use of the multiple photo APIs to fetch photos from public - * photo album and display them in high-definition on the iPad and iPhone. - * - * The following APIs are currently demoed: - * - * - Facebook Graph API - * - Dribbble Shots - * - * Sample location: examples/photos/NetworkPhotoAlbums - * - * - *

Screenshots

- * - * @image html photos-iphone-example1.png "Screenshot of a basic photo album on the iPhone." - * - * Image source: flickr.com/photos/janekm/360669001 - */ - -/**@}*/ - -#import -#import - -#import "NIPhotoAlbumScrollView.h" -#import "NIPhotoAlbumScrollViewDataSource.h" -#import "NIPhotoAlbumScrollViewDelegate.h" -#import "NIPhotoScrollView.h" -#import "NIPhotoScrollViewDelegate.h" -#import "NIPhotoScrollViewPhotoSize.h" -#import "NIPhotoScrubberView.h" -#import "NIToolbarPhotoViewController.h" - -#import "NimbusPagingScrollView.h" -#import "NimbusCore.h" diff --git a/Pods/WebBrowser/LICENSE.md b/Pods/WebBrowser/LICENSE.md deleted file mode 100755 index 5e85bbc..0000000 --- a/Pods/WebBrowser/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Teambition - -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. \ No newline at end of file diff --git a/Pods/WebBrowser/README.md b/Pods/WebBrowser/README.md deleted file mode 100644 index ddda9da..0000000 --- a/Pods/WebBrowser/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# WebBrowser -A web browser using WebKit and written in Swift for iOS apps. - -![Example](Gif/WebBrowserExample.gif "WebBrowserExample") - -## How To Get Started -### Carthage -Specify "WebBrowser" in your ```Cartfile```: -```ogdl -github "teambition/WebBrowser" -``` - -### CocoaPods -Specify "WebBrowser" in your ```Podfile```: -```ruby -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' -use_frameworks! - -pod 'WebBrowser' -``` - -### Usage -#### Initialization -```swift -let webBrowserViewController = WebBrowserViewController() -// assign delegate -webBrowserViewController.delegate = self - -webBrowserViewController.language = .english -webBrowserViewController.tintColor = ... -webBrowserViewController.barTintColor = ... -webBrowserViewController.isToolbarHidden = false -webBrowserViewController.isShowActionBarButton = true -webBrowserViewController.toolbarItemSpace = 50 -webBrowserViewController.isShowURLInNavigationBarWhenLoading = true -webBrowserViewController.isShowPageTitleInNavigationBar = true -webBrowserViewController.customApplicationActivities = ... - -webBrowserViewController.loadURLString("https://www.apple.com/cn/") -``` - -#### Pushing to the navigation stack -```swift -navigationController?.pushViewController(webBrowserViewController, animated: true) -``` - -#### Presenting modally -```swift -let navigationWebBrowser = WebBrowserViewController.rootNavigationWebBrowser(webBrowser: webBrowserViewController) -present(navigationWebBrowser, animated: true, completion: nil) -``` - -#### Implement the delegate -```swift -func webBrowser(_ webBrowser: WebBrowserViewController, didStartLoad url: URL?) { - // do something -} - -func webBrowser(_ webBrowser: WebBrowserViewController, didFinishLoad url: URL?) { - // do something -} - -func webBrowser(_ webBrowser: WebBrowserViewController, didFailLoad url: URL?, withError error: Error) { - // do something -} - -func webBrowserWillDismiss(_ webBrowser: WebBrowserViewController) { - // do something -} - -func webBrowserDidDismiss(_ webBrowser: WebBrowserViewController) { - // do something -} -``` - -## Minimum Requirement -iOS 8.0 - -## Localization -WebBrowser supports 5 languages: English, Simplified Chinese, Traditional Chinese, Korean, Japanese. You can set the language when initialization. - -## Release Notes -* [Release Notes](https://github.com/teambition/WebBrowser/releases) - -## License -WebBrowser is released under the MIT license. See [LICENSE](https://github.com/teambition/WebBrowser/blob/master/LICENSE.md) for details. - -## More Info -Have a question? Please [open an issue](https://github.com/teambition/WebBrowser/issues/new)! diff --git a/Pods/WebBrowser/WebBrowser/InternationalControl.swift b/Pods/WebBrowser/WebBrowser/InternationalControl.swift deleted file mode 100644 index a7a4b77..0000000 --- a/Pods/WebBrowser/WebBrowser/InternationalControl.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// InternationalControl.swift -// WebBrowser -// -// Created by Xin Hong on 16/4/27. -// Copyright © 2016年 Teambition. All rights reserved. -// - -import Foundation - -public enum WebBrowserLanguage { - case english - case simplifiedChinese - case traditionalChinese - case korean - case japanese - - internal var identifier: String { - switch self { - case .english: return "en" - case .simplifiedChinese: return "zh-Hans" - case .traditionalChinese: return "zh-Hant" - case .korean: return "ko" - case .japanese: return "ja" - } - } -} - -internal func LocalizedString(key: String, comment: String? = nil) -> String { - return InternationalControl.sharedControl.localizedString(key: key, comment: comment) -} - -internal struct InternationalControl { - internal static var sharedControl = InternationalControl() - internal var language: WebBrowserLanguage = .english - - internal func localizedString(key: String, comment: String? = nil) -> String { - guard let localizationPath = WebBrowser.localizationPath(forIdentifier: language.identifier) else { - return key - } - let bundle = Bundle(path: localizationPath) - return bundle?.localizedString(forKey: key, value: nil, table: "WebBrowser") ?? key - } -} diff --git a/Pods/WebBrowser/WebBrowser/NavigationBarAppearance.swift b/Pods/WebBrowser/WebBrowser/NavigationBarAppearance.swift deleted file mode 100644 index 29147b0..0000000 --- a/Pods/WebBrowser/WebBrowser/NavigationBarAppearance.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// NavigationBarAppearance.swift -// WebBrowser -// -// Created by Xin Hong on 16/4/30. -// Copyright © 2016年 Teambition. All rights reserved. -// - -import UIKit - -internal struct NavigationBarAppearance { - var isHidden = false - var tintColor = UIColor.blue - var barTintColor: UIColor? - var isTranslucent = true - var shadowImage: UIImage? - var backgroundImageForBarMetricsDefault: UIImage? - var backgroundImageForBarMetricsCompact: UIImage? - - init() { } - - init(navigationBar: UINavigationBar) { - tintColor = navigationBar.tintColor - barTintColor = navigationBar.barTintColor - isTranslucent = navigationBar.isTranslucent - shadowImage = navigationBar.shadowImage - backgroundImageForBarMetricsDefault = navigationBar.backgroundImage(for: .default) - backgroundImageForBarMetricsCompact = navigationBar.backgroundImage(for: .compact) - } - - func apply(to navigationBar: UINavigationBar) { - navigationBar.tintColor = tintColor - navigationBar.barTintColor = barTintColor - navigationBar.isTranslucent = isTranslucent - navigationBar.shadowImage = shadowImage - navigationBar.setBackgroundImage(backgroundImageForBarMetricsDefault, for: .default) - navigationBar.setBackgroundImage(backgroundImageForBarMetricsCompact, for: .compact) - } -} diff --git a/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/en.lproj/WebBrowser.strings b/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/en.lproj/WebBrowser.strings deleted file mode 100644 index a4808b4..0000000 --- a/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/en.lproj/WebBrowser.strings +++ /dev/null @@ -1,14 +0,0 @@ -/* - WebBrowser.strings - WebBrowser - - Created by Xin Hong on 16/4/27. - Copyright © 2016年 Teambition. All rights reserved. -*/ - -"Done" = "Done"; -"Cancel" = "Cancel"; -"Open" = "Open"; -"OpenExternalAppAlert.title" = "Leave this app?"; -"OpenExternalAppAlert.message" = "This web page is trying to open an outside app. Are you sure to open it?"; -"Open in Safari" = "Open in Safari"; diff --git a/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/ja.lproj/WebBrowser.strings b/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/ja.lproj/WebBrowser.strings deleted file mode 100644 index 2149d66..0000000 --- a/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/ja.lproj/WebBrowser.strings +++ /dev/null @@ -1,14 +0,0 @@ -/* - WebBrowser.strings - WebBrowser - - Created by Xin Hong on 16/4/27. - Copyright © 2016年 Teambition. All rights reserved. -*/ - -"Done" = "完了"; -"Cancel" = "キャンセル"; -"Open" = "開く"; -"OpenExternalAppAlert.title" = "離れるこの App?"; -"OpenExternalAppAlert.message" = "このページこのページしようとして開くもうひとつApp, 確定開く?"; -"Open in Safari" = "Safariで開く"; diff --git a/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/ko.lproj/WebBrowser.strings b/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/ko.lproj/WebBrowser.strings deleted file mode 100644 index b242bff..0000000 --- a/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/ko.lproj/WebBrowser.strings +++ /dev/null @@ -1,14 +0,0 @@ -/* - WebBrowser.strings - WebBrowser - - Created by Xin Hong on 16/4/27. - Copyright © 2016年 Teambition. All rights reserved. -*/ - -"Done" = "완료"; -"Cancel" = "취소"; -"Open" = "열기"; -"OpenExternalAppAlert.title" = "떠나다이 App?"; -"OpenExternalAppAlert.message" = "이 페이지 애쓰고 있다 열기 다른 App, 확정 열기?"; -"Open in Safari" = "Safari로 열기"; diff --git a/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/zh-Hans.lproj/WebBrowser.strings b/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/zh-Hans.lproj/WebBrowser.strings deleted file mode 100644 index 974f115..0000000 --- a/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/zh-Hans.lproj/WebBrowser.strings +++ /dev/null @@ -1,14 +0,0 @@ -/* - WebBrowser.strings - WebBrowser - - Created by Xin Hong on 16/4/27. - Copyright © 2016年 Teambition. All rights reserved. -*/ - -"Done" = "完成"; -"Cancel" = "取消"; -"Open" = "打开"; -"OpenExternalAppAlert.title" = "离开此应用?"; -"OpenExternalAppAlert.message" = "此页面正试图打开另一个应用,确定要打开吗?"; -"Open in Safari" = "在 Safari 中打开"; diff --git a/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/zh-Hant.lproj/WebBrowser.strings b/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/zh-Hant.lproj/WebBrowser.strings deleted file mode 100644 index 895c139..0000000 --- a/Pods/WebBrowser/WebBrowser/Resources/LocalizedStrings/zh-Hant.lproj/WebBrowser.strings +++ /dev/null @@ -1,14 +0,0 @@ -/* - WebBrowser.strings - WebBrowser - - Created by Xin Hong on 16/4/27. - Copyright © 2016年 Teambition. All rights reserved. -*/ - -"Done" = "完成"; -"Cancel" = "取消"; -"Open" = "打開"; -"OpenExternalAppAlert.title" = "離開此App?"; -"OpenExternalAppAlert.message" = "此頁面正試圖打開另一App,確定要打開嗎?"; -"Open in Safari" = "在 Safari 中打開"; diff --git a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/Contents.json b/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/Contents.json deleted file mode 100644 index da4a164..0000000 --- a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/Contents.json b/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/Contents.json deleted file mode 100644 index bb9f00b..0000000 --- a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "backIcon.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "backIcon@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "backIcon@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/backIcon.png b/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/backIcon.png deleted file mode 100644 index 57b919440168f3e296b3e9b39d508e5f48282401..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1254 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H1|*Mc$*~4fk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m{l@EB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxSU1_g&``n5OwZ87 z)XdCKN5ROz&`93^h|F{iO{`4Ktc=VRpg;*|TTx1yRgjAt)Gi>;Rw<*Tq`*pFzr4I$ zuiRKKzbIYb(9+TpWQLKEE>MMTab;dfVufyAu`f(~1RD^r68eAMwS&*t9 zlvO-#Aurx3; zGBh=W>2=9ZF3nBND}m`v0qS)#b9S{fbvD4M7nB%s3xGDeq!wkCrKY$Q<>xAZJ#CeV z+bxbb&4cPq!QvLEKb&yt)dxC89~8AnQ4JFUrXLU!o^XL2c+yYJ1E%*PV8WgzEby9v zfic3<#WAGf)|RXO+AN7O2R`03O`W5mcV&^s;{{X14JX-qK3U*n^z^{N#_I+uo}MSv z*b5gubCQ|T9JB13>xrXNejC01eWiH9+?(lY{qeQ8a?79HHa0%%voLJ6!tRu{)uY;)8$|a-NG53RDS+*+GMGtM-ChKhJN8GzOhl~wc6*E z83wF#k{GLRc--DF!?>o$RVHEY#kR^r?GeWW!$PIgdEY0qrvA))!SOzc_xXoSa`UwI zsGfhyI!)le>7Ab3oKsV~xW7$(uC=_?x=!XBr`_j!moguQ_dJrlE^$#*>~oXnPoEt} zH>}$*BfV##>#_Ed)}uCwGPyerF8~U;`z(k(#tsy^lgt%sbZ@zK&WX=9y?H54&t;ucLK6TW7s0&% diff --git a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/backIcon@2x.png b/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/backIcon@2x.png deleted file mode 100644 index 769cc3b07aabc203ee2cf7e9e3cfe145e3777536..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1604 zcmeAS@N?(olHy`uVBq!ia0vp^Iv~u!1|;QLq8NdcWQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2v2cW|hp4h>{3jAFJg2T)jk)8oi3#0-$aN1{?c|g2d$P)DnfH z)bz|eTc!8A_bVx6rr0WloBA5~7C5J7WO`H;r3P2|g(O#HCtIc{+1n}DR9FEG$W1Lt zRH(?!$t$+1uvG$^YXxM3g!Ppaz)DK8ZIvL7itr6kaLzAERWQ{v)=f4rG*mD%(=#+N zH8V5RQ7|$vG}1Q!A~Rh>6Dw0QDv55FG|-pw6wGYnPFt43sj+7T$xvrSfQI&tPC^3CAB!YD6^m>Ge1uOWMX1cerbuV z640d(FXR@$jm;~D1`{yA^eYkz^bPe4Kwg3=^!3HBG&dKny0|1L72#g21{a4^7NqJ2 zr55Lx79|5CE=?I^Re_arQEFmIeo;t%ehw@Y12XbU@{2R_3lyA#%@j0z6O%LZKmwXz z9lpL+o_WP3iFwJXo-VdZKr{3*GgGWwosA5g9L+3D4Gqi<4P8wv9F3e^j7(h&EDg+z z3{4GTdR_99OLJ56N?>|Z5PB_f>IEf++ybD@E~!PCWvMA{Mftf3U{70R;&zJ}PV=C8 zQ*gV*9H(A=pkwqwQHvDSFd<<20WskT7s!Dp{nR{QdM^Sd?2fN$Zy6Yvwt2cZhE&|T zGV{E5NTA5^_h(jI4QO^Y?S2(s5W8Az8|SivS#R1?CS8n(2xxO$bYYRk3w2l5fQ$T# z1THHqI^jBr-+AZzxxL?i z7VVs)x$M(yrPY&a{#nfQnN?zy`?`KTTcm+pubZ!iNKv`CFXwg@A> zIVHP&&oUPSi7kq|*-9F@Ht^YSvM?#GEv`^~!I14bjmcQ5_3#73{#C)#4=Nfg_pPuz zy-xh5X@SU}OW&fj+21Y*O4)wkVNEKx;vOCwCTW*4c9T!qzM+pJ4sDWl{l@U-eEK;t zuL{l6Zm!=1RK%2CPc`U$6C0pvRQ2Ah;bzmeH1SZjca1;fH|@?jaZ4_7(q7(eoo^&> zBzs?5R-n0qGt2ecB=@qY+n**ayUH7&z9}z&dD*|$pFZi^&#<}{H}Px3+k~LoO!MCD zJ>Z`b8wjly^OLb?7wICoX^-E#J~cBfa{OkZFY%|EYe&8+J? zySK_M3D|v?cV73Jw%f%kuT7TE+HHN1d*ank-_#cb-jK|Uday@Ga;@gNYSrB2kH!bz z?g&r0vTi-oe7D3^@Bj4G>26})bL~U6NZFFrJAJKP+f|-#%I5AM#es$=KSH?G( zCMj97`DKbO`^93`s5o(J)8wdDUj2?2jy2kw%*4VqeZDp>KR)9`MwZNVEuXJ_%a5-( zajqe4?V&!Cw;uPp-^`h5e=tNdry}ae&&HBhlV;j0f6EqGwus-bsOY(XTDeS z_(Y14*^>5%syXtfD$Hj8eR*=7rC9gO0*f5ysu@dPz9=;j>fEvKVtCH{yn1c}hAhpq UrY&nC+(G5Kr>mdKI;Vst04YCa_5c6? diff --git a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/backIcon@3x.png b/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/backIcon.imageset/backIcon@3x.png deleted file mode 100644 index 8df29fc9c8e2bc56913acd2f20beef1544a2ea7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1949 zcmaJ?dr%X19*+?(FXO_x;ZI z^Z7n!ehrx!sou0;8ihjfmZTwBq)c{x9`5A--*Ug2(}hYM#!)zZI0U9A(G*Ht0-;wZ%TXLCMoTr?c<@2r z=OCa_#e=zgDNm{wp=wQ9wE>k?XULV+<;oZpnDBcbju4Ur7>X+Z0^6-M3W<2|8LyB$ zJI!1Wc;%qBh9#wsnYAlOYu~Aere;C1Cm&v|8iyHjxeE5(+&R;_#d$tvO1izwL@) zFT9O-7W#9(ze;SBSLso17HZU07?kATN*K;idZEaGDsY`auG8&a>td!_hwF@LogNU$ z1OQ8_P-?VJ!?tG#sZ=P@8gYeIiAs=okmTTKG%BH31VhP5f=E8Zi-I6=WONcNLSR0^ zi{S}ih!3q{5uLIEL$&xCR`oNMzb@9f449sbjGzWhC8|m>=rG_}(L&Aoxxnl4J;$on z&n04AESF4%>m2PbM!jYt_s4mBvACr2V)aoix$g#Yv4>l4pQli$z7ix!PE0Pg<)_L2 z6gWH<{qaO-YtmNniGf%6z9*<9{pnANsP#6*Y3vor1kH^eU}YjLCEu0!Vky2DLKOp# zGi`}-n`jbN^O5k{FMNZqFpnW~W?7N#^gb_ErWm2LxldRN*wJ&A z`~i1Q?@<4;E1`~i|7(1hdN?ur!UWAT$y_ogRzRwyC49+%9jWNC=C`Xq9wC4HBv^1N=KK)wfyJ;*}X=Q(U2jcawZ7^$O z#=YsvOR>9HbnvSxG&KbuY9l_SQCY@4$waJ;&@W55Mr-F-0^6 zvTRCQy>&XG=RjD-!~%10Px`Iv7vF?-*7`sEyJYG%VOemitleszE`RT}kmx19tKaHOP8pxZ;hFZ7&UfLUl$XXW6x~}5iK*uf=%^x16@5IO4X$e zLmrP79jwhEIoVfZf0vN?xBK5A8$G%aM@Wau-U!>u>~z)#O&1LRjJ6kR=wA=>YHrke zJcueNq*psO7IIfZn@+=J={c=Eg_%pGL74S=?#Yp|@k={)PpYx`{DDtAyXRXGPkLm? zVgp$B)LMAX>`|D)zvc5Z(BQh-T--?mzdh@6tbN9DdzbqDJK`>jUqL`DbE)n?WkgR} z0NpH>|6y{R@P?%U^xo#}lD`NK1=V+1RBpzrpux}1S-RGQ+jA1$@w@G zR+o971tl4{PtS=8xb3sF(B6%!kqfXt=uK7IS-rLo^Kki3vZerXG-tQJj`Eilw!tiRFcV3thaR$

c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxSU1_g&``n5OwZ87 z)XdCKN5ROz&`93^h|F{iO{`4Ktc=VRpg;*|TTx1yRgjAt)Gi>;Rw<*Tq`*pFzr4I$ zuiRKKzbIYb(9+TpWQLKEE>MMTab;dfVufyAu`f(~1RD^r68eAMwS&*t9 zlvO-#Aurx3; zGBh=W>2=9ZF3nBND}m`vLFfgl!l4(G7;+1MHoK%2WtOF;xE1B+Du6w0m5IeIZf4G| zmZr{@K=aJ8y9J^*1&dptdL41<)dxC89~8AnQ4JFUrXLU!o^XL2c+yYJ1E%*PV8Wi} zd}2NW17oqLi(^Q|tu<43dmV8QX;YuAnkKHJ)TGJcDxkx1&~2l@)(=ctkGNI*m7Yk} zuz3fHykDT?wndPI+fjhi%xMD`=cJY&{d1hId6qGKK75>K^Woz+C$}sXbvC(5kHw3Ge#ZIrBr>^cdX^AY$L78oQ9S7rPTJShO ztaL6}k$Fp9Os|f0cfwwuHLrK=nemBlTIN&H^&6xzOMd?4)oJA4z%LfsDY>=zbfq!> z!6q%k^V}!*d)Te^I`i4b_IdtE!x@39&ng$4+J8`RMi7w2@>zj-c|z3G87pfl>Ww+q zy;%L!cE5OR*0m{q4aOIo-+ytwdDQAr;j7Hq`ws11b$Zhy!&O`QmzZl+*?3*5+rXxm zs`WDLBZnvZK`o2vZ={3jAFJg2T)jk)8oi3#0-$aN1{?c|g2d$P)DnfH z)bz|eTc!8A_bVx6rr0WloBA5~7C5J7WO`H;r3P2|g(O#HCtIc{+1n}DR9FEG$W1Lt zRH(?!$t$+1uvG$^YXxM3g!Ppaz)DK8ZIvL7itr6kaLzAERWQ{v)=f4rG*mD%(=#+N zH8V5RQ7|$vG}1Q!A~Rh>6Dw0QDv55FG|-pw6wGYnPFt43sj+7T$xvrSfQI&tPC^3CAB!YD6^m>Ge1uOWMX1cerbuV z640d(FXR@$jm;~D1`{yA^eYkz^bPe4Kwg3=^!3HBG&dKny0|1L72#g21{a4^7NqJ2 zr55Lx79|5CE=?I^Re_arQEFmIeo;t%ehw@Y12XbU@{2R_3lyA#%@j0z6O%LZKmwXz z9lpL+o_WP3iFwJXo-VdZKr{3*GgGYG%$!{|Z5PB_e>IEf++ybD@E~!PCWvMA{Mftf3U{70R;&zKEPV=C8 zQ*gV*45wawpkwqwQHvDSFd<<20WskT7s!Dp{nR{QdM^Sd>^mK1rx+NRmU+53hE&|T zGSlBfq)_B|`kifjVmgXD*hQJl-=ti0UEwTi<>Dfi7O9jZ!IJ67)tMXkg+F8kPgB(5 zB_`UFI$m5@7@@Q)rE)Sy)0Yj7Cz?uEq(<%czsEn1`QW*8JvRG4B!2&UBi7FD{-3lN z8$bWtvvtmY!j5#=8_v5F-6FpLlPX}ooEDm@bzT-mS2c4dtX1|1I zE0}CpO}$GmOcnVkJL_&)E2qcy=uD{Kk4?LFkN2{8h1+&L6N^duYn(2Xj_r zSDe${$`!2F;Js+w)0yioY57<(uj{H3_72YwUH0We%T$dw1sO)$s0=(i2k)hG$!3O9ZFo3TNk6=serb_bj$e$~EnbaBEb);G-e580H8Sqm+%aG$Vg_s`I~ zPgC2yziFS(d9mqe$&6>8+g7Ak%%2-n$@t#loco?VPm5+*Tfh8$uDe}5a-Nk;_tAaF z9~W9l&Nv{!w}@3Lsk!beZnN0;%7nWn@wFftTMPkWjYbLuas9QSnfb6Mw<&;$Ut CN?+pu diff --git a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/forwardIcon.imageset/forwardIcon@3x.png b/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/forwardIcon.imageset/forwardIcon@3x.png deleted file mode 100644 index 9e251f30fa3f15d1daa6d065a24d7834664e1c5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1953 zcmaJ?eNyta=Hsy`coMn+x2R1pAkv{47?c~;nXnR8 z>vG;Y4@UyPtR)6j3Z9}^4QWv$Q|*jlT8$Wi27t&YE2h?NgmF*y2C-Nci-lpqG2qn8e?&oY-dT+feOX{hZ>E~qs_Py z{zvbB5}Q>y7|c?_W;ENRB@S-GVrME05}RN(j+#^`nl;_UL_Lb5W<835;v_z}Orh2q z5T_&P2|}TO zoN25C)n*%E1fRz0{=tULh;+~YvIm_ zWf5Xn&ZGU;QBS*w`EhQa4=!OmAAJ}h=G{aLc4+IR9snTu$R#3`b@11!*JY|T^Ujuj zUuN{%h_NPN-24EVMASAUD8>{&|3i)E?j7+uMe7)5j?Wn5gkE8@L7^& zzIP@$woR$UJ-4d1l)kw&`n#f@w!&*b{(ZZP>pD_q%3xi`tr3^BfVcrS4a>G(-&4@j z@krq!s^t2g4C>s_R*vnbfU=3vK&+A4z4h}EU!Uk*ej{fbX#xBX%+d_P`l-#$krzj# zM8@Il2G>3>(ioSv)>!d}&iZ2OWda=U;6D5ut15G>+t&D7a9;A6nnTCKC4D|C&kc89 z|2A&QqcFG2KmKjjL!cj&ZUK`Wdd<7N3s&lAC0_sqIA5B6dyfB2<&R`)m#X4%lBlFp z_IuZxb8`;QdjRUke?FKf%PZ{v?3}o^Wx_jbey|T{+tz>8O=O`Sx2;&ResD8ZpN7Qj z+}9!exb)L+tCzlUV^d9H9Q9cFl+3ZTm9p|qr#w6OsJZ1}LUYq&<&7(TUMS(0 zzEIyj9_`bZm+)aKjoO>WyTXu8PE077htuxtT3mPUmsNwA&FhahZL#x;>r*{s)Kz8i z9$%*y7T;}I5YoBKKkMC&doO6*mr5xyL1Mk-enG3OLX@tZx4d&_n|*W`$tW8FU2Q8o zX&RMeZYA5x{}BDpV}ax*$CvHhhsQ16?QYgGYVE2oFV$~fb7&D~znw&h34B0$HK4^s z6LPD_GeC+}+>eYo6I#rPgi2@{TC%S4q+;)TJCi`EV}CyB<8|jtCnL*;1IS_St6$Pg z?h4NcCnrpjm+#T{{GtoklpMRLOF!o{LKU}UUG&v7J;=WTo?51WX~pUT^Ntmz;Nh!f zhLCTfvqplNlY6Vpj8*2VZUqe;Q2dbBMM{l|wu=Em5VWY_oJY`+Px)v`IukRA>e5nOlffRTRg)Oj=4MNs(hIT3Ix`WJzI}nBmks=s-@Pn4?{s%3FD< zAk=yYj2^n;Ls1c!VFit&hBu1r0#TY~YEkBBUJD_p=z=-@{`GBH9rpR=eCO=*HN;u) zRHe>DT$b8cAvM?wP(h1wDW_;$cyI8v*~I=lm2TC|!U!Zw%-gP~H< zPM8N@z`HO4x}01CCCmdr$}@TAW~r$Nu~l;xtT z$E&vS`MG#6?^I`4J4QiLXZkwGRW8K48j7ykGIX^$wtNo0buV9Q+PI#y&UCI5zlsLt zn?_wy=Xf2Q>l6XM+TuUJ10J7?(XH_4gQzsSd!bj1w}I&U#FV8`>&5jNbif+$-R){m z$7?tQmyhtM>!cc@C#klp2D=Z=f;hR0f=zLSY4tZzQBm19%V~Z3>gn!&1vF6c2V4#1 zq$h=Xrw0vSFX3>OY4r?~4wbwSM+d+SR^R)}IJbRx5IemKf{0dCLBmGFd&nz*O@gd) zIu4!(J5Z%tV;nc5*MnxdDZiNXev{9X97XLd9uEp$D$63eTG}Bx*uChqy?vsstGhTV z+SXS@m1*)zsk9_b#WHpDLVFHQKyVsUatG=@UAy z8tkiZ9NZw?_ZxIJ@{+AcF2j09MKxlKe?@<)Dbu@FRMI)UvyZ|`klY6L{QgG%aup;L z{bEud&NlXXoE$Ux)JZ#Fop}Wt(VWm@4R-ItSD-7%iLN%cx_3Ke!tV_1)Q6{yeXs#* zODk}tl_#k93uwz(xtYw*p!aeJ3AUxP1g%C!qE(z~Mx^_7c}f2Q-%vj|f(0%84sC); zMZ4lh&@0M`I&}aJL4#8U`cA{o%boesne0sVU{KeYQKVc!?oH5fm;-%b8R**3j?wme z8$!yZI8$FUiyjJFJzg}Z(H^~2T2-yCR(T|R4T_+*LRJ}rgI*pdU!tod(tBL|qta{W zdl+OaW|D4&Ta3;nbzXIDRkjp#_pXHj5JINlqz&#c&MqOn&*U>FU&O;~T$LWwAyi^4(P7c>YjkjFa+|J8XC}c*3k=sb83@Lg>#+`pfe_e4wf|ak+ z`ZvhJNWoR)b#5O8ZLiRB9uC(*t;g{r=$3o*!Bo0tj(|Ha{YmR?y%O>i-4IVk8n}V{ zVHg(L0q^R)c-aDXRUQMT3fxqdX03C8m4yQcZ@& zn6ei1ioQ|N>T4TUeP!c1qSsE+^E?UL2~kHe`9A2EK-|Q}RLfVb7nOb;?T2Ov@#yG@ zA3aMC!V1v!)a68X@_VoY=7FxUN@W-obl2;wZi3+uOu7g2^lwLF$u_}wI0kK?0ccw~ z)V3ZIjylq^SLBzy{@}M6f=XTkww=_fH-J{#4Nl(Px gF$2X6{10c~FUwg7n1~Ueb^rhX07*qoM6N<$f?gNnx&QzG diff --git a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon@2x.png b/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon@2x.png deleted file mode 100644 index 141fa5889f112a8c8f185b6647e16ab9a0f16ee0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3691 zcmbW41zQse!-hd(^oY@2g0zTqC>=UFBnQ$tx@#j;ghPii;*64Vhpv(5c%*AELSo{m zQ4)f{;5*-6c(41qpZhmFZ_U64^fX*FBqSvCMuxf;|269WrK0?ARooTl{tIcSg@HCn z^Ayh>2?>L!k?wP=DAGd&^@-Cw@4r4UE4QFG9zwqaJlfjxZP?y_63w?UHy^937O$pj z%C9L5w5qjguUGJveqH}5Ur<~xAb{F!yga*(8N+5WpP(5tJ#n_Zc6o%pzqvc^FFHf~ z?%7#uB^Jg`{YHcyYq2><3E2z$PgJl=qoRP1o>Dm}!niR|r@8SFk4@B%YnSHFqHzeq z_(`y`Bn~+mE{JV5P*Ss7R!ZH%kt?(9f0eJ84@y=Ni!1iC{ga#bfNG8Z2w<@Iib$O> zo#LvXsedhMr{=b>3=n+3kE_C_cc^h?CHoEAD-X-QT(bShG>^A~P=8QiT&G94k(CR^ zGhvn+hFU7%ho-et@XCSIs-RStBz_nZv2BoXpP%6dB6liTC7V*7mh~k<$KZ%0yu&Xd zd*s!35@inkA8kolYE)CHLlwZBGV<`4T1Z6%RU9*Aw`blut-gC(Qu4eDL~b*_>N1J! zvHjjd7E1FmkD&|AuhC?C7ZBZd6oudKfVfyQqz1r=FqSeOPy&1xz)R^x@-Lf2@qpKUACg4Irgmt@+; zhn}zhB~luV!BcbzJ5~jAt@zRXcIc9tfK`H4)J%qYRJr4L!y30ZgWriBO_`ketx)jUlM)Koh7T=-GrXc&ib@26+ z-a(R4dZ*{96b%wfaU!h3g&I)z>q9P@ z?~2R3n>PDNUzaBTo+eqnlLE9Y=hfaY6!w6zOC|;Q4k!c8m4BeU;m4?h0+Nl zBgogTioXX00%ITWZ4kNlH%DT$k^aVUZ{4OyE|gQbSH71+b>lrdiHdFsB=s|R>6A$6 z$zCVlS$BgL+iEOf(*>7HF9OYo62?4K(n*Yzo_Zd_8co-s8l#>g4|Z8Qa0lu-!zdGx z5H6dCuVpZbV%4nm*ThN26OG*-KULbEh0zi7Bj37_AAu;=4rG$Y2F$Nh!m&NhG~@^- zv1ua=gyjLpEI+|LE~}2&A<#g+_(TNejHIRkN;Ox1(h9XB9bNn2Z&k7W%;r_jRL$_F z-RH<*QHYJQwHm@9^0Ki&)#+%23X)PcQ%-1;3)oMzT|of+5QG)AmS>4ycsgE}&asjf zAx)Ey)6i*nvt3)%;$JoN3>inq8lti4KA}O)1!=1=6|-tF8~eH2;X}iM3I{ZNdSc@n zz?UOvX&XLsRo$Y@F$y|AM$N&tQJeDlM9#)Y-z%cmDdmp$XLEDxp;twK=i5Q<_QwL3 zN2V!ZT1&JXe=xVYLOqEKyU`c9AbOM4^V}6lbjjnkI@0YCeKFeW?&7gRB@C)`d0mS(%sbwwQo zJ@3?SRGT5I0S%r}_dHfzrZwjw&vK7H;6cvq=0{4ld=^(VwK+O|$CDKk0>!L>yaRN{ zsU3N2!KN=x?}yqgmUw(X-(>IRAv5i~eO&#tYm&Bjqi`#Y2Y!g+!i2IAVTjF(%8K#D z)e|Muaxc`N!{aa()JPY{Qe~$9@f8FTBB8Emf>SIEX8SD@wq_FQeHd?WNnQ-tj}|)b zQ>AUL%#K(6E(zBXe5-wE&H2`z_B$3V-SbW>cAa0JwklFzkQ(L-f=W-F0+C|MdD94p)VQtPT?k_cmXpR(l8i zGpmpYP$y$s{t%xL(>av1( ztZo?UNsI@&ec(0BUbFGnBaDT4ImC`Gb%|NfJjpiqd@`Gs>odq+8o}&y*>|@kjdN}w z{LDWTQLG8|h^x!fPU+uxk@B;zou>F5<52RvVXUqMPmZfq`mMh0fDc1>BbK^L!=j^B zZ8kcfoR3TVjitS?xAD3QB~`-D3n7>(LI{)J#kHIAHE$ZJScgjb`>mNOX&} z!U}kApR5zOX&YZYC7x-<36OMbeYC=KpxIW|oadnppGX@@O7HakMzu=z-fW$Kwa4rQ zb?_f7thy5O^(CL^NxIa+rTB%glbem>pn8h5ykkIMWmXWhKE;^gl_`Xiz8#z{73MZK zAg@m6&~%)DVdFCYn;XH=ZghoJeHidC>6YHIwnH=_VL- z1DsMKpES&Y-pD;~5S&WS++4r?7b-|M6>hxFX2Ypvpp4h}lSVu3$%Z7rtoR8FnKyaS zn`*A}!`#QTl>f${89VHekLH5Ey(1qZ^rN?y=%_*4Ii$Jnw%63cA)0&U;Y69CAg?@> zqU5UMQWjcivV-FOPiwq0Qo3o!-wK{4JZK%VIOz~4EwO7=fE}e2Zs!;Qx&S}$M^WrW zAi%R>du9NS%K#e>s79_hW<4PPtIySX75|MYvPM?R@ru%s1peAZXbl|g-7l^D&Sn9Z z+tKEXn%!clq+@7-fKtO|s9({Dc}(qal}6I~kV)h2ZX!5N`+CrJtTv?kDxA%Q=EZ)G zY8e3TQd$E445vr7emvh659Pfj3;TE~rOxG<>>yB3cvj&c5-d(P4v+pkqys5{(hT>J zXxu9@@&e~kBAl{1;hZHlbu5?RWqxU}fIOkWWTU&6j+ZHL%dv%xUnfG!vx7cTj=bRX zU+hubKGXOCZ5{z9YY{mSR9viFEoLLtLp_oZI-IhXQkHtk_d!tgUzX$mdUP3IsNpj2woBvM|{Z8fvUPdIVM;xX`}s+p`@7WLo$yK^mzt z8}X5Nm&F?eK>DIHqGj?}l*5rTtbRwv+Gc`j0lRIoe#rg@YJM^lkC*H)+|_H%>6QYK%LuZz_ViiuwM^4^*p zN$0g90wwss&5kiW9%3hV_uZCad%GS_>|@pO?*-tYJ2}ngF;+-yt)bfF_CHh-eKZT* z4q@>w2DK}zEJM@L_u#YpM&n;+M$rXm=4SF<3Ks*j*W|+Y>cz&c7Z*`21Qa!MFCy4V zF(bwauAXW!`+EldJ}@O+F1oZ&7{BnFzU$$EaUB0A>tO-6ZV-KcQGUtPQ$li_u_f;S zZ>fL9GToFNZe(EVBWq(!*-dY31-QRH8O74QLkrX4{t-@SVquK4V8O-HDw6r;aYL}= zHeXj5{emx9>$D9P^6fsJhtFW+Gni{C8aw1joVsm68^Y#e7fWP}aMU3LtA*ap1^~?M zc6`%=QMD&8+swN=H#v!Hi~QzlQMnzjP%8=F~EKWGF{@?MtT+c6Ln+$|wuW!D$&HV0{84#n0$-_AHH# zxUKt&)OQF1FO_$(1!KxbQ`Z*(gJchXnu}?@m(lnWBM=XjT#^9=L-}4sRGgfdIc*R9 zlzTwiNPP^$eTqce^A%=p%x~&>C>h5#44PD)nqd8p^)PmWk50m_7%+xq3r9ew&kZ!4 zrUuU<$;WOVo~y^?P}j^nRk}3}p~OH=pYNuV5!W*2bbU@-6|@t0C{;8f!W~$1W*^*` zA8~TfU2*KeD*-$R*!Y(ml(Wp%n>P>GycH~NCDTnde?bLmhKJ6#uxtbHqty{I+kZ+Z ze)h0{r*DQ=D`Mv$?!pV7X7*Yp_GUFcuW}=#;O`&MIvu4XB<{-$`)NDsr58Pa&5rMr`m!T^ z0CokVRaBA<<-xMLa>~KVNrS*w?wpwse`W?oLYpQr9vZubbYUsn9I3PWU&DLCMbgcQ s@;*qM+&;f35%m5I+y6>kBgGwn`+6w@PYaa(?>&+j>49~dwIQ(o0~B5c>;M1& diff --git a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon@2x~iPad.png b/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon@2x~iPad.png deleted file mode 100644 index 558cc45ac93c431a1988af52312f5fbc3cb28a59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5053 zcmcJT=Q|q?)Q0V-P0iR8u~(#Rv^Ehl_8wI#)ZVSyHLIxDt3>TsA!-XXN~=a}MO#r~ z)o9C)mbdT!@V+0;xv%HCp6h%(AMR9y35<~rNJmCS#t7HfG5^Pc{~cPIf17(qNcbPf zgUw-DWKEy=NMvL;!{IubmJ#F!rGO)=5spz=Ax@!qCstOSnI(=^t{mHkyd1m}ONQxg z!iu6Iz`53P@z#8^1X&aC4IrbQrtaL5?!!t$WvP^MH{`BByr8FqG+Ji>YUjpv9Vg61A&8TnMKCtmr>|4r23qv6c7sKbZmjdX-+GEY;t zH^g2C`8xA_KZz8H0Hg!xW4XAIj{vCCecCYc;@Dpr5?MK@AIOJvS#5n3Wn@#a@)`uV zxzef5QZ`6Bd6$xCc|Wd+dVHHb0EQ7eKgjSg1gPNuHsgaeK0&ZKi~6<^UNnH!l$r?k zI}{k}uc^^vxVQLKjmiv7i#3Ta4%6A~-yXrH`H}2kjHxrhSFCV&L_M!Ox|f(v{!+n{ z%-9SlIdLq$7|qN?#;?)n?g3O||4c>H-+H?9wt8w)v*1;hn=^1cRxexF6#|MWC_}=9uJz0PFDpli11g~q?UMAuWmG8w-kNiXDBC{k z7s_PTm0o!_$cx9pEiND74NJLgQ={7{f(7F#cKY__Vj6p9J_y5#$v=+zzrSWe9)GJ! zV%RrYl{;SP?IoLgOdUoYRSMV@J|Gdjg|?Mok@>xDx8)_3%WVzfnhk%8{yEGGQrDa` zuEEo5CYtv*TO_sOON_=45;dP;7Po6SzCFa#US_E8go;x43`wT@+De z;t3qD!MtliuD45d;xO!E+Oz8|pZeyjE8Ws!dfjl-TrqWeW*~7fW!aiwvqw$2a#Km^ zhr~6i026{PTfb5t!}!n72DEG=jaH>T*j2Jx__C`rrE~Sg+I`-BfwYc#@k2BGaD8E# zy?YUSsiJ=}DiPW;Npi^u1n7&b%yx1VprZ7n8*VW|ESyT$qNsJsn9wmdX0s^0bbO`q zQl;Vi`<&1`CSWNc>xI{FiIM!9YJ|M3LW{&1cp?Q%eHzr!uH$mwh;rpSlD};RSIZSn zH8(Tm`K78L%BCROQ&yb4MXY&MprFP{5F+NI|xer4vc+H#sAy`2|HRGAZgq&?-grQC^ zV2CdgseSA%#8zx(J-9PK<_pJcP>`n$Tu}}mY`cn1TVjo|%djk1S6L zVHm2)kDuu-89b3+TvfFH#Af9vVZq`+eB~3fe@Rw=+OY^|)O(lK`GmFhYSC32fqWH= z?93ZXV_cvK)Hz5e^M;vp+yP~W;0sja?&g^v%r?`b)53nsE<{OrZ}sM?b0xlPKV_5h zH-X%Fpla99&qZep7)4d(cHA1;jqW3qh5eYyO_xbZf^OeLg>d zC^LTE3Tp>wALmk7{GRQ^6!n@05Iqxp57DzCVh?23lN)6d^`9ED&Hb2FTB|nmb>!cz zgzV5({e#VtD-$Q8pNYIo=K9l{x{fOwT3fH!e3e0twGi*Z1Sbp1P4=@D%X^8>_JBXl z&cp$;m9MIs4T|kL1|wtx(lfnD10d9>NG;pqh5g9IeYAO8uTx~3d)D`B^np!c6er!R zJavbl2Xm)+z5i%;tbM8;;#WmKY@r_Y6xX9W&cYKM-3OhtRd+yV_POWs)&E(E4xPT% zyFd&CovZ9lyG(W?_=L6D{X-acbOB#<*+y=2QSi^?sG8w6yh^!f0=xPuQCbC#2GZ>v zlYKRmGUt+Kzk~#+qBPcPW{q3ES|KK1Njb&joxtP$e6@G>%?V}wh#NuJ8#%88HZ|lt znA;&DnanM&7Kbmm9qjrHqsey2PHsJ|`$XwN-ge*ULUBtq;SN?Rcdn+9X+XG{O9gqo zPcc#8*Y(HQ=v^Pf^t}z%=dTXgfi#aO=l}Bg(3}YImJ{jm0`^Om^7HG8jB|!QpD>ez z7x*IK)mh8~Xc-UIq&kh1qD=#ODP>RMqx?DYJn2g20~;uuX}aB=S;nA#-ow$$bOfg9 z!s7X~RQEnfsw`Lx*y_`5C><~48RupxL?5(S`nYQdTdF2uw;vq|-= zU5i@bX~)_xvIue20d30O_0)*Ux3uiM#p`|VxAm@KtIZvywfT2A;R~Y$Gk5``63fcV z!}6I~Mrxz$VBSWfoU7MTlFsdIW2lzL&f}0sg}~Vt=q$TUENAkX!)CO(@A~h7q?#4) zO(0=nUy)_3aAGeVT`Du8ItzpLQv?aG^eCAFwzM|$a_79QHCvW*Zp|Yrq8enz89}1O zYLs0|U)HMh|k@vPu%Va`%s%fUl$rzd4#238y{ni61qFsI{4l+TPm86l zap=kNqS=Mr32%beCmhIb#3`AgvA#{}Fc|BZZ{;+wXm}|J43dbsmR7&skF5uW`gWgZ zJ*&ySxUcWKH*%N^KgB-r0(`g0+n)?^lWq-LgrDOv%AiZkUKfB zPj`g`QTH(hwJg>n|9Iu@dATeIWbsOP5${s8w||R_zXT)zG#(@52EGm{Z*lD%T}E95 z_y+boTmNe&>_0V8=9DP1+~qDxAnw;%nxSx=7m6*no#GB59ER5YOZgwt<}v-V1982> zPPG>a$hq9Bx|p8DS<55sAFRs1IhPz*Tc0|m$?M9WC1jZRub?9q{#!G*R$OYrZ*lTwnU7o$!_Y$j49Q4#7W0Zc)CHnR9D1ERmMerYdgnuZ-- zHq0G(VqTW6RMmD=`u3YdRM5juzi#~JXZ3!6=+_K>!X6s;cr`&}0>CY%+NQ+){M&g^ z_UuMhl3hijH&{=&v^m#bk`GZ;`mn3%CRMPMp+C`{)8?Jk$CQw+o`*m1`YODR5izji zDBznH)zAY>aV2OTqTPj=NMyy!*8B-+0f4Y2DS?l|r|$98Yi#^}k))!3>~fcwI;>d! zY(89JQB6v^275;KGFmtPQUUQ>%Ewm8f3)A${A!*%ZLfgDeq@R`WPeb!nyOV)rdw8? zNxeuW9wacr7q(%3x41-39?fNU>=%RZof&FOL$j`{q5nJ{VdEKy;JF|TMgi)h&aC`~ z^c*{xK2p}Ja{17qQ>uFl@g;hqq$U%}qTk@Z%Tb0Z#`S(>L{HG;hPBLbX{sI0Su$UR z;)9xG464p8ijUHSZrVt?ucq{*8D&%2A(SQq|7wO$v4Gaj#X{`;K|M8>bo-f1P)*u&=KmqN8dxKY*ZbaX~w6 zSq{O?e_6MP2JcX$31Nf7%SngI)3cZgEGq6!%FQ8!EN_sQ_mZ}ggofD2O}M+D)ZPK^ zsyf?+A6ef)oxDb9S0YQ<5iwxNSAEbP82G5{#?r7NaR>;UP3-VgjUr)=+!a1`J$k-- z4ja>$lzHpcdp@lN@(qh zIeRbCN}F;-N;0K)!*p`B()1!%(KD>}5A;rjxgRoLZ%f{X$~OK=O~pBsrQ!K4b{jyG z$i1-$Xaz`boatcxBc;;e-7HIX*dJbQyDie>=NH|{d6qSp#YLpbjg$s2S4jk@wKR&S zRyOe#`Y$%9X7&eBiz-pn5akXH*76djH92b>0xT8b|oYy;UuVObEU*CehgNLYxg4siyzq8H638G?ItA0Lc0fNvVJs`QeC!54--bL8Z@tyyMJ}}uL zO_Y@0;8s>5-q+RC{XWkMJ$00+L*YgvN>$SQU;eqTVey{d*2@GU^n7F+y7gLQAS?x{ zE15k!-V_kg(+PV1y!9b9U7w4RGYsm0LwI=}l0F()?AmFx!rM|yKI$D+2)|s6t~7qR z`Ck4e*7-pi=_c?pVF6B*jv_BV_vVba;X_trM|8JI$koo8E>!C9E-~%*svZsUi=Lz| zmJ+1N4kR^DUeL{R@t0~l!erO zP>gQ-er@1I*@OM`Dv z%ky%b3<^SJC4>drdxh1fPXcJ=nYJyRf~$YDgk;#$2imOsn9(e-ZRC9F-Z42jvu{y; z8!>ntE#zxGy>cjf`I7yx-0d|EGZw|27n2LQO zu%;HDS+6L?%a3)$O%wUYW;PA;x3ZHGd{ZbcAaWV|##NcI$Hz+l zb^4Bw2C_oI-d;bI%yC1Oj(H&yZ&Kg?Yw8~6&^6*c@SiwGMh=7yLHbtma+E>UZEHb(@{MsiGQE>&WUdKmpF4(bGtPTJdZ{a7wQT8 zxb-jLeJ=H!xia4-nYcr52Bg~fgs~up+u?8P(tht`PzzF=>CUou$sCzW&^(>VjCYKr zHE^L!juq2bf1^V8p*7^=<_frIBYH0Wxn9b882{iiiqFX>kbz7Zx{Nlt3zj1;jmnnC z2_47_a(NzCjpGRx1>R0(IB%9syo|tWp9JT{1Ow<}O#)}cI5*|NG|V&jw@1>RPm$Ub zg_B05j%OjXUg|YXRSl=AUBXjr3~y2Pmcc|Y}NmYFP7rCYjQx5 WxW@6HJk&oQM+Vn5(P`3hjsG9biIlbg diff --git a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon@3x.png b/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon@3x.png deleted file mode 100644 index ed4f87d7e59948647e82b7cbce1818fab37eb9de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6129 zcmchb)msye!^PRgMu$O-R1gUXk~f zX&4ON@B2^uF3$PfoabDh=foT6Y0^+aDM?63XtcG|jQ%6)|3wb@&lQFtV*df)Yow_{ zQa!@9MMA<K87hjpdsvkGGJ zdx!EHG8=)Tmwz{8&ITfrWK`b59k`guA^$T7^mV%kIC>Q6(&Qg0bc$fY9>n3K?L@&; zuXk^{<(76y7uK%a{(b39WQ!B;fsy(Jj6;n5L88z~$lYJjFqT7z4#N^%lyxY*GVLt{ z53nsTRuNrw0)J~^0T362<{Z5tipuhyI@~ULtH{#>v-@;sTOhK$tf$FAN)$>>5A7WTQHn5Q)R*aMVhDsXzmtuTpN}_}R6tas--&3_3h_c&2N14N{99-`OFk3+V%Bg?W z*1?Rk#W|f{6S+i1$jkUaiK`hJ(!)Nf%A$!LF7Rcfdww(e=aPTQF&=1Q(mmBpYo7j&gManR@>>YDLL4P9R_Z+{y5ymyVm z`U5xkB2ZbXz3z2`tQe{BKJXN2q6m@%?S9sya9w>aMf=ISmcquEk*^TM{0GWvN2d5C za^T_zyF=EqO;prp-8`~p!01;+Q3UXwmm|#n;7WBYH&&IhR`XJbksp?9l6DJ&m6p)g zyA&@`VmOa!DCP=XpJW}*a&RE=5++gnQsUF;e5dV`?y*h;)#h`idrqXs($o{E=c_>K zzohIUfYGA$se3{%V4TX;z-z$YU#-9r@(ZX=q4j0*l(`+hEHa~yt0P_!GPEvHUD8p^ zbp{;WlF3HDsEb3^Q|f{vsN@gK-`M%d?p^09CY-mK`N25nU(PkAsq0j<2#v4n;BPMn zf;fLWA?{xuA3rG~=~qmo9oCgl|0S4trbo8o(Az#}ge~bH_8aR5AEy9W=*OB#{)>+s zLB=w?UJ&Ad#9tNeLmadmC67F0Q<@Z8^ZTw3-x#%?-amI=inio-oqfZ>UaIevyMK4g zN?DQ}3yjv=+ZqZ|ssM)vs52>P(O29&9;Y1R@I(qu}5EHmiSq-wwE&lj-50GBa;Sn;c1+ z=KL(7*yapCpy|Gm=D2v$1miGxq4?NE<)Z`D6jXjIqGA0 z5QXR6I_)mf1|8E@7OV?!bt;39N?XDB=Mr3<$HF#hjoce7lkNR@z=h6?cqcv@#W=16 zP>f1Nhl{=o33Kjq_89 z!>aV^55-S#I|%fG&hC~SOBz2`(2J-vQdiGq%dNRwCUe7ww#9`3^ewq}Te~;*5TmF! z8$g0*p^7~#Q8UY1(%m5A((3$TW@69Zr&2wlQdbEIm;g%cVt)$NKb`;JA22`nBVrCa zwLY@tB9ru6qY3?3WGao}FnAF~ayoMj3vcvDcUAop+U?0aU7j>IJ32M8Y&_?t6+^hD zY|`^@x9mPP73k`E!5YT4u`@|mJ6$ij5KgkATxsOteI!?stnv_^4EOom`1fAqnXcQP zzFC4iy3vkv7oXiB$ZacUSo2H7n&rD!Xk%m_u;@txq_(D{CQyCIitn#jw9)R@ui)Rg z2r*QdXFC6g;e%Dycn!bsat4{ysPRyLeXNJB&!cm43xng5$rqKS#DSv%4{xrVdSwp| zuqU@nBBk?DIzqtw9-BUv{+GPW@7 zhvEigW2J#S|L{~t4N5pkaLTt^Qyb0R8(~bCMPyi-r1Pa~lE=f0)sHekYP9dd57W9d7j1I3UnkoRwtY#K@@uL3I(%mROqbqcvqeU1dzDq!+;XehJH-sQpnlBhPbjAYny5nVwvbsxJ9dNBX4*y9T{)(tg`OV?g9RJ zt*Q1k|5Tu-cH58^v&<^M`S*97EVG+o;4 z{0OLn6rJ+AzVe`ZimP(aa}awM?EB8wxUAUwuyd2@TlzcLS+EuQ z%!Od(LZ?&2=;>BaW_BvVyG;n_VCPiLlKn*~{akSyVOs8bX8u)7WN>kR3wFc$vJ;ZS zzcjO3kfc!+(A5Mv{Zsq7!MF@XL#XwVKI4T~dY5LEe&@%qB6G$!gI#Oes^D-daXgt& zFhwD8Q>nu;Ch{)k6p!lO8+xVix+2f4bIg2|ab8a8XFvCoV}(z$R$N6FxEclhoCji? z9_r~DqrEPoAq|=U&+871by0qGh5{H2mvw65}WM&a(I!&?5`G&R%O97F1-isR{qv|GRVj7ses&&RB zqCMKoHOE*7q*?9B$o5~;A}W!pm$H|;JvL+SI74b1jQrek35~qRrbY47r2TWF6)*hk z1Fn;OH}T=7JKdp~MtpKF>C}oAq@!VGWBHrtZhY;_t%WBQ`3ci<-4_u)vx;dsxD=wk z+{5E8^YZ&vJGP)O4He7JyWQWp5-T-}hPvrf(n4EmS%Y|j3!FEuzg}9DR%XS$Xhmo- znf*$%m-#*%(V^JzK7!N*t_1S%C@N+~N1IXe`b`8FW{!s~w(U;eb%-ivS;q*0H$7q! zxU+|yFVCI?wDX=67o#$A<9eXTtTp~@3ED0jGBmOIYC~WN!{<54=T4`L%Yo&!U*1Nv zyi~5Q!s4R`X1n$6rK>uAN5>u7vTa6NanqKKUx+>AjUZo3t0mbq8FRsY?e;Xi5O7UX zn)y{AQ|Il1o@nV5-qf&UC_%(M#H&TwHLicL8_3}!EYAaf>!oLcJO(GTsF(VgQ+~hu zLhB@TRkFBnJbBW_i0S|7y}h<3z40edcCyYm8*xgnx7Rz3Yb_D6H=D_T;?e{60%Vwg zA2N*bYW<2Mb$D6KW5f?A0uh!Dt&(sr8E9@fXZ&}vYhe#$()E~(nYrGS#@6axU&btF zNl#lNQN0_uO_L)>Dy{U<=m*M1pVxl`E#a|sevZ2M2Pe}9VHDZ*$|@eE7x?uxKeqa~ zn<-#6s||@ZXv`<0;pr*=)5nxNPNBj)pv9}N-3s7Pc1NFV1JQMc1E(ujcQd)xyUD+M z3NnxPo}lKKub_N1D9&HpOqf5O^@so7spxW|$a?lJ5521Qvr6qxCMI6PxVO_CcG*U3 z)T~$CJ!uu#=lsk!mWGKaBV~VPgKe}HA!_vwtRa63zEy8zPuAf%7|$3Ku$YnB+Sy)X zlls!hS={1FP2|#l^W}QS{u_Z!pJd|WX}@uf&XAaex356Qbo!AOPYA-EGR$hnZA9Y7 zMzB!zvrt5}M$2GHw+bxZ=Hh4fV)IL4ig<#clezhrpPpqN6a1p8arA=gDb&bbwJIlQ zdb0Yn7)8zRG1VtQ=a$>=>525>`txjSG&~4#IzWSJQG{p(C|)Dg?Z2kg(AMf?@cezs zKK33j7@It({@?zDf5upGQ$16z;(v-U~Xo0bTyt8fch-@j?jA4J-qzhiTIc2<3*~Kgbld4wHFS4=lBxl zZMgahf(F$~RJ^M48CiZ}wHdqapLqkF6=0|=iALR^%H5Lea^{=9k!Sc0Ora!`^oNVe z?jxjpXh+v9j!^YZ&tG?Cl7QMN#B%g{8GU#mR#apjO_; zp}V;18qlLHtAj!r7yMV>t7|&nUVyi~04kX; zVf>>~Q9kWnzV79-I%N&!*++62YyBacC!7=?b{vCgP8bCTVqY0v?n}G3>)|ZC`>Q{_ z{5MS=^kp@l!h$lV!G?1>L&SddT91o|69h%tLHc)vFD6YJ8X4UQ1V2rKzevff@s#++d)*;dQAN&0jea6 z=Qf>57?)S{5AXv#LUfuSCqM&M#1U;+r$79FHX7>eKIYO(pmZNjZRA7;b$(t=;ed4NY)OG7Qt3MB*)^(l zituTh`|C97EjLn@u?6>|2@c0Bi~Dcn&%G6X_LNZD^mS=qsFNE1{1VXVu(VFMa;Q#k z^kJGZHc+DNGtB*Hg->Y?Io6sn<$-HaH8GBM|c*-FQvkp_l(byC&&@zwX^Urj1IQT>@Nh0uxWoopKgU@$* zr!s2S@FV)#jRPL^fyT~5+<-_#7qa8c^kC$*v68>~$vO)LczM?S*79im)^G)W?{l2o zef3Q`>t|@(@k3VBxo7jHmml!lj*4dNSbvt6$~j!{&$k%jOue82jN1fvAawY~Lchz~ zNEnl^c)9INF2!H~y=UDRcxgm9{L9%FtfdD@OPto)idWz%8F@6kJG2V66lg9@LVVV2 zLUuK5_4-B_Q4w}Bg^#zhQn=3hZg<$z&!0Zn83G>{(9s> z=kJWPF~erON#}7B=@`M+HiSey(dcamvY8QS!5Urol)t7upDPzqxQ`D`FG9@#|H*O@ zV?CsWqhC(O@|B`N+}1b|xc-(;rZtCJwBL=#E8R$9Xz;kH8f=J7SE^8dBKf|0St~!R zjYerj`Yp@t!Mh!8A|Q>nL2a02)P2XhI)%Qx7?XQ7cV$$D7%$3VzA?U6h20V(eLx2o z-5OBmqh+6E#;6=nFL8GJW;1=vTcA)Nlos5zyk+DE8{!rEgxgob^OSh%Ue3UM$~wf! zHYQnyvmBR1v0H#Yz2{$6BSDns^7%?PMKRBB8EL>g1fv#Af*rXKqoDqrK|1BNulK&? z*Z1x%2X4%WTl|8sHBiVeHB`8L_slm^6M5HJi|I)% zZKpl;e-9h%s_sowYR>_z=E4cSzM-C2d`q>*8K%TbEd4YK^`3dOmj{lGuFeqS&`Q^y zD(wLOq4A`I7M-O5C-Am1^O`-WOEmuiDDRe16~ivY%t!^{={-#Foz15U8|yVaxFudB zn=d)F8tjY%5;9yvCbA#~sG) zZpn&t&bKbO2Eml&S=uR7prZ7E`6wi$nQ6IGm%&7sY`mDEtytX|Yoc}&c;JR4ku0^- m5~Zgm1@*xGw}=t_$Fz{I&F_gp-}~>wC(%~dQ>#{Sc>90*BFWGI diff --git a/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon~iPad.png b/Pods/WebBrowser/WebBrowser/Resources/WebBrowser.xcassets/safariIcon.imageset/safariIcon~iPad.png deleted file mode 100644 index 4c8a5aebfbef4673767fd6c5e99aaf59e209a52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2109 zcmV-D2*US?P)Px+_en%SRCodHntAY6Qy74W>?D+>P>71LCA7$r8Ih?hWh;Z3$QXmjGKrG4v5v7b zn!*%D)@H;oT8wH?mXtLafB2)(qR9R{=DRbuJNLW4`+dKA@2BRzGf(%P_nh;dbKiUJ z`=0at+GLYbN)MDCC_PYmp!7iLfzkt|2TBi=9@zLiuxW!IsV(F8hAwab>6jp(ba&9_r2j~bov@>i4pTKmO3_5Y6 zl)*gJ$KcBO5Jp1}*c{SIOB%W&Z-RxOt$8p2HX1pWCz%WD-~s3gS;-+7dKCVEnQ%00 zuyPr0G&+ttGiWs#LB+Ugl_9-J;d}T1whrkV zdh1&@xa+K>&m=ragYvs!MUD4vCEBIzvm5P}!IYHkb8j|*5&R6@Sk@w~YH1v4o3^hf z2jx(3gM6cfMvB?c0N*b%377wV5nYkRmJBu)`h*5OgL@M}J=r&8rv6)xHEtcQiZRgz z-6F_xlNvKjtjf5x0LH}B-i*#fuun`~?kdl6Zzhc5XHcZmJYxCD{SGrAE`x50{(UGs zo*mDi?%;i!Nn-upNewcpb0yCQcltjF-aapO=mbxFM-SsLmLxb59BBa=ZNm%lGAG zy=lX)@GD>~1dj4L9jr?$PttHs+Q#*^JB*G_u5-kIX}kzAyS)ctM|uAPG_`4t&e0fV z-(0sp_b|Xb2#W!B3ET-CAP;fnTncUpqR#pQT~DYcov3i$o;^Lng+<-iup;aGMHsv; z#;61gneuDp8ft=DfbrB$%mdfI#ndtmkr2sY!{&Te%3 zr8VL{Casu?{Ukk)Gq6#F9#CahTc9 z7?y`zhS9U(br=YKa&hu4O0#j6;xlEP+5em0H~f2XWTv}PZeO8Qq%LjoNE)sK-*gbf zjZbE;aG*Edbc1?iM>+-bY!fkXHRS~nUDaYOF)Yr=ttdNIDqi6FSX`q7-A>d!4?4yy z90YN7+rm>2Y#T;${~^>PuFC$Ej-PYAB4i}6A5vv=>s#<`WF=1Y4bWL5VvM?d2{x=# zW9qX~jl2XjJ1_$!HAetY=~jdYlPdX3Ga*YsgckVf>Li2Dk~Mb2BjPF8(K24P8R^49YXWRksZKLJ{I- z{K`BAIuoO&U}H@kzw4gsOTqhZ3RV$tJkB^NqG#m8%BLlw*mFa1UhQt zp^AYvTwki_Ty=vg`l2o;GLWGmm&3OYVa&O~n}`^PhJ%5+T7Vu%ozC(|vjtezN$PZ( z&dXY~>6|VA586?=9mNMxWtQc;F*ZM9ur1}qFdjTU#mPP>e}?67FiZp;l%zF2N0bLvJu?+M@Npy}!F|hOSW#%di zuwKjI_i@@gF^@JnZ4J0}a0}5$d78mz6)}Oq46+V7q!{dc+UTqR!@yd&K5D2DW#hst@HOm`asoQ`-IQ(Pnwh2B$5q7W z+M)Xan#$@iUGr16Lsq2+ce+hNBB-960W^tW08{*EALA!=r zb=ovAsGgcIgDt6Z%aN2lM^ZmL!N#`Kc{Xg3&}ImAeul2B|DChK^S+IO!S%YZGIHNK zQjQjza+vL_*)T-7`rK=|S>7PzY-Z`(HBNP}W5#CRL3Q-&O`rF{UvnFt4Qrjhf!$Bk zH|<7tU&u?`;lB)yH3j1KV5m0?F?i2`-{E2KC!(z62n;<5f5JOpd83ijc#`=LoG)+Y z{uoFK{#36gCXC}?JS+lj`3as3g@^&NXz}wI20o;#Z5=GBu#~IuM-&h7t)K&RhEC8D z+`>$UXW%O+Od8>^@Wbs)p(p4>W8Pk%lf=~%IPZJzb*ftlKkpS#O6h^p1EmK_50oA# nJy3d}^g!u>(gURjGV;K`^;L^9H;Y4x00000NkvXXu0mjf#)=J# diff --git a/Pods/WebBrowser/WebBrowser/SafariActivity.swift b/Pods/WebBrowser/WebBrowser/SafariActivity.swift deleted file mode 100644 index f2352c5..0000000 --- a/Pods/WebBrowser/WebBrowser/SafariActivity.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// SafariActivity.swift -// WebBrowser -// -// Created by Xin Hong on 16/4/27. -// Copyright © 2016年 Teambition. All rights reserved. -// - -import UIKit - -open class SafariActivity: UIActivity { - open var url: URL? - - open override var activityType: UIActivity.ActivityType? { - return ActivityType(String(describing: self)) - } - - open override var activityTitle : String? { - return LocalizedString(key: "Open in Safari") - } - - open override var activityImage : UIImage? { - return WebBrowser.image(named: "safariIcon") - } - - open override func canPerform(withActivityItems activityItems: [Any]) -> Bool { - for activityItem in activityItems { - if let activityURL = activityItem as? URL { - return UIApplication.shared.canOpenURL(activityURL) - } - } - return false - } - - open override func prepare(withActivityItems activityItems: [Any]) { - for activityItem in activityItems { - if let activityURL = activityItem as? URL { - url = activityURL - } - } - } - - open override func perform() { - if let url = url { - let completed = UIApplication.shared.openURL(url) - activityDidFinish(completed) - } - } -} diff --git a/Pods/WebBrowser/WebBrowser/ToolbarAppearance.swift b/Pods/WebBrowser/WebBrowser/ToolbarAppearance.swift deleted file mode 100644 index 44c82ff..0000000 --- a/Pods/WebBrowser/WebBrowser/ToolbarAppearance.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// ToolbarAppearance.swift -// WebBrowser -// -// Created by Xin Hong on 16/4/30. -// Copyright © 2016年 Teambition. All rights reserved. -// - -import UIKit - -internal struct ToolbarAppearance { - var isHidden = true - var tintColor = UIColor.blue - var barTintColor: UIColor? - var isTranslucent = true - - init() { } - - init(toolbar: UIToolbar) { - tintColor = toolbar.tintColor - barTintColor = toolbar.barTintColor - isTranslucent = toolbar.isTranslucent - } - - func apply(to toolbar: UIToolbar) { - toolbar.tintColor = tintColor - toolbar.barTintColor = barTintColor - toolbar.isTranslucent = isTranslucent - } -} diff --git a/Pods/WebBrowser/WebBrowser/WebBrowser.swift b/Pods/WebBrowser/WebBrowser/WebBrowser.swift deleted file mode 100644 index 4257fc9..0000000 --- a/Pods/WebBrowser/WebBrowser/WebBrowser.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// WebBrowser.swift -// WebBrowser -// -// Created by Xin Hong on 16/4/27. -// Copyright © 2016年 Teambition. All rights reserved. -// - -import UIKit - -internal struct WebBrowser { - static let estimatedProgressKeyPath = "estimatedProgress" - static var estimatedProgressContext = 0 - static let defaultToolbarItemSpace: CGFloat = 50 - - static var resourceBundleURL: URL? { - let resourceBundleURL = Bundle(for: WebBrowserViewController.self).url(forResource: "WebBrowser", withExtension: "bundle") - return resourceBundleURL - } - - static func localizationPath(forIdentifier identifier: String) -> String? { - if let path = Bundle(identifier: "Teambition.WebBrowser")?.path(forResource: identifier, ofType: "lproj") { - return path - } else if let resourceBundleURL = resourceBundleURL, let resourceBundle = Bundle(url: resourceBundleURL) { - return resourceBundle.path(forResource: identifier, ofType: "lproj") - } - return nil - } - - static func image(named name: String) -> UIImage? { - if let image = UIImage(named: name, in: Bundle(for: WebBrowserViewController.self), compatibleWith: nil) { - return image - } else if let resourceBundleURL = resourceBundleURL, let resourceBundle = Bundle(url: resourceBundleURL) { - return UIImage(named: name, in: resourceBundle, compatibleWith: nil) - } - return nil - } -} diff --git a/Pods/WebBrowser/WebBrowser/WebBrowserDelegate.swift b/Pods/WebBrowser/WebBrowser/WebBrowserDelegate.swift deleted file mode 100644 index 985539a..0000000 --- a/Pods/WebBrowser/WebBrowser/WebBrowserDelegate.swift +++ /dev/null @@ -1,46 +0,0 @@ -// -// WebBrowserDelegate.swift -// WebBrowser -// -// Created by Xin Hong on 16/4/26. -// Copyright © 2016年 Teambition. All rights reserved. -// - -import UIKit -import WebKit - -public protocol WebBrowserDelegate: class { - func webBrowser(_ webBrowser: WebBrowserViewController, didStartLoad url: URL?) - func webBrowser(_ webBrowser: WebBrowserViewController, didFinishLoad url: URL?) - func webBrowser(_ webBrowser: WebBrowserViewController, didFailLoad url: URL?, withError error: Error) - - func webBrowserWillDismiss(_ webBrowser: WebBrowserViewController) - func webBrowserDidDismiss(_ webBrowser: WebBrowserViewController) - func webBrowser(_ webBrowser: WebBrowserViewController, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) -> Bool -} - -public extension WebBrowserDelegate { - func webBrowser(_ webBrowser: WebBrowserViewController, didStartLoad url: URL?) { - - } - - func webBrowser(_ webBrowser: WebBrowserViewController, didFinishLoad url: URL?) { - - } - - func webBrowser(_ webBrowser: WebBrowserViewController, didFailLoad url: URL?, withError error: Error) { - - } - - func webBrowserWillDismiss(_ webBrowser: WebBrowserViewController) { - - } - - func webBrowserDidDismiss(_ webBrowser: WebBrowserViewController) { - - } - - func webBrowser(_ webBrowser: WebBrowserViewController, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) -> Bool { - return false - } -} diff --git a/Pods/WebBrowser/WebBrowser/WebBrowserViewController.swift b/Pods/WebBrowser/WebBrowser/WebBrowserViewController.swift deleted file mode 100644 index baaaec7..0000000 --- a/Pods/WebBrowser/WebBrowser/WebBrowserViewController.swift +++ /dev/null @@ -1,412 +0,0 @@ -// -// WebBrowserViewController.swift -// WebBrowser -// -// Created by Xin Hong on 16/4/26. -// Copyright © 2016年 Teambition. All rights reserved. -// - -import UIKit -import WebKit - -open class WebBrowserViewController: UIViewController { - open weak var delegate: WebBrowserDelegate? - open var language: WebBrowserLanguage = .english { - didSet { - InternationalControl.sharedControl.language = language - } - } - open var tintColor = UIColor.blue { - didSet { - updateTintColor() - } - } - open var barTintColor: UIColor? { - didSet { - updateBarTintColor() - } - } - open var isToolbarHidden = false { - didSet { - navigationController?.setToolbarHidden(isToolbarHidden, animated: true) - } - } - open var toolbarItemSpace = WebBrowser.defaultToolbarItemSpace { - didSet { - itemFixedSeparator.width = toolbarItemSpace - } - } - open var isShowActionBarButton = true { - didSet { - updateToolBarState() - } - } - open var customApplicationActivities = [UIActivity]() - open var isShowURLInNavigationBarWhenLoading = true - open var isShowPageTitleInNavigationBar = true - - fileprivate var webView = WKWebView(frame: CGRect.zero) - - public func getWKWebView() -> WKWebView { - return webView - } - - fileprivate lazy var progressView: UIProgressView = { - let progressView = UIProgressView(progressViewStyle: .default) - progressView.trackTintColor = .clear - progressView.tintColor = self.tintColor - return progressView - }() - fileprivate var previousNavigationControllerNavigationBarAppearance = NavigationBarAppearance() - fileprivate var previousNavigationControllerToolbarAppearance = ToolbarAppearance() - - fileprivate lazy var refreshButton: UIBarButtonItem = { - let refreshButton = UIBarButtonItem(barButtonSystemItem: .refresh, target: self, action: #selector(WebBrowserViewController.refreshButtonTapped(_:))) - return refreshButton - }() - fileprivate lazy var stopButton: UIBarButtonItem = { - let stopButton = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(WebBrowserViewController.stopButtonTapped(_:))) - return stopButton - }() - fileprivate lazy var backButton: UIBarButtonItem = { - let backIcon = WebBrowser.image(named: "backIcon") - let backButton = UIBarButtonItem(image: backIcon, style: .plain, target: self, action: #selector(WebBrowserViewController.backButtonTapped(_:))) - return backButton - }() - fileprivate lazy var forwardButton: UIBarButtonItem = { - let forwardIcon = WebBrowser.image(named: "forwardIcon") - let forwardButton = UIBarButtonItem(image: forwardIcon, style: .plain, target: self, action: #selector(WebBrowserViewController.forwardButtonTapped(_:))) - return forwardButton - }() - fileprivate lazy var actionButton: UIBarButtonItem = { - let actionButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(WebBrowserViewController.actionButtonTapped(_:))) - return actionButton - }() - fileprivate lazy var itemFixedSeparator: UIBarButtonItem = { - let itemFixedSeparator = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) - itemFixedSeparator.width = self.toolbarItemSpace - return itemFixedSeparator - }() - fileprivate lazy var itemFlexibleSeparator: UIBarButtonItem = { - let itemFlexibleSeparator = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) - return itemFlexibleSeparator - }() - - public var onOpenExternalAppHandler: ((_ isOpen: Bool) -> Void)? - - // MARK: - Life cycle - open override func viewDidLoad() { - super.viewDidLoad() - - savePreviousNavigationControllerState() - configureWebView() - configureProgressView() - } - - open override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - navigationController?.setNavigationBarHidden(false, animated: true) - navigationController?.navigationBar.setBackgroundImage(nil, for: .default) - navigationController?.navigationBar.shadowImage = nil - navigationController?.navigationBar.isTranslucent = true - navigationController?.navigationBar.addSubview(progressView) - navigationController?.setToolbarHidden(isToolbarHidden, animated: true) - - progressView.alpha = 0 - updateTintColor() - updateBarTintColor() - updateToolBarState() - } - - open override func viewWillDisappear(_ animated: Bool) { - super.viewWillDisappear(animated) - restorePreviousNavigationControllerState(animated: animated) - progressView.removeFromSuperview() - } - - public convenience init(configuration: WKWebViewConfiguration) { - self.init() - webView = WKWebView(frame: CGRect.zero, configuration: configuration) - } - - open class func rootNavigationWebBrowser(webBrowser: WebBrowserViewController) -> UINavigationController { - webBrowser.navigationItem.rightBarButtonItem = UIBarButtonItem(title: LocalizedString(key: "Done"), style: .done, target: webBrowser, action: #selector(WebBrowserViewController.doneButtonTapped(_:))) - let navigationController = UINavigationController(rootViewController: webBrowser) - return navigationController - } - - deinit { - webView.uiDelegate = nil - webView.navigationDelegate = nil - if isViewLoaded { - webView.removeObserver(self, forKeyPath: WebBrowser.estimatedProgressKeyPath) - } - } - - // MARK: - Public - open func loadRequest(_ request: URLRequest) { - webView.load(request) - } - - open func loadURL(_ url: URL) { - webView.load(URLRequest(url: url)) - } - - open func loadURLString(_ urlString: String) { - guard let url = URL(string: urlString) else { - return - } - webView.load(URLRequest(url: url)) - } - - open func loadHTMLString(_ htmlString: String, baseURL: URL?) { - webView.loadHTMLString(htmlString, baseURL: baseURL) - } -} - -extension WebBrowserViewController { - // MARK: - Helper - fileprivate func configureWebView() { - webView.frame = view.bounds - webView.autoresizingMask = [.flexibleWidth, .flexibleHeight] - webView.autoresizesSubviews = true - webView.navigationDelegate = self - webView.uiDelegate = self - webView.isMultipleTouchEnabled = true - webView.scrollView.alwaysBounceVertical = true - view.addSubview(webView) - - webView.addObserver(self, forKeyPath: WebBrowser.estimatedProgressKeyPath, options: .new, context: &WebBrowser.estimatedProgressContext) - } - - fileprivate func configureProgressView() { - let yPosition: CGFloat = { - guard let navigationBar = self.navigationController?.navigationBar else { - return 0 - } - return navigationBar.frame.height - self.progressView.frame.height - }() - progressView.frame = CGRect(x: 0, y: yPosition, width: view.frame.width, height: progressView.frame.width) - progressView.autoresizingMask = [.flexibleWidth, .flexibleTopMargin] - } - - fileprivate func savePreviousNavigationControllerState() { - guard let navigationController = navigationController else { - return - } - - var navigationBarAppearance = NavigationBarAppearance(navigationBar: navigationController.navigationBar) - navigationBarAppearance.isHidden = navigationController.isNavigationBarHidden - previousNavigationControllerNavigationBarAppearance = navigationBarAppearance - - var toolbarAppearance = ToolbarAppearance(toolbar: navigationController.toolbar) - toolbarAppearance.isHidden = navigationController.isToolbarHidden - previousNavigationControllerToolbarAppearance = toolbarAppearance - } - - fileprivate func restorePreviousNavigationControllerState(animated: Bool) { - guard let navigationController = navigationController else { - return - } - - navigationController.setNavigationBarHidden(previousNavigationControllerNavigationBarAppearance.isHidden, animated: animated) - navigationController.setToolbarHidden(previousNavigationControllerToolbarAppearance.isHidden, animated: animated) - - previousNavigationControllerNavigationBarAppearance.apply(to: navigationController.navigationBar) - previousNavigationControllerToolbarAppearance.apply(to: navigationController.toolbar) - } - - fileprivate func updateTintColor() { - progressView.tintColor = tintColor - navigationController?.navigationBar.tintColor = tintColor - navigationController?.toolbar.tintColor = tintColor - } - - fileprivate func updateBarTintColor() { - navigationController?.navigationBar.barTintColor = barTintColor - navigationController?.toolbar.barTintColor = barTintColor - } -} - -extension WebBrowserViewController { - // MARK: - UIBarButtonItem actions - @objc func refreshButtonTapped(_ sender: UIBarButtonItem) { - webView.stopLoading() - webView.reload() - } - - @objc func stopButtonTapped(_ sender: UIBarButtonItem) { - webView.stopLoading() - } - - @objc func backButtonTapped(_ sender: UIBarButtonItem) { - webView.goBack() - updateToolBarState() - } - - @objc func forwardButtonTapped(_ sender: UIBarButtonItem) { - webView.goForward() - updateToolBarState() - } - - @objc func actionButtonTapped(_ sender: UIBarButtonItem) { - DispatchQueue.main.async { - var activityItems = [Any]() - if let url = self.webView.url { - activityItems.append(url) - } - var applicationActivities = [UIActivity]() - applicationActivities.append(SafariActivity()) - applicationActivities.append(contentsOf: self.customApplicationActivities) - - let activityViewController = UIActivityViewController(activityItems: activityItems, applicationActivities: applicationActivities) - activityViewController.view.tintColor = self.tintColor - - if UIDevice.current.userInterfaceIdiom == .pad { - activityViewController.popoverPresentationController?.barButtonItem = sender - activityViewController.popoverPresentationController?.permittedArrowDirections = .any - self.present(activityViewController, animated: true, completion: nil) - } else { - self.present(activityViewController, animated: true, completion: nil) - } - } - } - - @objc func doneButtonTapped(_ sender: UIBarButtonItem) { - delegate?.webBrowserWillDismiss(self) - dismiss(animated: true) { - self.delegate?.webBrowserDidDismiss(self) - } - } -} - -extension WebBrowserViewController { - // MARK: - Tool bar - public func updateToolBarState() { - backButton.isEnabled = webView.canGoBack - forwardButton.isEnabled = webView.canGoForward - - var barButtonItems = [UIBarButtonItem]() - if webView.isLoading { - barButtonItems = [backButton, itemFixedSeparator, forwardButton, itemFixedSeparator, stopButton, itemFlexibleSeparator] - if let urlString = webView.url?.absoluteString, isShowURLInNavigationBarWhenLoading { - var titleString = urlString.replacingOccurrences(of: "http://", with: "", options: .literal, range: nil) - titleString = titleString.replacingOccurrences(of: "https://", with: "", options: .literal, range: nil) - navigationItem.title = titleString - } - } else { - barButtonItems = [backButton, itemFixedSeparator, forwardButton, itemFixedSeparator, refreshButton, itemFlexibleSeparator] - if isShowPageTitleInNavigationBar { - navigationItem.title = webView.title - } - } - - if isShowActionBarButton { - barButtonItems.append(actionButton) - } - - setToolbarItems(barButtonItems, animated: true) - } -} - -extension WebBrowserViewController { - // MARK: - External app support - fileprivate func externalAppRequiredToOpen(_ url: URL) -> Bool { - let validSchemes: Set = ["http", "https"] - if let urlScheme = url.scheme { - return !validSchemes.contains(urlScheme) - } else { - return false - } - } - - fileprivate func openExternalApp(with url: URL) { - let externalAppPermissionAlert = UIAlertController(title: LocalizedString(key: "OpenExternalAppAlert.title"), message: LocalizedString(key: "OpenExternalAppAlert.message"), preferredStyle: .alert) - let cancelAction = UIAlertAction(title: LocalizedString(key: "Cancel"), style: .cancel, handler: { [weak self] (action) in - self?.onOpenExternalAppHandler?(false) - }) - let openAction = UIAlertAction(title: LocalizedString(key: "Open"), style: .default) { [weak self] (action) in - UIApplication.shared.openURL(url) - self?.onOpenExternalAppHandler?(true) - } - externalAppPermissionAlert.addAction(cancelAction) - externalAppPermissionAlert.addAction(openAction) - present(externalAppPermissionAlert, animated: true, completion: nil) - } -} - -extension WebBrowserViewController { - // MARK: - Observer - open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { - if let keyPath = keyPath, (keyPath == WebBrowser.estimatedProgressKeyPath && context == &WebBrowser.estimatedProgressContext) { - progressView.alpha = 1 - let animated = webView.estimatedProgress > Double(progressView.progress) - progressView.setProgress(Float(webView.estimatedProgress), animated: animated) - - if webView.estimatedProgress >= 1 { - UIView.animate(withDuration: 0.3, delay: 0.3, options: .curveEaseOut, animations: { - self.progressView.alpha = 0 - }, completion: { (finished) in - self.progressView.progress = 0 - }) - } - } else { - super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) - } - } -} - -extension WebBrowserViewController: WKNavigationDelegate { - // MARK: - WKNavigationDelegate - public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { - updateToolBarState() - delegate?.webBrowser(self, didStartLoad: webView.url) - } - - public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { - updateToolBarState() - delegate?.webBrowser(self, didFinishLoad: webView.url) - } - - public func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { - updateToolBarState() - delegate?.webBrowser(self, didFailLoad: webView.url, withError: error) - } - - public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { - updateToolBarState() - delegate?.webBrowser(self, didFailLoad: webView.url, withError: error) - } - - - public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { - if let oriDelegate = delegate, oriDelegate.webBrowser(self, decidePolicyFor: navigationAction, decisionHandler: decisionHandler) { - return - } - if let url = navigationAction.request.url { - if !externalAppRequiredToOpen(url) { - if navigationAction.targetFrame == nil { - loadURL(url) - decisionHandler(.cancel) - return - } - } else if UIApplication.shared.canOpenURL(url) { - openExternalApp(with: url) - decisionHandler(.cancel) - return - } - } - - decisionHandler(.allow) - } -} - -extension WebBrowserViewController: WKUIDelegate { - // MARK: - WKUIDelegate - public func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { - if let mainFrame = navigationAction.targetFrame?.isMainFrame, mainFrame == false { - webView.load(navigationAction.request) - } - return nil - } -} diff --git a/kplayer.xcodeproj/project.pbxproj b/kplayer.xcodeproj/project.pbxproj index b3ba4ee..6431f9c 100644 --- a/kplayer.xcodeproj/project.pbxproj +++ b/kplayer.xcodeproj/project.pbxproj @@ -9,8 +9,8 @@ /* Begin PBXBuildFile section */ 1C73600CB93F16F4F28C116F /* KSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736A6E8396EE306B1AD3A8 /* KSettingsView.swift */; }; 1C736048BFA120F5C7D36874 /* readme.md in Sources */ = {isa = PBXBuildFile; fileRef = 1C73685B4BBFDAFBF08C032C /* readme.md */; }; + 1C73604B4926AA24595D4FD7 /* DocPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7363CD8FF2C0A56DB63ADD /* DocPickerViewController.swift */; }; 1C7360C0F2A4F0214FE353BD /* FileHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7367ECBD369A2A0C94C499 /* FileHelper.swift */; }; - 1C73613562EB375F53A0BD03 /* ServerDownloadDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736595533B56039C417E0D /* ServerDownloadDelegate.swift */; }; 1C7361B3AF46CEB30D3F4FA0 /* KSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736AE5021E3D985FE3402D /* KSettings.swift */; }; 1C73620BC7F5A1F35FFFF9FC /* SPhotoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736AD9F0A39AD543FC1176 /* SPhotoView.swift */; }; 1C73631EACF56BABD3B2BCFB /* LayoutTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736BC4450890C45F8FBC63 /* LayoutTools.swift */; }; @@ -22,11 +22,12 @@ 1C736503B656C999E5E12081 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7365B06FA66294E99AC2D3 /* NetworkManager.swift */; }; 1C73654C9EA6D255CFC039C5 /* NetworkHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73620D01687FB4F1811C5C /* NetworkHelper.swift */; }; 1C736559059B6FBA1C661191 /* KToggleButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73661C3F9F4E53645551AD /* KToggleButton.swift */; }; - 1C7365885FAF292F2221ED44 /* PhotoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73673DC671535E3A049F54 /* PhotoController.swift */; }; 1C7365C59F72C29EA41C8717 /* SVideoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736EEC570C71AAC50F2E95 /* SVideoModel.swift */; }; + 1C7365C929045799553DF4BC /* MasterModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7363EDB190A6B76C5AAAF7 /* MasterModel.swift */; }; 1C7365CE76693E7772585CA8 /* SVideoPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73621E431C9BEC1440B936 /* SVideoPlayer.swift */; }; 1C73666A07CF2416B1B8D3F0 /* KSettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736C94157754DE1C808173 /* KSettingsModel.swift */; }; 1C736690D123BD4B24874394 /* pathfinder.scpt in Sources */ = {isa = PBXBuildFile; fileRef = 1C7369BED02028D8564E82D5 /* pathfinder.scpt */; }; + 1C736699A2992473AC2626AC /* MasterSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736CDA5E3039EEE0CC39E4 /* MasterSplitView.swift */; }; 1C7366A0CFD2B55BF8C3BAF0 /* NetworkDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7364F10BED5DA0F1C0423C /* NetworkDelegate.swift */; }; 1C7366BEA68D6E4CEE43417E /* ImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736CC8D90375E86CD01964 /* ImageLoader.swift */; }; 1C7366FE5C760C8D5117207F /* SVideoLoopPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7360F9835128FC0A198ED0 /* SVideoLoopPlayer.swift */; }; @@ -37,6 +38,7 @@ 1C73675C34BE0990D44570BE /* ItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736253AB7A95EA41B605B7 /* ItemModel.swift */; }; 1C736771C503FB0D52AEB8F7 /* kplayer.js in Sources */ = {isa = PBXBuildFile; fileRef = 1C73625012D50E457D18A785 /* kplayer.js */; }; 1C736776CF759CA3DB136F33 /* KBrowserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736EF64DE56AD058A4F612 /* KBrowserView.swift */; }; + 1C736789A4B89024F6485608 /* PlayerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736F5826258B8B4BA6ECE6 /* PlayerApp.swift */; }; 1C7367AF39961D2BA72480ED /* DataLoadOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736F9338CE36708244D42A /* DataLoadOperation.swift */; }; 1C736821D6DF2237A3EABCC1 /* ViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73648CEC974A2500172064 /* ViewControllerExtensions.swift */; }; 1C7368242038C0FF6C9631E7 /* VideoHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7364709899FF62774B0199 /* VideoHelper.swift */; }; @@ -44,7 +46,6 @@ 1C7368DBC47F0CC152504141 /* SPhotoScrubber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7368EFFBCD688E0D425117 /* SPhotoScrubber.swift */; }; 1C73691A9C7174E0C6B57267 /* stringutil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736B794396F2E50387B8F2 /* stringutil.swift */; }; 1C73693A1334A7792856FC58 /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73611D226B48C24DB37535 /* MasterViewController.swift */; }; - 1C736953BDBBAFC40884132A /* BrowserController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73602350ACE2436736F981 /* BrowserController.swift */; }; 1C73696E4C0353053BF98031 /* links.html in Resources */ = {isa = PBXBuildFile; fileRef = 1C73615FFA2AA98BD1C56CD4 /* links.html */; }; 1C736998044A9A7D89411892 /* AsyncImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7360B6D0757D4FB6433E7B /* AsyncImage.swift */; }; 1C7369ABC44CFB530EA71FB6 /* HeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736D9BB5498E7E8F11C754 /* HeaderCell.swift */; }; @@ -53,6 +54,7 @@ 1C736A5FA5BA53B2597F2ED7 /* Kirschkeks-256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C736059262A57AADE6AB761 /* Kirschkeks-256x256.png */; }; 1C736A622876405F3EE2D043 /* EditItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7366C09381DC0052B52B69 /* EditItemView.swift */; }; 1C736A7B6221A1D50FB3904C /* ItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73631C96E6C860833052CA /* ItemType.swift */; }; + 1C736A9DE203A7658D85B7B6 /* ItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73630B535C2358125793D4 /* ItemView.swift */; }; 1C736B4B0889BD35DC566124 /* nspersistentcontainer-defaults-swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7361F01841F546FA7AFD58 /* nspersistentcontainer-defaults-swift.swift */; }; 1C736BEC4C4263EF6A89E9E3 /* SPhotoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736F83C6190A3A0D5BD1F0 /* SPhotoModel.swift */; }; 1C736C00693A05747578DF87 /* grabber.js in Sources */ = {isa = PBXBuildFile; fileRef = 1C73619BBFA9295A11C9ACBA /* grabber.js */; }; @@ -66,6 +68,7 @@ 1C736D5A7C7CB9B14AF0ECA6 /* DetailViewController+Show.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736B17A8E9FB352B90A903 /* DetailViewController+Show.swift */; }; 1C736D89CF86841F4C98A1F7 /* KPersistentContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7362DE1D6BE634D7C2ACBF /* KPersistentContainer.swift */; }; 1C736DAE7F2A530AACDA0D18 /* KFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7363743CD8120637AC1EDE /* KFrame.swift */; }; + 1C736DEE40337056C8D2A044 /* DetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7363745D2F89492F2D79C1 /* DetailView.swift */; }; 1C736DFA8544C773E3C22F10 /* VideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73675F8DDFA82DEADB542E /* VideoPlayerView.swift */; }; 1C736DFD076D9CC30F0B9D58 /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736677D4EF2437358B2387 /* Utility.swift */; }; 1C736E21B246C0BE7E123FD3 /* MediaModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736B41C6AC33F3FA592C63 /* MediaModel.swift */; }; @@ -106,7 +109,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 1C73602350ACE2436736F981 /* BrowserController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BrowserController.swift; sourceTree = ""; }; 1C7360295486647982CFEACF /* UIViewController+Alert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Alert.swift"; sourceTree = ""; }; 1C736059262A57AADE6AB761 /* Kirschkeks-256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Kirschkeks-256x256.png"; path = "kplayer/Kirschkeks-256x256.png"; sourceTree = ""; }; 1C736069C214E9522BB1BD97 /* ItemCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemCell.swift; sourceTree = ""; }; @@ -126,21 +128,23 @@ 1C736253AB7A95EA41B605B7 /* ItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemModel.swift; sourceTree = ""; }; 1C736260E748CF136FF37EA7 /* UploadOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UploadOperation.swift; sourceTree = ""; }; 1C7362DE1D6BE634D7C2ACBF /* KPersistentContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KPersistentContainer.swift; sourceTree = ""; }; + 1C73630B535C2358125793D4 /* ItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemView.swift; sourceTree = ""; }; 1C73631C96E6C860833052CA /* ItemType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemType.swift; sourceTree = ""; }; 1C7363743CD8120637AC1EDE /* KFrame.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KFrame.swift; sourceTree = ""; }; + 1C7363745D2F89492F2D79C1 /* DetailView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailView.swift; sourceTree = ""; }; + 1C7363CD8FF2C0A56DB63ADD /* DocPickerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DocPickerViewController.swift; sourceTree = ""; }; + 1C7363EDB190A6B76C5AAAF7 /* MasterModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterModel.swift; sourceTree = ""; }; 1C73645DBD6499A726D34973 /* links.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = links.html; sourceTree = ""; }; 1C73647019E6C2E822127BA3 /* DatabaseManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatabaseManager.swift; sourceTree = ""; }; 1C7364709899FF62774B0199 /* VideoHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoHelper.swift; sourceTree = ""; }; 1C73648CEC974A2500172064 /* ViewControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewControllerExtensions.swift; sourceTree = ""; }; 1C7364F10BED5DA0F1C0423C /* NetworkDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkDelegate.swift; sourceTree = ""; }; 1C73654AB95A2D629833BEC5 /* SearchItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchItemView.swift; sourceTree = ""; }; - 1C736595533B56039C417E0D /* ServerDownloadDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServerDownloadDelegate.swift; sourceTree = ""; }; 1C73659CC9B523B957E58DC6 /* LocalManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalManager.swift; sourceTree = ""; }; 1C7365B06FA66294E99AC2D3 /* NetworkManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkManager.swift; sourceTree = ""; }; 1C73661C3F9F4E53645551AD /* KToggleButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KToggleButton.swift; sourceTree = ""; }; 1C736677D4EF2437358B2387 /* Utility.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utility.swift; sourceTree = ""; }; 1C7366C09381DC0052B52B69 /* EditItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditItemView.swift; sourceTree = ""; }; - 1C73673DC671535E3A049F54 /* PhotoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoController.swift; sourceTree = ""; }; 1C73675F8DDFA82DEADB542E /* VideoPlayerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoPlayerView.swift; sourceTree = ""; }; 1C736777456388CA571DA17B /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; 1C7367B39F09CCD1760A345A /* SEmbeddedVideo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SEmbeddedVideo.swift; sourceTree = ""; }; @@ -164,6 +168,7 @@ 1C736C72CDF8902484856B3B /* SelfSizingHostingController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelfSizingHostingController.swift; sourceTree = ""; }; 1C736C94157754DE1C808173 /* KSettingsModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KSettingsModel.swift; sourceTree = ""; }; 1C736CC8D90375E86CD01964 /* ImageLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageLoader.swift; sourceTree = ""; }; + 1C736CDA5E3039EEE0CC39E4 /* MasterSplitView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterSplitView.swift; sourceTree = ""; }; 1C736D27EC608FAAFDB4A68C /* WebView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = ""; }; 1C736D50A22FC4553165199D /* FlexibleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlexibleView.swift; sourceTree = ""; }; 1C736D9BB5498E7E8F11C754 /* HeaderCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderCell.swift; sourceTree = ""; }; @@ -175,6 +180,7 @@ 1C736EA15A11AF7D57F85824 /* ThumbnailCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThumbnailCache.swift; sourceTree = ""; }; 1C736EEC570C71AAC50F2E95 /* SVideoModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SVideoModel.swift; sourceTree = ""; }; 1C736EF64DE56AD058A4F612 /* KBrowserView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KBrowserView.swift; sourceTree = ""; }; + 1C736F5826258B8B4BA6ECE6 /* PlayerApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerApp.swift; sourceTree = ""; }; 1C736F83C6190A3A0D5BD1F0 /* SPhotoModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPhotoModel.swift; sourceTree = ""; }; 1C736F9338CE36708244D42A /* DataLoadOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataLoadOperation.swift; sourceTree = ""; }; 6D522F61736592330F481B4F /* Pods-kplayer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-kplayer.debug.xcconfig"; path = "Pods/Target Support Files/Pods-kplayer/Pods-kplayer.debug.xcconfig"; sourceTree = ""; }; @@ -228,9 +234,10 @@ 1C736069C214E9522BB1BD97 /* ItemCell.swift */, 1C736D9BB5498E7E8F11C754 /* HeaderCell.swift */, 1C7369F53095B7A4D65679C2 /* DetailViewController.swift */, - 1C73602350ACE2436736F981 /* BrowserController.swift */, 1C7366C09381DC0052B52B69 /* EditItemView.swift */, 1C736B17A8E9FB352B90A903 /* DetailViewController+Show.swift */, + 1C7363745D2F89492F2D79C1 /* DetailView.swift */, + 1C73630B535C2358125793D4 /* ItemView.swift */, ); path = detail; sourceTree = ""; @@ -250,7 +257,6 @@ 1C7363B608460DED4F522D1C /* photo */ = { isa = PBXGroup; children = ( - 1C73673DC671535E3A049F54 /* PhotoController.swift */, 1C736AD9F0A39AD543FC1176 /* SPhotoView.swift */, 1C736F83C6190A3A0D5BD1F0 /* SPhotoModel.swift */, 1C7368EFFBCD688E0D425117 /* SPhotoScrubber.swift */, @@ -265,8 +271,10 @@ 1C73611D226B48C24DB37535 /* MasterViewController.swift */, 1C7364F10BED5DA0F1C0423C /* NetworkDelegate.swift */, 1C736A6E8396EE306B1AD3A8 /* KSettingsView.swift */, - 1C736595533B56039C417E0D /* ServerDownloadDelegate.swift */, 1C73654AB95A2D629833BEC5 /* SearchItemView.swift */, + 1C736CDA5E3039EEE0CC39E4 /* MasterSplitView.swift */, + 1C7363EDB190A6B76C5AAAF7 /* MasterModel.swift */, + 1C7363CD8FF2C0A56DB63ADD /* DocPickerViewController.swift */, ); path = master; sourceTree = ""; @@ -411,6 +419,7 @@ 1C736F3946A38499113D351A /* video */, 1C73633B55AC5378053BDCE2 /* server */, 1C736FEAC391DC13A5D6E61E /* web */, + 1C736F5826258B8B4BA6ECE6 /* PlayerApp.swift */, ); path = kplayer; sourceTree = ""; @@ -559,9 +568,6 @@ "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework", "${BUILT_PRODUCTS_DIR}/FileBrowser/FileBrowser.framework", "${BUILT_PRODUCTS_DIR}/HanekeSwift/Haneke.framework", - "${BUILT_PRODUCTS_DIR}/NVActivityIndicatorView/NVActivityIndicatorView.framework", - "${BUILT_PRODUCTS_DIR}/Nimbus/Nimbus.framework", - "${BUILT_PRODUCTS_DIR}/WebBrowser/WebBrowser.framework", "${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework", ); name = "[CP] Embed Pods Frameworks"; @@ -569,9 +575,6 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FileBrowser.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Haneke.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NVActivityIndicatorView.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimbus.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WebBrowser.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZIPFoundation.framework", ); runOnlyForDeploymentPostprocessing = 0; @@ -617,7 +620,6 @@ 1C73640D928DE56D35175D39 /* UploadOperation.swift in Sources */, 1C73646F87B495A47D7943C7 /* NetData.swift in Sources */, 1C73693A1334A7792856FC58 /* MasterViewController.swift in Sources */, - 1C7365885FAF292F2221ED44 /* PhotoController.swift in Sources */, 1C736D16E81BA1FB325200E0 /* HanekeFetchOperation.swift in Sources */, 1C736D24891597F2728230EE /* ImageLoadOperation.swift in Sources */, 1C7367AF39961D2BA72480ED /* DataLoadOperation.swift in Sources */, @@ -625,7 +627,6 @@ 1C73675C34BE0990D44570BE /* ItemModel.swift in Sources */, 1C73691A9C7174E0C6B57267 /* stringutil.swift in Sources */, 1C736821D6DF2237A3EABCC1 /* ViewControllerExtensions.swift in Sources */, - 1C736953BDBBAFC40884132A /* BrowserController.swift in Sources */, 1C73671FC2CCCACAA2FFC153 /* ThumbnailCache.swift in Sources */, C91E05892795AC5C0003AB79 /* KTag+CoreDataClass.swift in Sources */, 1C736E21B246C0BE7E123FD3 /* MediaModel.swift in Sources */, @@ -646,7 +647,6 @@ C91E058B2795AC5C0003AB79 /* KItem+CoreDataClass.swift in Sources */, 1C736A622876405F3EE2D043 /* EditItemView.swift in Sources */, C9D67651291E73A00060179C /* Cached+CoreDataProperties.swift in Sources */, - 1C73613562EB375F53A0BD03 /* ServerDownloadDelegate.swift in Sources */, 1C736EC45EE7DA5F7FCE63DA /* LocalManager.swift in Sources */, 1C736DFD076D9CC30F0B9D58 /* Utility.swift in Sources */, 1C736998044A9A7D89411892 /* AsyncImage.swift in Sources */, @@ -680,6 +680,12 @@ 1C736EFF1E09988625FF770C /* hints.md in Sources */, 1C73670151CCBC714795807F /* SRangeSlider.swift in Sources */, 1C736E5C86EFC8E8C1ABA131 /* raspberrypi.js in Sources */, + 1C736699A2992473AC2626AC /* MasterSplitView.swift in Sources */, + 1C7365C929045799553DF4BC /* MasterModel.swift in Sources */, + 1C736DEE40337056C8D2A044 /* DetailView.swift in Sources */, + 1C736A9DE203A7658D85B7B6 /* ItemView.swift in Sources */, + 1C73604B4926AA24595D4FD7 /* DocPickerViewController.swift in Sources */, + 1C736789A4B89024F6485608 /* PlayerApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -768,7 +774,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -817,7 +823,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; diff --git a/kplayer.xcodeproj/xcuserdata/marcoschmickler.xcuserdatad/xcschemes/kplayer.xcscheme b/kplayer.xcodeproj/xcuserdata/marcoschmickler.xcuserdatad/xcschemes/kplayer.xcscheme index a384432..f620b0f 100644 --- a/kplayer.xcodeproj/xcuserdata/marcoschmickler.xcuserdatad/xcschemes/kplayer.xcscheme +++ b/kplayer.xcodeproj/xcuserdata/marcoschmickler.xcuserdatad/xcschemes/kplayer.xcscheme @@ -1,10 +1,16 @@ - + version = "1.7"> + + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + + - + + + + + + + diff --git a/kplayer/AppDelegate.swift b/kplayer/AppDelegate.swift index 80cd0d5..a29580f 100644 --- a/kplayer/AppDelegate.swift +++ b/kplayer/AppDelegate.swift @@ -31,42 +31,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele NetworkManager.sharedInstance.wakeLinkstation() - let url = URL(string: NetworkManager.sharedInstance.vidurl)?.appendingPathComponent("ren").appendingPathComponent("kplayer.txt") - - var roots = [MediaItem]() - do { - let remoteroots = try String(contentsOf: url!) - let components = remoteroots.split(separator: "\n") - for c in components { - let line = c.split(separator: " ") - - let name = String(line[0]) - let root = String(line[1]) - - let item = MediaItem(name: name, path:"", root: root, type: ItemType.REMOTEROOT) - roots.append(item) - } - } catch { - } - - let web = MediaItem(name: "web", path:"", root: "/srv/samba/ren/web", type: ItemType.WEBROOT) - web.loaded = true - let google = MediaItem(name: "google", path:"www.google.de", root: "", type: ItemType.PICFOLDER) - google.loaded = true - web.children = [ google ] - let urlPath = Bundle.main.url(forResource: "links", withExtension: "html") - let parser = HtmlParser(url: urlPath) - parser.parse() - - google.children = parser.items - - roots.append(LocalManager.sharedInstance.favorites) - roots.append(MediaItem(name: "extern", path:"", root: "", type: ItemType.FAVROOT)) - roots.append(MediaItem(name: "tags", path:"", root: "", type: ItemType.TAGROOT)) - roots.append(MediaItem(name: "models", path:"models", root: "", type: ItemType.TAGROOT)) - roots.append(web) - - controller.model.items = roots + controller.model.items = LocalManager.sharedInstance.model!.items NetworkManager.sharedInstance.alive() diff --git a/kplayer/PlayerApp.swift b/kplayer/PlayerApp.swift new file mode 100644 index 0000000..77fb8cc --- /dev/null +++ b/kplayer/PlayerApp.swift @@ -0,0 +1,25 @@ +// +// Created by Marco Schmickler on 20.08.23. +// Copyright (c) 2023 Marco Schmickler. All rights reserved. +// + +import Foundation +import SwiftUI + +//@main +struct PlayerApp: App { + let model: MasterModel + + init() { + let del = NetworkDelegate() + model = MasterModel(itemModel: LocalManager.sharedInstance.model!, delegate: del, detailDelegate: del); + } + + var body: some Scene { + WindowGroup { + + MasterSplitView(completionHandler: { + }, model: model); + } + } +} \ No newline at end of file diff --git a/kplayer/core/DatabaseManager.swift b/kplayer/core/DatabaseManager.swift index 1b86435..79be26c 100644 --- a/kplayer/core/DatabaseManager.swift +++ b/kplayer/core/DatabaseManager.swift @@ -15,6 +15,8 @@ class DatabaseManager { var allTags = [String : [String]]() + var currentTag = "" + init() { self.persistentContainer = KPersistentContainer(defaultContainerWithName: "kplayer") self.managedObjectContext = self.persistentContainer.viewContext @@ -368,14 +370,21 @@ rollback() res.append(tag) } - let m = MediaItem(name: "new", path: "new", root: "tags", type: ItemType.TAG) - m.local = true - res.append(m) + if (path != "") { + let m = MediaItem(name: "new", path: "new", root: path, type: ItemType.TAG) + m.local = true + res.append(m) - let c = MediaItem(name: "combine", path: "combine", root: "tags", type: ItemType.TAG) - c.local = true - res.append(c) + } + else { + let m = MediaItem(name: "new", path: "new", root: "tags", type: ItemType.TAG) + m.local = true + res.append(m) + let c = MediaItem(name: "combine", path: "combine", root: "tags", type: ItemType.TAG) + c.local = true + res.append(c) + } completionHandler(res) } diff --git a/kplayer/core/LocalManager.swift b/kplayer/core/LocalManager.swift index 1dc9315..3e96a11 100644 --- a/kplayer/core/LocalManager.swift +++ b/kplayer/core/LocalManager.swift @@ -14,8 +14,52 @@ class LocalManager { var favorites = MediaItem(name: "fav", path: "", root: "", type: ItemType.FAVROOT) + var model : ItemModel? + var externalURL = "" + init() { + model = ItemModel() + + let url = URL(string: NetworkManager.sharedInstance.vidurl)?.appendingPathComponent("ren").appendingPathComponent("kplayer.txt") + + var roots = [MediaItem]() + do { + let remoteroots = try String(contentsOf: url!) + let components = remoteroots.split(separator: "\n") + for c in components { + let line = c.split(separator: " ") + + let name = String(line[0]) + let root = String(line[1]) + + let item = MediaItem(name: name, path:"", root: root, type: ItemType.REMOTEROOT) + roots.append(item) + } + } catch { + } + + let web = MediaItem(name: "web", path:"", root: "/srv/samba/ren/web", type: ItemType.WEBROOT) + web.loaded = true + let google = MediaItem(name: "google", path:"www.google.de", root: "", type: ItemType.PICFOLDER) + google.loaded = true + web.children = [ google ] + let urlPath = Bundle.main.url(forResource: "links", withExtension: "html") + let parser = HtmlParser(url: urlPath) + parser.parse() + + google.children = parser.items + + roots.append(favorites) + roots.append(MediaItem(name: "extern", path:"", root: "", type: ItemType.FAVROOT)) + roots.append(MediaItem(name: "tags", path:"", root: "", type: ItemType.TAGROOT)) + roots.append(MediaItem(name: "models", path:"models", root: "", type: ItemType.TAGROOT)) + roots.append(MediaItem(name: "compilations", path:"compilations", root: "", type: ItemType.TAGROOT)) + roots.append(web) + + model!.items = roots + } + func loadSettings() { do { let jsonData = try FileHelper.getData(name: "settings.json") diff --git a/kplayer/core/MediaItem.swift b/kplayer/core/MediaItem.swift index b0f8e68..97726ab 100644 --- a/kplayer/core/MediaItem.swift +++ b/kplayer/core/MediaItem.swift @@ -11,7 +11,8 @@ import CoreData /** Repräsentiert ein Item eines der festgelegten Typen. */ -class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable { +class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable, Hashable { + var id: String = UUID().uuidString /** Wird durch name, path und root identifiziert. @@ -124,6 +125,25 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable { } } + func hash(into hasher: inout Hasher) { + hasher.combine(id) + } + + static func ==(lhs: MediaItem, rhs: MediaItem) -> Bool { + lhs.id == rhs.id + } + + public func longName() -> String { + if root.starts(with: "/srv/samba/ren") { + let len = "/srv/samba/ren".count + let rootPostfix = (root as NSString).substring(from: len) + return rootPostfix + "/" + path + } + else { + return root + "/" + path + } + } + func toMediaModel() -> MediaModel { var c = [MediaModel]() @@ -301,6 +321,15 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable { return "\(type): \(root) \(path) \(name) (\(index)) Child count \(children.count)" } + func printTree(indent: String = "") { + print(indent + self.debugDescription) + let prefix = " " + indent; + + for c in children { + c.printTree(indent: prefix) + } + } + var encodedDir: String? { let dir = "\(root)/\(path)" diff --git a/kplayer/core/NetworkManager.swift b/kplayer/core/NetworkManager.swift index ebe271d..8bdab57 100644 --- a/kplayer/core/NetworkManager.swift +++ b/kplayer/core/NetworkManager.swift @@ -459,8 +459,8 @@ class NetworkManager { let furl = URL(fileURLWithPath: newfile) let dirUrl = furl.deletingLastPathComponent().path - var line = "mkdir -p " + dirUrl + "; ffmpeg -i '" + file - line += "' -ss " + start + " -t " + length + " -vcodec copy -acodec copy " + newfile + var line = "mkdir -p " + dirUrl + "; ffmpeg " + line += " -ss " + start + " -i '" + file + "' -t " + length + " -vcodec copy -acodec copy " + newfile print(line) let url = nodeurl + "cut?line=" + line.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)! AF.request(url).responseString { response in diff --git a/kplayer/detail/BrowserController.swift b/kplayer/detail/BrowserController.swift deleted file mode 100644 index 6cd60d4..0000000 --- a/kplayer/detail/BrowserController.swift +++ /dev/null @@ -1,390 +0,0 @@ -// -// Created by Marco Schmickler on 2018-11-01. -// Copyright (c) 2018 Marco Schmickler. All rights reserved. -// - -import Foundation -import UIKit -import WebBrowser -import WebKit -import Alamofire -import SwiftUI - -protocol DownloadDelegate { - func killFFMPEG() - - func dlserverlen(result: @escaping (String) -> ()) - func download(url: URL, path: String, result: @escaping (URL) -> () ) - func downloadToServer(path: String, url: URL, result: @escaping (String) -> ()) - - func inProgress() -> Int -} - -protocol ItemController { - func setCurrentItem(item: MediaItem) - func setItems(items: [MediaItem]) - func setCompletionHandler(handler: @escaping (() -> Void)) -} - -class BrowserController : UIViewController, ItemController, WebBrowserDelegate, UINavigationControllerDelegate, WKScriptMessageHandler, WKHTTPCookieStoreObserver { - var completionHandler: (() -> Void)? - - var currentItem : MediaItem? - - var web : WebBrowserViewController? - let config = WKWebViewConfiguration() - - var dl = false - - func setItems(items: [MediaItem]) { - - } - - func setCurrentItem(item: MediaItem) { - currentItem = item - } - - func setCompletionHandler(handler: @escaping (() -> Void)) { - completionHandler = handler - } - - func cookiesDidChange(in cookieStore: WKHTTPCookieStore) { - cookieStore.getAllCookies { cookies in - print(cookies) - } - } - - override func viewDidLoad() { - - let preferences = WKPreferences() - preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") - - config.preferences = preferences - config.allowsInlineMediaPlayback = true - config.allowsAirPlayForMediaPlayback = false - config.userContentController.add(self, name: "openDocument") - config.userContentController.add(self, name: "jsError") - config.setValue(true, forKey: "_allowUniversalAccessFromFileURLs") - - if (currentItem!.name.contains(".x")) { - config.websiteDataStore = WKWebsiteDataStore.nonPersistent() - } - config.websiteDataStore.httpCookieStore.add(self) - - let cookiesStore = config.websiteDataStore.httpCookieStore - let cookieProps: [HTTPCookiePropertyKey : Any] = [ - HTTPCookiePropertyKey.domain: "URL", - HTTPCookiePropertyKey.path: "/", - HTTPCookiePropertyKey.name: "key", - HTTPCookiePropertyKey.value: "value", - HTTPCookiePropertyKey.secure: "TRUE", - HTTPCookiePropertyKey.expires: NSDate(timeIntervalSinceNow: 209000) - ] - cookiesStore.setCookie(HTTPCookie(properties: cookieProps)!) - - let webBrowserViewController = WebBrowserViewController(configuration: config) - web = webBrowserViewController - web?.getWKWebView().customUserAgent = "Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5"; - - webBrowserViewController.delegate = self - - webBrowserViewController.language = .english - // webBrowserViewController.tintColor = ... - // webBrowserViewController.barTintColor = ... - webBrowserViewController.isToolbarHidden = false - webBrowserViewController.isShowActionBarButton = false - webBrowserViewController.toolbarItemSpace = 50 - webBrowserViewController.isShowURLInNavigationBarWhenLoading = true - webBrowserViewController.isShowPageTitleInNavigationBar = true - - // webBrowserViewController.customApplicationActivities = ... - webBrowserViewController.loadURLString(currentItem!.name) - webBrowserViewController.onOpenExternalAppHandler = { [weak self] _ in - guard let `self` = self else { return } - self.completionHandler!() - //self.navigationController?.popViewController(animated: true) - } - let backButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(BrowserController.back(_:))) - let closeButton = UIBarButtonItem(barButtonSystemItem: .close, target: self, action: #selector(BrowserController.close(_:))) - webBrowserViewController.navigationItem.leftBarButtonItems = [backButton, closeButton] - - let reviewButton = UIBarButtonItem(title:"download", style:UIBarButtonItem.Style.plain, target: self, action: #selector(BrowserController.doDownload(_:))) - let dlButton = UIBarButtonItem(title:"server", style:UIBarButtonItem.Style.plain, target: self, action: #selector(BrowserController.doServerDownload(_:))) - - webBrowserViewController.navigationItem.rightBarButtonItems = [dlButton, reviewButton] - - navigationController?.delegate = self - navigationController?.pushViewController(webBrowserViewController, animated: true) - // present(webBrowserViewController, animated: false) - } - - @objc public func doDownload(_ sender: AnyObject) { - dl=false - executeDocumentDownloadScript(webView: web!.getWKWebView(), forAbsoluteUrl: "hello") - } - - @objc public func doServerDownload(_ sender: AnyObject) { - dl=true - executeDocumentDownloadScript(webView: web!.getWKWebView(), forAbsoluteUrl: "hello") - } - - @IBAction func close(_ sender: AnyObject) { - completionHandler!() - } - - @IBAction func back(_ sender: AnyObject) { - if (web!.getWKWebView().canGoBack) { - web!.getWKWebView().goBack() - web!.updateToolBarState() - } - else { - completionHandler!() - } - } - - public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { - debugPrint("did receive message \(message.name)") - - - if (message.name == "openDocument") { - do { - let data = (message.body as! String).data(using: .utf8) - let jsonObject = try JSONSerialization.jsonObject(with: data!, options: []) - handleDocument(jsonObject as! [String]) - } catch { - } - - - - } else if (message.name == "jsError") { - debugPrint(message.body as! String) - } - } - - private func handleDocument(_ strings: [String]) { - print(strings) - - let alertController = UIAlertController(title: "Download", message: "Videos found", preferredStyle: .alert) - - NetworkManager.sharedInstance.dlserverlen { c in - alertController.title = "On Server: \(c)"; - } - - for s in strings { - var name = s - if let u = URL(string: s) { - name = u.lastPathComponent - if s.contains("720") { - name = name + "720 " - } - if s.contains("1080") { - name = name + "1080 " - } - if s.contains("480") { - name = name + "480 " - } - } - - let oneAction = UIAlertAction(title: name, style: .default) { (action) in - self.preview(url: s) - } - alertController.addAction(oneAction) - } - let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in - } - - alertController.addAction(cancelAction) - - web!.present(alertController, animated: true) { - - } - } - - func preview(url: String) { - let url2 = URL(string: url)! - - if (url2.pathExtension == "zip") { - downloadZip(url2, path: "download") - return - } - - if (url2.pathExtension == "jpg") { - downloadZip(url2, path: "images/new") - return - } - - let name = url2.lastPathComponent - let host = currentItem!.name - let hostcomp = host.split(separator: ".") - let site = String(hostcomp[hostcomp.count-2]) - - if ((url2.pathExtension == "mp4" || url2.pathExtension == "m3u8") && dl) { - NetworkManager.sharedInstance.downloadToServer(path: site, url: url2, cookies: nil, result: { - (r) in - print(r) - self.showAlert(title: "download ready", message: r) - if (r == "exists") { - - } - }) - return - } - - let item = MediaItem(name: name, path: name, root: site, type: ItemType.VIDEO) - - if url.starts(with: "/") { - item.externalURL = host + url - } - else { - item.externalURL = url - } - - if hostcomp.count > 2 { - let hostEnd = String(hostcomp[1] + "." + hostcomp[2]) - - getCookieHeader(for: hostEnd) { dictionary in - print(dictionary) - - item.cookies = dictionary - self.showVideo(selectedItem: item) - } - } - else { - showVideo(selectedItem: item) - } - } - - func getCookies(for domain: String? = nil, completion: @escaping ([String : Any])->()) { - let httpCookieStore = config.websiteDataStore.httpCookieStore - var cookieDict = [String : AnyObject]() - httpCookieStore.getAllCookies { cookies in - for cookie in cookies { - if let domain = domain { - if cookie.domain.contains(domain) { - cookieDict[cookie.name] = cookie.properties as AnyObject? - } - } else { - cookieDict[cookie.name] = cookie.properties as AnyObject? - } - } - completion(cookieDict) - } - } - - func getCookieHeader(for domain: String? = nil, completion: @escaping (String)->()) { - let httpCookieStore = config.websiteDataStore.httpCookieStore - var cookieDict = [HTTPCookie]() - httpCookieStore.getAllCookies { cookies in - for cookie in cookies { - if let domain = domain { - if cookie.domain.contains(domain) { - cookieDict.append(cookie) - } - } - } - let values = HTTPCookie.requestHeaderFields(with: cookieDict) - - completion(values["Cookie"]!) - } - } - - - func showVideo(selectedItem: MediaItem) { - var se = selectedItem - var children = [MediaItem]() - var clonedChildren = [MediaItem]() - var baseItem = selectedItem - - if baseItem.type == ItemType.SNAPSHOT { - baseItem = selectedItem.parent! - } - - children = baseItem.children - clonedChildren = baseItem.clone().children - - let model = SVideoModel(allItems: children, currentSnapshot: se, baseItem: baseItem) - - model.edit = LocalManager.sharedInstance.settings.edit - model.loop = LocalManager.sharedInstance.settings.autoloop - model.zoomed = LocalManager.sharedInstance.settings.zoomed - - let player = SVideoPlayer(completionHandler: { saved in - baseItem.children = clonedChildren - - self.dismiss(animated: true, completion: nil); - }, model: model) - player - - let pc = UIHostingController(rootView: player) - pc.view.backgroundColor = .black - - getWindow().rootViewController!.definesPresentationContext = true - pc.modalPresentationStyle = .overCurrentContext - present(pc, animated: true) - } - - func getWindow() -> UIWindow { - let delegate2 = UIApplication.shared.delegate! - return delegate2.window as! UIWindow - } - - private func downloadZip(_ url: URL, path: String) { - NetworkManager.sharedInstance.download(url: url, path: path) { url in - self.showAlert(title: url.lastPathComponent, message: "ready") - } - } - - func webBrowser(_ webBrowser: WebBrowserViewController, didStartLoad url: URL?) { -print(url?.absoluteString) - } - - func webBrowser(_ webBrowser: WebBrowserViewController, didFinishLoad url: URL?) { - } - - func webBrowser(_ webBrowser: WebBrowserViewController, didFailLoad url: URL?, withError error: Error) { - } - - func webBrowserWillDismiss(_ webBrowser: WebBrowserViewController) { - completionHandler!() - } - - func webBrowserDidDismiss(_ webBrowser: WebBrowserViewController) { - completionHandler!() - } - - func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { - - if (animated && viewController == self) { - completionHandler!() - } - } - -// func webBrowser(_ webBrowser: WebBrowserViewController, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) -> Bool { -// let url = navigationAction.request.url -// decisionHandler(.cancel) -// let closure = webBrowser.getWKWebView() -// executeDocumentDownloadScript(webView: closure, forAbsoluteUrl: url!.absoluteString) -// -// return true -// } - - /* - Intercept the download of documents in webView, trigger the download in JavaScript and pass the binary file to JavaScript handler in Swift code - */ - private func executeDocumentDownloadScript(webView: WKWebView, forAbsoluteUrl absoluteUrl : String) { - // TODO: Add more supported mime-types for missing content-disposition headers - do { - let url = NetworkManager.sharedInstance.getDownloadJs() - let js = try String(contentsOf: url, encoding: .utf8) - let j = js.replacingOccurrences(of: "(absoluteUrl)", with: absoluteUrl) - webView.evaluateJavaScript(j) { (result, err) in - if (err != nil) { - debugPrint("JS ERR: \(String(describing: err))") - } - } - } catch { - print(error) - } - - } -} diff --git a/kplayer/detail/DetailView.swift b/kplayer/detail/DetailView.swift new file mode 100644 index 0000000..7397c4b --- /dev/null +++ b/kplayer/detail/DetailView.swift @@ -0,0 +1,45 @@ +// +// Created by Marco Schmickler on 17.08.23. +// Copyright (c) 2023 Marco Schmickler. All rights reserved. +// + +import Foundation +import SwiftUI + +struct DetailView : View { + @ObservedObject var model: MasterModel + @State var hiddenTrigger = false + + let config = [ + GridItem(.flexible(), alignment: .leading) + ] + + let columns = [ + GridItem(.adaptive(minimum: 200)), + ] + + var body: some View { + ScrollView(.vertical, showsIndicators: false) { + ForEach(model.detailItems, id: \.self) { category in + LazyVGrid(columns: columns, spacing: 10, pinnedViews: [.sectionHeaders]) { + Section(header: Text(category.name)) { + ForEach(category.children.count == 0 ? [category] : category.children, id: \.self) { item in + ItemView(category: category, item: item, model: model) + } + } + } + .padding(.horizontal) + } + } + .onAppear { + NotificationCenter.default.addObserver(forName: Notification.Name(rawValue: "loadedItems"), object: nil, queue: nil) { _ in + print("loadedItems notify") + //hiddenTrigger.toggle() + model.objectWillChange.send() + // Handle the notification + } + }.onDisappear { + NotificationCenter.default.removeObserver(self) + } + } +} diff --git a/kplayer/detail/DetailViewController+Show.swift b/kplayer/detail/DetailViewController+Show.swift index 74561c2..bd861ce 100644 --- a/kplayer/detail/DetailViewController+Show.swift +++ b/kplayer/detail/DetailViewController+Show.swift @@ -55,19 +55,6 @@ extension DetailViewController { getWindow().rootViewController!.present(pc, animated: true) } - func showPhotos2(_ im: [MediaItem]) { - let pc = MediaPhotoController() - - pc.items = im - pc.completionHandler = { - self.dismiss(animated: true, completion: nil); - } - let navController = UINavigationController(rootViewController: pc) // Creating a navigation controller with pc at the root of the navigation stack. - navController.modalPresentationStyle = .fullScreen - - self.present(navController, animated: false, completion: nil) - } - func showWeb(selectedItem: MediaItem) { if selectedItem.name.contains("strip") { @@ -90,26 +77,6 @@ extension DetailViewController { getWindow().rootViewController!.present(pc, animated: true) } - func showWeb2(selectedItem: MediaItem) { - if selectedItem.name.contains("strip") { - - let chromeURL = selectedItem.name.replacingOccurrences(of: "https://", with: "googlechrome://") - UIApplication.shared.open(URL(string: chromeURL)!) - - return - } - let pc = BrowserController() - pc.setCurrentItem(item: selectedItem) - - pc.completionHandler = { - self.dismiss(animated: true, completion: nil); - } - let navController = UINavigationController(rootViewController: pc) // Creating a navigation controller with pc at the root of the navigation stack. - navController.modalPresentationStyle = .fullScreen - - self.present(navController, animated: false, completion: nil) - } - func showVideo(selectedItem: MediaItem) { var se = selectedItem var children = [MediaItem]() @@ -138,6 +105,7 @@ extension DetailViewController { model.slow = delegate!.settings().slow model.zoomed = delegate!.settings().zoomed model.jump = delegate!.settings().jump + model.loop = delegate!.settings().autoloop let player = SVideoPlayer(completionHandler: { saved in if saved { diff --git a/kplayer/detail/DetailViewController.swift b/kplayer/detail/DetailViewController.swift index 3d310d4..0b37c99 100644 --- a/kplayer/detail/DetailViewController.swift +++ b/kplayer/detail/DetailViewController.swift @@ -43,6 +43,7 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout var modeButton: UIBarButtonItem? var mode = false + var newDetails = false var detailItem: MediaItem? { didSet { @@ -98,11 +99,12 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout self.collectionView.addGestureRecognizer(lpgr); modeButton = UIBarButtonItem(barButtonSystemItem: .search , target: self, action: #selector(switchMode)); + let renameButton = UIBarButtonItem(barButtonSystemItem: .refresh, target: self, action: #selector(renameItem)); let settingsButton = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(settings)); let overviewButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(overview)); let favButton = UIBarButtonItem(barButtonSystemItem: .bookmarks, target: self, action: #selector(favorites)); let browserButton = UIBarButtonItem(barButtonSystemItem: .organize, target: self, action: #selector(fileBrowser)); - navigationItem.rightBarButtonItems = [settingsButton, favButton, overviewButton,browserButton,modeButton!] + navigationItem.rightBarButtonItems = [settingsButton, favButton, overviewButton,browserButton,modeButton!, renameButton] if detailItem != nil { if detailItem!.children != nil { var d = detailItem!.children @@ -138,6 +140,36 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout } // Edit Settings Button + @objc func renameItem() { + if let item = currentItem { + // renameFolder(item) + } + newDetails = true + let del = NetworkDelegate() + let model = MasterModel(itemModel: LocalManager.sharedInstance.model!, delegate: del, detailDelegate: del); + let view = MasterSplitView(completionHandler: { + self.dismiss(animated: true) + }, model: model); + + let pc = SelfSizingHostingController(rootView: view) + + getWindow().rootViewController!.definesPresentationContext = true + pc.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext + getWindow().rootViewController!.present(pc, animated: true) + } + + func renameFolder(_ item: MediaItem) { + let ac = UIAlertController(title: "Enter new folder name", message: nil, preferredStyle: .alert) + ac.addTextField() + + let submitAction = UIAlertAction(title: "Submit", style: .default) { [unowned ac] _ in + let answer = ac.textFields![0].text! + + item.name = answer + item.path = answer + } + } + @objc func settings() { let kv = KSettingsView(kSettings: LocalManager.sharedInstance.settings, completionHandler: { self.dismiss(animated: true, completion: nil); @@ -175,29 +207,32 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout showAllVideos(d) return - let pc = MediaPhotoController() - - for it in d.children { - if it.children.count > 1 || !showFavoritesOnly { - for c in it.children { - i.append(c) - } - } - } - - pc.items = i - pc.completionHandler = { - self.dismiss(animated: true, completion: nil); - } - let navController = UINavigationController(rootViewController: pc) // Creating a navigation controller with pc at the root of the navigation stack. - navController.modalPresentationStyle = .fullScreen - - present(navController, animated: false, completion: nil) +// let pc = MediaPhotoController() +// +// for it in d.children { +// if it.children.count > 1 || !showFavoritesOnly { +// for c in it.children { +// i.append(c) +// } +// } +// } +// +// pc.items = i +// pc.completionHandler = { +// self.dismiss(animated: true, completion: nil); +// } +// let navController = UINavigationController(rootViewController: pc) // Creating a navigation controller with pc at the root of the navigation stack. +// navController.modalPresentationStyle = UIModalPresentationStyle.fullScreen +// +// present(navController, animated: false, completion: nil) } } @objc func refreshItems(_ notification: Notification) { + if newDetails { + return + } if notification.object == nil { if self.collectionView != nil { self.collectionView.reloadData() diff --git a/kplayer/detail/ItemView.swift b/kplayer/detail/ItemView.swift new file mode 100644 index 0000000..1dfca93 --- /dev/null +++ b/kplayer/detail/ItemView.swift @@ -0,0 +1,22 @@ +// +// Created by Marco Schmickler on 18.08.23. +// Copyright (c) 2023 Marco Schmickler. All rights reserved. +// + +import Foundation +import SwiftUI + +struct ItemView : View { + @ObservedObject var category: MediaItem + @ObservedObject var item: MediaItem + @ObservedObject var model: MasterModel + + var body: some View { + Button(action: { + print("click") + model.showDetails(sectionItem: category, selectedItem: item, categoryItem: category) + }, label: { + AsyncImage(item: item, small: false, placeholder: { Text("Loading ...") }) + }) + } +} diff --git a/kplayer/master/DocPickerViewController.swift b/kplayer/master/DocPickerViewController.swift new file mode 100644 index 0000000..4019ae4 --- /dev/null +++ b/kplayer/master/DocPickerViewController.swift @@ -0,0 +1,45 @@ +// +// Created by Marco Schmickler on 19.08.23. +// Copyright (c) 2023 Marco Schmickler. All rights reserved. +// + +import Foundation +import SwiftUI +import UIKit + +struct DocPickerViewController: UIViewControllerRepresentable { + + var callback: (URL) -> () + private let onDismiss: () -> Void + + init(callback: @escaping (URL) -> (), onDismiss: @escaping () -> Void) { + self.callback = callback + self.onDismiss = onDismiss + } + + func makeCoordinator() -> Coordinator { Coordinator(self) } + + func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext) { + } + + func makeUIViewController(context: Context) -> UIDocumentPickerViewController { + let controller = UIDocumentPickerViewController(forOpeningContentTypes: [.folder]) + controller.allowsMultipleSelection = false + controller.delegate = context.coordinator + return controller + } + + class Coordinator: NSObject, UIDocumentPickerDelegate { + var parent: DocPickerViewController + init(_ pickerController: DocPickerViewController) { + self.parent = pickerController + } + func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { + parent.callback(urls[0]) + parent.onDismiss() + } + func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { + parent.onDismiss() + } + } +} \ No newline at end of file diff --git a/kplayer/master/MasterModel.swift b/kplayer/master/MasterModel.swift new file mode 100644 index 0000000..a11b769 --- /dev/null +++ b/kplayer/master/MasterModel.swift @@ -0,0 +1,262 @@ +// +// Created by Marco Schmickler on 16.08.23. +// Copyright (c) 2023 Marco Schmickler. All rights reserved. +// + +import Foundation +import UIKit +import LocalAuthentication + +class MasterModel : ObservableObject { + init(itemModel: ItemModel, delegate: MasterDelegate, detailDelegate: DetailDelegate) { + self.itemModel = itemModel + self.delegate = delegate + self.detailDelegate = detailDelegate + + items = itemModel.items + detailItems = [MediaItem]() + } + + var itemModel : ItemModel + var delegate: MasterDelegate + var detailDelegate: DetailDelegate + + + @Published var videoModel: SVideoModel = SVideoModel(allItems: [], currentSnapshot: MediaItem(name: "", path: "", root: "", type: .VIDEO), baseItem: MediaItem(name: "", path: "", root: "", type: .VIDEO)) + @Published var photoModel = SPhotoModel(allItems: [MediaItem(name: "", path: "", root: "", type: .PICS)]) + + @Published var showVideo = false + @Published var showPhoto = false + @Published var showFilePicker = false + @Published var showSettings = false + + @Published var selectedItemId : String? + { + didSet { + if let selected = selectedItemId { + if !LocalManager.sharedInstance.authenticated { + // doAuthenticate() + // return + } + + for i in items { + if i.id == selected { + selectedItem = i; + + print(i.name) + + if i.isDetails() { + gotoDetails(i) + return + } + + if (i.isFolder()) { + print(i.path) + + if (i.externalURL == nil && i.type == .FAVROOT) { + + + if i.name == "extern" { + showFilePicker = true + return + } + else { + i.externalURL = FileHelper.getDocumentsDirectory().absoluteString + } + } + //Task { + delegate.loadFolder(selectedItem: i) { + (neu) in + if neu.isFolder() { + self.gotoNextFolder(neu) + } else { + self.gotoDetails(neu) + } + } + // } + } + } + } + } + } + } + + @Published var parentItem = [MediaItem]() + @Published var items : [MediaItem] + @Published var selectedItem : MediaItem? + @Published var selectedDetail : MediaItem? + @Published var detailItems: [MediaItem] + + func back() { + if !parentItem.isEmpty { + parentItem.removeLast() + } + + items = parentItem.last?.children ?? itemModel.items + selectedItemId = nil + selectedItem = nil + } + + private func gotoNextFolder(_ neu: MediaItem) { + DispatchQueue.main.async { + self.selectedItemId = nil + self.selectedItem = nil + + self.parentItem.append(neu) + + self.items = neu.children + + neu.printTree() + } + } + + private func gotoDetails(_ selected: MediaItem) { + let weiter: (MediaItem) -> Void = { + (m) in + // DispatchQueue.main.async { + m.sort() + + NetworkManager.sharedInstance.loadItems(m) + + self.detailItems = m.children + m.printTree() + // } + } + + if (selected.root == "/tags") { + DatabaseManager.sharedInstance.currentTag = selected.name + } + + detailItems = [MediaItem]() + + // Task { + delegate.loadItemDetails(selectedItem: selected, completionHandler: weiter) + // } + } + + func showDetails(sectionItem: MediaItem, selectedItem: MediaItem, categoryItem: MediaItem) { + if sectionItem.isVideo() { + showVideo(selectedItem: selectedItem) + } else if sectionItem.isPic() { + let s = sectionItem.clone() + detailDelegate.loadDetails(selectedItem: s) { + self.showPhotos(s.children, selectedItem: selectedItem, categoryItem: categoryItem) + } + } else if sectionItem.isWeb() { + // showWeb(selectedItem: selectedItem) + } else if sectionItem.type == ItemType.DOWNLOAD { + // showDownload(sectionItem: sectionItem) + } + } + + func showVideo(selectedItem: MediaItem) { + let mode = false + var clonedChildren = [MediaItem]() + selectedDetail = selectedItem + var baseItem = selectedItem + + if baseItem.type == ItemType.SNAPSHOT { + baseItem = selectedItem.parent! + } + + if baseItem.compilation && mode { + baseItem.compilation = false + baseItem.children.removeAll() + baseItem.loaded = false + baseItem.parent = nil + NetworkManager.sharedInstance.loadItem(baseItem, index: 0) + } + + clonedChildren = baseItem.clone().children + + let model = SVideoModel(allItems: clonedChildren, currentSnapshot: selectedItem, baseItem: baseItem) + + model.edit = delegate.settings().edit + model.slow = delegate.settings().slow + model.zoomed = delegate.settings().zoomed + model.jump = delegate.settings().jump + model.loop = delegate.settings().autoloop + + videoModel = model + showVideo = true + } + + func saveVideo(saved: Bool) { + if saved { + if let baseItem=selectedDetail { + baseItem.children = videoModel.allItems + delegate.saveItem(selectedItem: baseItem) + } + } + else { + //baseItem.children = clonedChildren + } + showVideo = false + } + + func showPhotos(_ im: [MediaItem], selectedItem: MediaItem, categoryItem: MediaItem, compilation: Bool = false) { + let base = MediaItem(name: "", path: "", root: "", type: ItemType.PICFOLDER) + base.children = im + if im.count < 1 { + return + } + let model = SPhotoModel(allItems: base.clone().children) + model.selectItem(selectedItem) + model.folderItems = detailItems + + for i in 0...detailItems.count - 1 { + if detailItems[i] === categoryItem { + model.folderIndex = i + break + } + } + + model.favorite = selectedItem.favorite + model.compilation = compilation + + photoModel = model + + showPhoto = true + } + + func pickURL(urlSelect: URL?) { + if let url = urlSelect { + + guard url.startAccessingSecurityScopedResource() else { + // Handle the failure here. + return + } + + selectedItem!.externalURL = url.absoluteString + LocalManager.sharedInstance.externalURL = url.absoluteString + + delegate.loadFolder(selectedItem: selectedItem!) { + (neu) in + if neu.isFolder() { + self.gotoNextFolder(neu) + } else { + self.gotoDetails(neu) + } + } + } + } + + func doAuthenticate() { + let authenticationContext = LAContext() + var error: NSError? + + guard authenticationContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else { + // showAlert(title: "Error", message: "This device does not have a TouchID sensor.") + return; + } + + authenticationContext.evaluatePolicy( + .deviceOwnerAuthentication, + localizedReason: "Only awesome people are allowed", + reply: { (success, error) -> Void in + LocalManager.sharedInstance.authenticated = success + }) + } + + +} diff --git a/kplayer/master/MasterSplitView.swift b/kplayer/master/MasterSplitView.swift new file mode 100644 index 0000000..35dec77 --- /dev/null +++ b/kplayer/master/MasterSplitView.swift @@ -0,0 +1,63 @@ +// +// Created by Marco Schmickler on 16.08.23. +// Copyright (c) 2023 Marco Schmickler. All rights reserved. +// + +import Foundation +import SwiftUI + +struct MasterSplitView: View { + var completionHandler: () -> Void + @ObservedObject var model: MasterModel + + var body: some View { + ZStack { + NavigationSplitView { + + List(model.items, selection: $model.selectedItemId) { item in + Text(item.name).font(.title3).bold() + }.id(UUID()).toolbar { + ToolbarItem(placement: .navigationBarLeading) { + Button(action: model.back, label: { + Image(systemName: "arrowshape.backward") + }) + } + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: { model.showSettings = true }, label: { + Image(systemName: "slider.horizontal.3") + }) + } + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: completionHandler, label: { + Image(systemName: "xmark.square") + }) + } + } + } + detail: { + HStack { + Text(model.selectedItem?.longName() ?? "").font(.title3) + Spacer() + }.background(Color(UIColor.systemGray6)) + DetailView(model: model) + } + + if model.showVideo { + SVideoPlayer(completionHandler: model.saveVideo, model: model.videoModel).background(.black) + } + + if model.showPhoto { + SPhotoAlbumView(completionHandler: { saved in + model.showPhoto = false + }, model: model.photoModel).background(.black) + } + }.sheet(isPresented: $model.showFilePicker, onDismiss: { model.showFilePicker = false}) { + DocPickerViewController(callback: model.pickURL, onDismiss: { model.showFilePicker = false }) + } + .sheet(isPresented: $model.showSettings, onDismiss: { model.showSettings = false}) { + KSettingsView(kSettings: LocalManager.sharedInstance.settings, completionHandler: { + model.showSettings = false + } ) + } + } +} \ No newline at end of file diff --git a/kplayer/master/MasterViewController.swift b/kplayer/master/MasterViewController.swift index 2e640af..30f3e2e 100644 --- a/kplayer/master/MasterViewController.swift +++ b/kplayer/master/MasterViewController.swift @@ -153,9 +153,23 @@ class MasterViewController: UITableViewController, UISearchResultsUpdating, UITa self.performSegue(withIdentifier: "showDetail", sender: self) } + if (selectedItem.root == "/tags") { + DatabaseManager.sharedInstance.currentTag = selectedItem.name + +// if let tags = DatabaseManager.sharedInstance.allTags["compilations"] { +// for t in tags { +// if t == selectedItem.name { +// print(t); +// DatabaseManager.sharedInstance.currentTag = t +// } +// } +// } + } + delegate!.loadItemDetails(selectedItem: selectedItem, completionHandler: weiter) } + func createFolder(_ item: MediaItem) { let ac = UIAlertController(title: "Enter new folder name", message: nil, preferredStyle: .alert) ac.addTextField() @@ -169,6 +183,13 @@ class MasterViewController: UITableViewController, UISearchResultsUpdating, UITa m.local = true item.children.append(m) m.parent = item + } else + if (item.root == "/compilations") { + DatabaseManager.sharedInstance.createTag("c_" + answer, path: "compilations") + let m = MediaItem(name: answer, path: answer, root: "tags", type: ItemType.TAG) + m.local = true + item.children.append(m) + m.parent = item } else { do { try FileHelper.createDir(name: answer) diff --git a/kplayer/master/ServerDownloadDelegate.swift b/kplayer/master/ServerDownloadDelegate.swift deleted file mode 100644 index f65c441..0000000 --- a/kplayer/master/ServerDownloadDelegate.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// Created by Marco Schmickler on 13.11.21. -// Copyright (c) 2021 Marco Schmickler. All rights reserved. -// - -import Foundation - -class ServerDownloadDelegate : DownloadDelegate { - func killFFMPEG() { - NetworkManager.sharedInstance.killFFMPEG() - print("killffmpeg") - } - - func dlserverlen(result: @escaping (String) -> ()) { - NetworkManager.sharedInstance.dlserverlen(result: result) - } - - func download(url: URL, path: String, result: @escaping (URL) -> ()) { - NetworkManager.sharedInstance.download(url: url, path: path, result: result) - } - - func downloadToServer(path: String, url: URL, result: @escaping (String) -> ()) { - NetworkManager.sharedInstance.downloadToServer(path: path, url: url, cookies: nil, result: result) - } - - func inProgress() -> Int { - NetworkManager.sharedInstance.currentDownloads.count - } - -} diff --git a/kplayer/photo/PhotoController.swift b/kplayer/photo/PhotoController.swift deleted file mode 100644 index 7154945..0000000 --- a/kplayer/photo/PhotoController.swift +++ /dev/null @@ -1,423 +0,0 @@ -// -// Created by Marco Schmickler on 04.06.15. -// Copyright (c) 2015 Marco Schmickler. All rights reserved. -// - -import Foundation -import Nimbus -import Alamofire - -/** -NIPhotoScrollView - - if (NIPhotoScrollViewPhotoSizeThumbnail != photoSize) { - // Don't let minScale exceed maxScale. (If the image is smaller than the screen, we - // don't want to force it to be zoomed.) - // todo marco minScale = MIN(minScale, maxScale); - } - -*/ - -class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollViewDataSource, NIPhotoScrubberViewDataSource { - - var items = [MediaItem]() - var completionHandler: (() -> Void)? - - var loadOriginal : ImageLoadOperation? - var loadNext : ImageLoadOperation? - var nextImage : UIImage? - var nextImageIndex = 0 - - var slide = 0 - - var timer: Timer? - - var thumbnails: ThumbnailCache? - - lazy var operationQueue: OperationQueue = { - var queue = OperationQueue() - queue.name = "Photo queue" - queue.maxConcurrentOperationCount = 1 - return queue - }() - - override func viewDidDisappear(_ animated: Bool) { - operationQueue.cancelAllOperations() - } - - override func setChromeTitle() { - let idx = photoAlbumView.centerPageIndex - if (items.count > idx) { - let selected = items[idx] - title = "(\(idx + 1) / \(photoAlbumView.numberOfPages)) \(selected.path) \(selected.name)" - } - } - - override func viewDidLoad() { - super.viewDidLoad() - - let backButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(MediaPhotoController.back)) - let slideButton = UIBarButtonItem(barButtonSystemItem: .fastForward, target: self, action: #selector(MediaPhotoController.slideShow)) - navigationItem.leftBarButtonItems = [backButton, slideButton] - - let playButton = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(MediaPhotoController.play)) - let shotButton = UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: #selector(MediaPhotoController.shot)) - navigationItem.rightBarButtonItems = [playButton, shotButton] - - setChromeVisibility(true, animated: true) - - thumbnails = ThumbnailCache(items: items, refresh: { - () -> Void in - self.photoScrubberView.reloadData(); - }); - - self.photoAlbumView.reloadData(); - - pagingScrollViewDidChangePages(photoAlbumView) - } - - override func didReceiveMemoryWarning() { - print("warning") - thumbnails?.cancel() - - super.didReceiveMemoryWarning() - } - - @objc func shot() { - let currentItem = items[photoAlbumView.centerPageIndex] - var imageUrl = currentItem.thumbUrl!.replacingOccurrences(of: "_thumb.jpg", with: ".jpg") - imageUrl = imageUrl.replacingOccurrences(of: "?preview=true", with: "") - - if imageUrl.starts(with: "file://") { - - let pages = photoAlbumView.visiblePages()! - for case let page as NIPhotoScrollView in pages { - if (page.pageIndex == photoAlbumView.centerPageIndex) { - let scroll = page.value(forKey: "scrollView") as! UIScrollView - - if scroll.isScrollEnabled { - currentItem.scale = Double(scroll.zoomScale) - currentItem.offset = scroll.contentOffset - currentItem.size = scroll.contentSize - - let jsonFile = currentItem.path + "/" + currentItem.name.replacingOccurrences(of: ".jpg", with: ".json") - let url = FileHelper.getDocumentsDirectory().appendingPathComponent(jsonFile) - LocalManager.sharedInstance.saveFavDir(url: url, item: currentItem) - // print(currentItem.toJSON()) - - scroll.isScrollEnabled = false - } - else { - scroll.isScrollEnabled = true - } - } - } - - - } - else { - let url = NetworkManager.sharedInstance.baseurl + "/service/linkfavpic" + imageUrl - - print(url) - AF.request(url).responseString { - (result) in - print("ok") - } - } - } - - @objc func back() { - if let t = timer { - t.invalidate() - } - - operationQueue.cancelAllOperations() - - thumbnails?.cancel(); - - completionHandler!() - } - - @objc func slideShow() { - slide += 1 - if (slide > 2) { - slide = 0 - } - - if timer == nil { - showItem() - } - } - - @objc func showItem() { - var nextItem = photoAlbumView.centerPageIndex + 1 - - if (nextItem >= (items).count) { - nextItem = 0 - } - - photoAlbumView.moveToPage(at: nextItem, animated: false); - photoScrubberView.setSelectedPhotoIndex(nextItem, animated: true) - pagingScrollViewDidChangePages(photoAlbumView) - - } - - @objc func play() { - let currentItem = items[photoAlbumView.centerPageIndex] - - if (currentItem.type == ItemType.PICS) { - let items = currentItem - - let len = items.root.count - let url = NetworkManager.sharedInstance.nodeurl + "listfiles" + items.root + "/" + items.path + "/" + items.name - - print(items) - print(url) - - AF.request(url).responseJSON { - (response) in - - var im = [MediaItem]() - - if let json = response.value { - - for s in json as! [String] { - if s.hasSuffix(".jpg") { - let l = s.count - let name = NSURL(fileURLWithPath: s).lastPathComponent! - var pathlen = l - len - name.count - -// if (pathlen > 1000) { - print(pathlen) - print(name) - print(s) -// } - if (pathlen < 2) { - pathlen = 2 - } - - let path = (s as NSString).substring(with: NSMakeRange(len + 1, pathlen - 2)) - - let folderName = NSURL(fileURLWithPath: path).lastPathComponent! - let fl = path.length() - let pfl = fl - folderName.length() - - print("\(folderName) \(pfl)") - let fpath = s.substringLeft(pfl) - - let i = MediaItem(name: folderName, path: fpath, root: items.root, type: ItemType.PICS) - i.thumbUrl = "\(s)?preview=true" - if !name.hasPrefix(".") { - im.append(i) - } - } - } - - let pc = MediaPhotoController() - pc.items = im - pc.completionHandler = { - self.dismiss(animated: true, completion: nil); - } - let navController = UINavigationController(rootViewController: pc) // Creating a navigation controller with pc at the root of the navigation stack. - - self.present(navController, animated: false, completion: nil) - } - } - return - } - } - - override func loadView() { - super.loadView() - photoAlbumView.dataSource = self - photoScrubberView.dataSource = self - - isToolbarTranslucent = true - hidesChromeWhenScrolling = true - chromeCanBeHidden = true - isScrubberEnabled = true - - - // Toolbar Setup - let bounds = self.view.bounds; - let toolbarHeight = CGFloat(120.0) - toolbar.frame = CGRect(x: 0, y: bounds.size.height - toolbarHeight, width: bounds.size.width, height: toolbarHeight) - photoAlbumView.isZoomingAboveOriginalSizeEnabled = true; - -// This title will be displayed until we get the results back for the album information. - self.title = "loading" - -// self.photoAlbumView.loadingImage = UIImage(named: "Kirschkeks-256x256.png") - print("\(items.count)") - } - - func photoAlbumScrollView(_ photoAlbumScrollView: NIPhotoAlbumScrollView!, photoAt photoAtIndex: Int, photoSize: UnsafeMutablePointer, - isLoading: UnsafeMutablePointer, originalPhotoDimensions: UnsafeMutablePointer) -> UIImage! { - let newItem = items[photoAtIndex] - let u1 = URL(string: newItem.imageUrlAbsolute) - let u2 = URL(string: newItem.thumbUrlAbsolute) - if let hqURL = u1, let u5 = u2 { - - var image: UIImage? = nil - - var size = NIPhotoScrollViewPhotoSizeUnknown - - image = thumbnails?.getThumbnail(newItem) - - if image != nil { - size = NIPhotoScrollViewPhotoSizeThumbnail - isLoading[0] = false - } else { - let thumbnail: (UIImage, Int) -> () = { (i: UIImage, thumbnailIndex: Int) in - self.photoAlbumView.didLoadPhoto(i, at: photoAtIndex, photoSize: NIPhotoScrollViewPhotoSizeThumbnail) - self.photoScrubberView.didLoadThumbnail(i, at: thumbnailIndex) - } - - let image = thumbnails?.loadThumbnail(thumbnailIndex: photoAtIndex, thumbnail: thumbnail) - } - - if (image == nil) { - isLoading[0] = true - } - - photoSize[0] = size - - return image - } else { - print("## Invalid URL: \(newItem.imageUrlAbsolute)") - - return nil - } - } - - public override func pagingScrollViewDidChangePages(_ pagingScrollView: NIPagingScrollView!) { - setChromeTitle() - - let currentIndex: Int = self.photoAlbumView.centerPageIndex - let hqURL = URL(string: items[currentIndex].imageUrlAbsolute)! - - if let op = loadOriginal { - op.cancel() - loadOriginal = nil - } - - let view2 = photoAlbumView.centerPageView() as! NIPhotoScrollView - restoreScrollState(currentIndex: currentIndex, view: view2) - - if view2.photoSize() != NIPhotoScrollViewPhotoSizeOriginal { - if nextImage != nil && currentIndex == nextImageIndex { - self.photoAlbumView.didLoadPhoto(nextImage!, at: currentIndex, photoSize: NIPhotoScrollViewPhotoSizeOriginal) - nextImage = nil - } - else { - let op2 = ImageLoadOperation(imageURL: hqURL, succeeder: { - i in - // self.photoAlbumView.isZoomingAboveOriginalSizeEnabled = max(i.size.height, i.size.width) <= 6000; - self.photoAlbumView.didLoadPhoto(i, at: currentIndex, photoSize: NIPhotoScrollViewPhotoSizeOriginal) - self.restoreScrollState(currentIndex: currentIndex, view: view2) - }, index: currentIndex) - loadOriginal = op2 - op2.qualityOfService = QualityOfService.userInitiated - operationQueue.addOperation(op2) - } - } - - if currentIndex + 1 < items.count { - if let op = loadNext { - op.cancel() - loadNext = nil - } - - if let image = thumbnails?.getThumbnail(items[currentIndex+1]) { - self.photoAlbumView.didLoadPhoto(image, at: currentIndex+1, photoSize: NIPhotoScrollViewPhotoSizeThumbnail) - } - - let hqURL2 = URL(string: items[currentIndex+1].imageUrlAbsolute)! - nextImage = nil - - let op3 = ImageLoadOperation(imageURL: hqURL2, succeeder: { - i in - self.nextImage = i - self.nextImageIndex = currentIndex + 1 - - if (self.slide > 0) { - self.timer = Timer.scheduledTimer(timeInterval: Double(self.slide) / 2, target: self, selector: #selector(self.showItem), userInfo: nil, repeats: false) - } else { - self.timer = nil - } - }, index: currentIndex) - loadNext = op3 - op3.qualityOfService = QualityOfService.userInitiated - operationQueue.addOperation(op3) - } - - let oldIndex = currentIndex - 1; - - if (oldIndex >= 0) { - let newItem = items[oldIndex] - if let image = thumbnails?.getThumbnail(newItem) { - self.photoAlbumView.didLoadPhoto(image, at: oldIndex, photoSize: NIPhotoScrollViewPhotoSizeThumbnail) - } - } - - } - - private func restoreScrollState(currentIndex: Int, view: NIPhotoScrollView) { - let item = items[currentIndex] - - if item.scale > 0.0 { - // view.setValue(false, forKey: "zoomingIsEnabled") - let scroll = view.value(forKey: "scrollView") as! UIScrollView - scroll.zoomScale = CGFloat(item.scale) - scroll.contentSize = item.size - scroll.contentOffset = item.offset - scroll.isScrollEnabled = false - } - } - - func numberOfPages(in pagingScrollView: NIPagingScrollView) -> Int { - let c = items.count - return c - } - -/** - * Fetches a page that will be displayed at the given page index. - * - * You should always try to reuse pages by calling dequeueReusablePageWithIdentifier: on the - * paging scroll view before allocating a new page. - */ - func pagingScrollView(_ pagingScrollView: NIPagingScrollView, pageViewFor pageViewForIndex: Int) -> (UIView & NIPagingScrollViewPageProtocol)! { - let view = photoAlbumView.pagingScrollView(pagingScrollView, pageViewFor: pageViewForIndex) as! NIPhotoScrollView - - // view.maximumScale = 2; - - - return view; - } - - func numberOfPhotos(in photoScrubberView: NIPhotoScrubberView!) -> Int { - let c = items.count - return c - } - - /** - * Fetch the thumbnail image for the given photo index. - * - * Please read and understand the performance considerations for this data source. - */ - func photoScrubberView(_ photoScrubberView: NIPhotoScrubberView!, thumbnailAt thumbnailIndex: Int) -> UIImage! { - if thumbnailIndex < 0 { - return nil - } - let thumbnail: (UIImage, Int) -> () = { (i: UIImage, thumbnailIndex: Int) in - self.photoScrubberView.didLoadThumbnail(i, at: thumbnailIndex) - } - - let image = thumbnails?.loadThumbnail(thumbnailIndex: thumbnailIndex, thumbnail: thumbnail) - - return image - } - - -} - diff --git a/kplayer/photo/SPhotoAlbumView.swift b/kplayer/photo/SPhotoAlbumView.swift index 6d844f2..7dc8885 100644 --- a/kplayer/photo/SPhotoAlbumView.swift +++ b/kplayer/photo/SPhotoAlbumView.swift @@ -71,11 +71,11 @@ struct SPhotoAlbumView: View { } else if more { v.overlay(VStack { KToggleButton(text: "spring", binding: $model.spring).frame(height: 30) -// Button(action: { -// saveSelectedItem() -// }, label: { -// Text("save") -// }) + Button(action: { + saveSelectedItem() + }, label: { + Text("save") + }) .buttonStyle(BorderlessButtonStyle()) } .frame(width: 60, alignment: .top).offset(x: 0, y: 70), alignment: .topLeading) diff --git a/kplayer/server/raspberrypi.js b/kplayer/server/raspberrypi.js index 61fdd10..0cb91bd 100644 --- a/kplayer/server/raspberrypi.js +++ b/kplayer/server/raspberrypi.js @@ -13,8 +13,7 @@ app.get('/', function(req, res) { res.json({ message: 'WELCOME' }); }); -app.get('/wakelinkstation', function (req, res) { - var cmd = '/srv/raspi/bin/wakeup-linkstation.sh' +function execute(cmd, res) { console.log(cmd) exec(cmd, (err, stdout, stderr) => { if (err) { @@ -28,23 +27,26 @@ app.get('/wakelinkstation', function (req, res) { console.log(`stderr: ${stderr}`); }); res.send("ok") +} + +app.get('/wakelinkstation', function (req, res) { + var cmd = '/srv/raspi/bin/wakeup-linkstation.sh' + execute(cmd, res); }) app.get('/suspendlinkstation', function (req, res) { var cmd = '/srv/raspi/bin/suspend-linkstation.sh' - console.log(cmd) - exec(cmd, (err, stdout, stderr) => { - if (err) { - console.log(err) - // node couldn't execute the command - return; - } + execute(cmd, res) +}) - // the *entire* stdout and stderr (buffered) - console.log(`stdout: ${stdout}`); - console.log(`stderr: ${stderr}`); - }); - res.send("ok") +app.get('/wakeimac', function (req, res) { + var cmd = '/srv/raspi/bin/wakeup-imac.sh' + execute(cmd, res); +}) + +app.get('/suspendimac', function (req, res) { + var cmd = '/srv/raspi/bin/suspend-imac.sh' + execute(cmd, res) }) var server = app.listen(8081, function () { diff --git a/kplayer/util/AsyncImage.swift b/kplayer/util/AsyncImage.swift index 5f25570..ee35a10 100644 --- a/kplayer/util/AsyncImage.swift +++ b/kplayer/util/AsyncImage.swift @@ -5,14 +5,17 @@ struct AsyncImage: View { @StateObject private var item: MediaItem private let placeholder: Placeholder private let image: (UIImage) -> Image + let small : Bool init( item: MediaItem, + small: Bool = true, @ViewBuilder placeholder: () -> Placeholder, @ViewBuilder image: @escaping (UIImage) -> Image = Image.init(uiImage:) ) { self.placeholder = placeholder() self.image = image + self.small = small _item = StateObject(wrappedValue: item) setImage(newItem: item) @@ -26,7 +29,12 @@ struct AsyncImage: View { private var content: some View { Group { if item.thumbImage != nil { - image(item.thumbImage!.scaleToSize(66.0, height: 44.0)) + if small { + image(item.thumbImage!.scaleToSize(66.0, height: 44.0)) + } + else { + image(item.thumbImage!.scaleToSize(15 * 16, height: 15 * 9)) + } } else { placeholder } diff --git a/kplayer/video/SVideoPlayer.swift b/kplayer/video/SVideoPlayer.swift index a2e07a2..691762b 100644 --- a/kplayer/video/SVideoPlayer.swift +++ b/kplayer/video/SVideoPlayer.swift @@ -42,6 +42,12 @@ struct SVideoPlayer: View, EditItemDelegate { @State var xoffs = 0.0 @State var rotazero = -1000.0 + @State var cutFlag = false + @State var lores = false + @State var second = false + @State var secondScale = 0.75 + @State var secondOffset = CGSize(width: -70, height: 50) + @State var orientation = UIDevice.current.orientation let orientationChanged = NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification) @@ -111,6 +117,21 @@ struct SVideoPlayer: View, EditItemDelegate { KToggleButton(text: "\(relative())", binding: $more) Button(action: { + let tag = DatabaseManager.sharedInstance.currentTag + if tag != "" { + let item = model.currentSnapshot + if item.tags.contains(tag) { + item.tags.removeAll(where: { toRemove in toRemove == tag }) + } else { + item.tags.append(tag) + } + model.dirty = true + } + }, label: { + Text(DatabaseManager.sharedInstance.currentTag) + }).foregroundColor(model.currentSnapshot.tags.contains(DatabaseManager.sharedInstance.currentTag) ? Color.yellow : Color.blue) + + Button(action: { model.favorite.toggle() model.dirty = true }, label: { @@ -195,12 +216,21 @@ struct SVideoPlayer: View, EditItemDelegate { .offset(small ? CGSize.zero : model.dragOffset).modifier(KAnimate(dragOffset: model.dragOffset, spring: false)).offset(x: xoffs, y: 0) .onTapGesture(count: 2) { print("3 tapped!") - if model.scale == 1 { + second = !second + if second { model.scale = lastScale } else { lastScale = model.scale - model.scale = 1 - model.dragOffset = CGSize.zero + + if (lores) { + model.scale = secondScale + model.dragOffset = secondOffset + } + else { + model.scale = 1 + model.dragOffset = CGSize.zero + } + } } .gesture( @@ -227,6 +257,9 @@ struct SVideoPlayer: View, EditItemDelegate { .onEnded { val in // without this the next gesture will be broken self.lastScaleValue = 1.0 + if let geo = model.proxy { + print("geo \(geo.size.height)"); + } }) .contentShape(Rectangle()) @@ -263,6 +296,7 @@ struct SVideoPlayer: View, EditItemDelegate { KToggleButton(text: "loop", binding: $model.loop).frame(height: 30) KToggleButton(text: "flip", binding: $upsidedown).frame(height: 30) + KToggleButton(text: "lores", binding: $lores).frame(height: 30) } Button(action: { @@ -332,7 +366,7 @@ struct SVideoPlayer: View, EditItemDelegate { } Button(action: { cut() }) { Text("cut") - } + }.foregroundColor(cutFlag ? Color.yellow : Color.blue) .frame(height: 30).buttonStyle(BorderlessButtonStyle()) } @@ -402,7 +436,7 @@ struct SVideoPlayer: View, EditItemDelegate { let controlsView = VideoPlayerControlsView(model: model, player: player) - if model.scale <= 1.0 { + if !second { controlsView } else { controlsView.hidden() @@ -469,7 +503,7 @@ struct SVideoPlayer: View, EditItemDelegate { if timeSlomoCounter >= 1 { timeSlomoCounter -= 1 } - if model.loop && model.currentSnapshot.length > 0 { + if model.loop && !model.paused && model.currentSnapshot.length > 0 { if time.seconds > model.currentSnapshot.time + model.currentSnapshot.length { seekTime(model.currentSnapshot.time) } @@ -572,15 +606,15 @@ struct SVideoPlayer: View, EditItemDelegate { } if (start.y < 170) { - let delta = (dragged.width + dragged.height) / 400.0 + let delta = (dragged.width + dragged.height) / 200.0 seekTimeSmoothly(smoothTime + delta) return false } else { - if model.scale != 1.0 || small { + if second || small { return true } else { - let delta = (dragged.width + dragged.height) / 400.0 + let delta = (dragged.width + dragged.height) / 200.0 seekTimeSmoothly(smoothTime + delta) return false @@ -606,14 +640,29 @@ struct SVideoPlayer: View, EditItemDelegate { return false } + if dragged.height < -100 && model.jump { + if timeCounter == 0 { + if let i = model.allItems.index(where: { m in m === model.currentSnapshot }) { + if i - 1 >= 0 { + gotoSnapshot(model.allItems[i - 1]) + } else { + gotoSnapshot(model.allItems[model.allItems.count-1]) + } + timeCounter = 50 + print("jump") + } + } + return false + } + if let time = getCurrentTime() { let dragWidth = 20.0 if !model.seeking { - if (model.scale > 1.0 || small) && start.y > 200 { + if (second || small) && start.y > 300 { return true } - if (model.slow) { + if (model.slow || second) { if dragged.width > dragWidth { seekTime(time + 5.0) } else if dragged.width < -dragWidth { @@ -748,6 +797,8 @@ struct SVideoPlayer: View, EditItemDelegate { } model.height = Int(height) + lores = (height <= 1080) && (height*1.5 < heightSpace) + var f = height / heightSpace print("h \(height) \(heightSpace) \(f)") @@ -765,6 +816,20 @@ struct SVideoPlayer: View, EditItemDelegate { model.dragOffset.width = 0 model.dragOffset.height = 0 } + else { + if (model.scale != 1) { + lastScale = model.scale + } + + if (lores) { + model.scale = secondScale + model.dragOffset = secondOffset + } + else { + model.scale = 1 + model.dragOffset = CGSize.zero + } + } } } @@ -851,6 +916,7 @@ struct SVideoPlayer: View, EditItemDelegate { func cut() { NetworkManager.sharedInstance.cutItem(model.currentSnapshot) + cutFlag = true } func truncate() { diff --git a/kplayer/video/VideoPlayerView.swift b/kplayer/video/VideoPlayerView.swift index 0a019bb..1a293f0 100644 --- a/kplayer/video/VideoPlayerView.swift +++ b/kplayer/video/VideoPlayerView.swift @@ -138,11 +138,30 @@ struct VideoPlayerControlsView : View { Slider(value: $model.videoPos, in: 0...1, onEditingChanged: sliderEditingChanged) // Video duration Text("\(Utility.formatSecondsToHMS(model.videoDuration))").foregroundColor(Color.white) + Button(action: setEnd) { + Text("end") + .padding(.trailing, 20).foregroundColor(model.currentSnapshot.length > 0 ? Color.yellow : Color.blue) + } } .padding(.leading, 10) .padding(.trailing, 10) } + func setEnd() { + if let time = player.currentItem?.currentTime().seconds { + let snapTime = model.currentSnapshot.time + if time > snapTime { + model.currentSnapshot.length = time - snapTime + } + else { + if (model.paused) { + model.currentSnapshot.time = time + } + } + model.dirty = true + } + } + private func moveBack() { let time = player.currentTime().seconds - 5.0;