├── LICENSE
├── PhotoBrowser.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── PhotoBrowser.xccheckout
│ └── xcuserdata
│ │ └── Charlin.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── Charlin.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── PhotoBrowser.xcscheme
│ └── xcschememanagement.plist
├── PhotoBrowser
├── AppDelegate.swift
├── DisplayVC+Host.swift
├── DisplayVC+Local.swift
├── DisplayVC.swift
├── DisplayView.swift
├── Frameworks
│ ├── CFSnapKit
│ │ ├── CFSnapKit.swift
│ │ └── Source
│ │ │ ├── Constraint.swift
│ │ │ ├── ConstraintAttributes.swift
│ │ │ ├── ConstraintConfig.swift
│ │ │ ├── ConstraintConstantTarget.swift
│ │ │ ├── ConstraintDSL.swift
│ │ │ ├── ConstraintDescription.swift
│ │ │ ├── ConstraintInsetTarget.swift
│ │ │ ├── ConstraintInsets.swift
│ │ │ ├── ConstraintItem.swift
│ │ │ ├── ConstraintLayoutGuide+Extensions.swift
│ │ │ ├── ConstraintLayoutGuide.swift
│ │ │ ├── ConstraintLayoutGuideDSL.swift
│ │ │ ├── ConstraintLayoutSupport.swift
│ │ │ ├── ConstraintLayoutSupportDSL.swift
│ │ │ ├── ConstraintMaker.swift
│ │ │ ├── ConstraintMakerEditable.swift
│ │ │ ├── ConstraintMakerExtendable.swift
│ │ │ ├── ConstraintMakerFinalizable.swift
│ │ │ ├── ConstraintMakerPriortizable.swift
│ │ │ ├── ConstraintMakerRelatable.swift
│ │ │ ├── ConstraintMultiplierTarget.swift
│ │ │ ├── ConstraintOffsetTarget.swift
│ │ │ ├── ConstraintPriority.swift
│ │ │ ├── ConstraintPriorityTarget.swift
│ │ │ ├── ConstraintRelatableTarget.swift
│ │ │ ├── ConstraintRelation.swift
│ │ │ ├── ConstraintView+Extensions.swift
│ │ │ ├── ConstraintView.swift
│ │ │ ├── ConstraintViewDSL.swift
│ │ │ ├── Debugging.swift
│ │ │ ├── Info.plist
│ │ │ ├── LayoutConstraint.swift
│ │ │ ├── LayoutConstraintItem.swift
│ │ │ ├── SnapKit.h
│ │ │ └── UILayoutSupport+Extensions.swift
│ ├── Haneke
│ │ ├── CGSize+Swift.swift
│ │ ├── Cache.swift
│ │ ├── CryptoSwiftMD5.swift
│ │ ├── Data.swift
│ │ ├── DiskCache.swift
│ │ ├── DiskFetcher.swift
│ │ ├── Fetch.swift
│ │ ├── Fetcher.swift
│ │ ├── Format.swift
│ │ ├── Haneke.h
│ │ ├── Haneke.swift
│ │ ├── Info-iOS.plist
│ │ ├── Info-tvOS.plist
│ │ ├── Log.swift
│ │ ├── NSFileManager+Haneke.swift
│ │ ├── NSHTTPURLResponse+Haneke.swift
│ │ ├── NSURLResponse+Haneke.swift
│ │ ├── NetworkFetcher.swift
│ │ ├── String+Haneke.swift
│ │ ├── UIButton+Haneke.swift
│ │ ├── UIImage+Haneke.swift
│ │ ├── UIImageView+Haneke.swift
│ │ └── UIView+Haneke.swift
│ └── NVActivityIndicatorView
│ │ ├── Animations
│ │ ├── NVActivityIndicatorAnimationAudioEqualizer.swift
│ │ ├── NVActivityIndicatorAnimationBallBeat.swift
│ │ ├── NVActivityIndicatorAnimationBallClipRotate.swift
│ │ ├── NVActivityIndicatorAnimationBallClipRotateMultiple.swift
│ │ ├── NVActivityIndicatorAnimationBallClipRotatePulse.swift
│ │ ├── NVActivityIndicatorAnimationBallGridBeat.swift
│ │ ├── NVActivityIndicatorAnimationBallGridPulse.swift
│ │ ├── NVActivityIndicatorAnimationBallPulse.swift
│ │ ├── NVActivityIndicatorAnimationBallPulseRise.swift
│ │ ├── NVActivityIndicatorAnimationBallPulseSync.swift
│ │ ├── NVActivityIndicatorAnimationBallRotate.swift
│ │ ├── NVActivityIndicatorAnimationBallRotateChase.swift
│ │ ├── NVActivityIndicatorAnimationBallScale.swift
│ │ ├── NVActivityIndicatorAnimationBallScaleMultiple.swift
│ │ ├── NVActivityIndicatorAnimationBallScaleRipple.swift
│ │ ├── NVActivityIndicatorAnimationBallScaleRippleMultiple.swift
│ │ ├── NVActivityIndicatorAnimationBallSpinFadeLoader.swift
│ │ ├── NVActivityIndicatorAnimationBallTrianglePath.swift
│ │ ├── NVActivityIndicatorAnimationBallZigZag.swift
│ │ ├── NVActivityIndicatorAnimationBallZigZagDeflect.swift
│ │ ├── NVActivityIndicatorAnimationBlank.swift
│ │ ├── NVActivityIndicatorAnimationCubeTransition.swift
│ │ ├── NVActivityIndicatorAnimationLineScale.swift
│ │ ├── NVActivityIndicatorAnimationLineScaleParty.swift
│ │ ├── NVActivityIndicatorAnimationLineScalePulseOut.swift
│ │ ├── NVActivityIndicatorAnimationLineScalePulseOutRapid.swift
│ │ ├── NVActivityIndicatorAnimationLineSpinFadeLoader.swift
│ │ ├── NVActivityIndicatorAnimationOrbit.swift
│ │ ├── NVActivityIndicatorAnimationPacman.swift
│ │ ├── NVActivityIndicatorAnimationSemiCircleSpin.swift
│ │ ├── NVActivityIndicatorAnimationSquareSpin.swift
│ │ └── NVActivityIndicatorAnimationTriangleSkewSpin.swift
│ │ ├── NVActivityIndicatorAnimationDelegate.swift
│ │ ├── NVActivityIndicatorPresenter.swift
│ │ ├── NVActivityIndicatorShape.swift
│ │ ├── NVActivityIndicatorView.h
│ │ ├── NVActivityIndicatorView.swift
│ │ └── NVActivityIndicatorViewable.swift
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── LaunchImage-2.launchimage
│ │ └── Contents.json
│ ├── LaunchImage.launchimage
│ │ └── Contents.json
│ └── Local
│ │ ├── 1.imageset
│ │ ├── 1.jpg
│ │ └── Contents.json
│ │ ├── 10.imageset
│ │ ├── 10.jpg
│ │ └── Contents.json
│ │ ├── 2.imageset
│ │ ├── 2.jpg
│ │ └── Contents.json
│ │ ├── 3.imageset
│ │ ├── 3.jpg
│ │ └── Contents.json
│ │ ├── 4.imageset
│ │ ├── 4.jpg
│ │ └── Contents.json
│ │ ├── 5.imageset
│ │ ├── 5.jpg
│ │ └── Contents.json
│ │ ├── 6.imageset
│ │ ├── 6.jpg
│ │ └── Contents.json
│ │ ├── 7.imageset
│ │ ├── 7.jpg
│ │ └── Contents.json
│ │ ├── 8.imageset
│ │ ├── 8.jpg
│ │ └── Contents.json
│ │ └── 9.imageset
│ │ ├── 9.jpg
│ │ └── Contents.json
├── Info.plist
├── LangVC.swift
├── LaunchScreen.xib
├── Main.storyboard
├── PhotoBrowser
│ ├── Common
│ │ ├── PhotoBrowser+Common.swift
│ │ └── pic.bundle
│ │ │ ├── cancel@2x.png
│ │ │ ├── cancel@3x.png
│ │ │ ├── save@2x.png
│ │ │ └── save@3x.png
│ ├── Controller
│ │ ├── PhotoBrowser+CollectionViewExtend.swift
│ │ ├── PhotoBrowser+HUD.swift
│ │ ├── PhotoBrowser+Indicator.swift
│ │ ├── PhotoBrowser+Main.swift
│ │ ├── PhotoBrowser+PBType.swift
│ │ └── PhotoBrowser+ZoomAnim.swift
│ ├── Layout
│ │ └── Layout.swift
│ ├── Model
│ │ └── PhotoBrowser+Model.swift
│ ├── PhotoBrowser.swift
│ └── View
│ │ ├── CollectionView.swift
│ │ ├── ItemCell.swift
│ │ ├── ItemCell.xib
│ │ └── ShowImageView.swift
├── PhotoTypeChooseVC.swift
├── PhotoTypeChooseVC.xib
└── ShowTypeChooseTVC.swift
├── PhotoBrowserTests
├── Info.plist
└── PhotoBrowserTests.swift
├── README.md
└── README_CH.md
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013-2014
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/PhotoBrowser.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PhotoBrowser.xcodeproj/project.xcworkspace/xcshareddata/PhotoBrowser.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 562BD118-C22B-4968-9336-D700C8D60A84
9 | IDESourceControlProjectName
10 | PhotoBrowser
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 234351B82CAB484320AFDFB8097FA765FB356BBF
14 | https://github.com/nsdictionary/PhotoBrowser.git
15 |
16 | IDESourceControlProjectPath
17 | PhotoBrowser.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | 234351B82CAB484320AFDFB8097FA765FB356BBF
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/nsdictionary/PhotoBrowser.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | 234351B82CAB484320AFDFB8097FA765FB356BBF
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | 234351B82CAB484320AFDFB8097FA765FB356BBF
36 | IDESourceControlWCCName
37 | PhotoBrowser
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/PhotoBrowser.xcodeproj/project.xcworkspace/xcuserdata/Charlin.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser.xcodeproj/project.xcworkspace/xcuserdata/Charlin.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/PhotoBrowser.xcodeproj/xcuserdata/Charlin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/PhotoBrowser.xcodeproj/xcuserdata/Charlin.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | PhotoBrowser.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 89CA44421B7F96030061FEFC
16 |
17 | primary
18 |
19 |
20 | 89CA44571B7F96030061FEFC
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/PhotoBrowser/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 冯成林 on 15/8/14.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 |
19 | // window = UIWindow(frame: UIScreen.mainScreen().bounds)
20 | // window?.backgroundColor = UIColor.whiteColor()
21 | // let displayVC = DisplayVC()
22 | //
23 | // displayVC.tabBarItem.title = "Charlin Feng"
24 | //
25 | //// let navVC = UINavigationController(rootViewController: displayVC)
26 | ////
27 | // let tabVC = UITabBarController()
28 | ////
29 | // tabVC.viewControllers = [displayVC]
30 | //
31 | // window?.rootViewController = tabVC
32 | //
33 | // window?.makeKeyAndVisible()
34 |
35 | return true
36 | }
37 |
38 | func applicationWillResignActive(_ application: UIApplication) {
39 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
40 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
41 | }
42 |
43 | func applicationDidEnterBackground(_ application: UIApplication) {
44 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
45 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
46 | }
47 |
48 | func applicationWillEnterForeground(_ application: UIApplication) {
49 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
50 | }
51 |
52 | func applicationDidBecomeActive(_ application: UIApplication) {
53 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
54 | }
55 |
56 | func applicationWillTerminate(_ application: UIApplication) {
57 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
58 | }
59 |
60 |
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/PhotoBrowser/DisplayVC+Local.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Display+Local.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 冯成林 on 15/8/14.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | extension DisplayVC {
13 |
14 | var titleLocalCH: String {return "哆啦A梦:伴我同行"}
15 | var titleEN: String {return "Doraemon: walk with me"}
16 |
17 |
18 |
19 | var descLocalCH: [String] {
20 | return [
21 | "《哆啦A梦:伴我同行》是一部纪念《哆啦A梦》之父藤子·F·不二雄诞辰80周年的3D动画电影,该片讲述了哆啦A梦圆满完成了他的使命,启程返回22世纪,大雄该如何以一己之力实现他那来之不易的幸福未来。该片于2014年8月8日在日本上映,2015年5月28日在中国内地上映。",
22 | "为了什么都做不来的野比大雄,22 世纪的玄孙野比世修送了猫型机器人──哆啦A梦来现代。",
23 | "笨笨的野比大雄原本自己开了间公司,但很不幸的倒闭,之后剩下了一屁股债务,子孙们吃了莫大的苦。于是,野比世修才打算送哆啦A梦到现代",
24 | "哆啦A梦于是开始勉勉强强的协助野比大雄的日常生活。",
25 | "虽然刚开始不太习惯,但两个人的关系也日渐变的紧密。",
26 | "得知野比大雄的梦想是打算与梦中情人的同班同学源静香结婚以后,哆啦A梦就想尽办法要帮助野比大雄获得静香的芳心。",
27 | "正当源静香总算答应了野比大雄的求婚的时候,任务完成的哆啦A梦却被完成程式要求",
28 | "在48小时内回到22世纪。难道,得到了什么,自然的,也会失去些什么这个命定的预言,没办法被哆啦A梦跟野比大雄突破。",
29 | "面对哆啦A梦即将离开的冲击,野比大雄又该如何自处。",
30 | ]
31 | }
32 |
33 | var descLocalEN: [String] {
34 | return [
35 | "The duo la a dream: with my peers is a commemoration of Duo La a dream the father of Tengzi f. bu'erxiong birtThumbNailay 80th anniversary of 3D animated film, the film tells the story of the Duo a dream the successful completion of his mission, the journey back to the 22nd century, Nobita the how to single handedly achieve his hard won happiness in the future. The film was released in Japan in August 8, 2014 and released in May 28, 2015 in China.",
36 | "In order to do anything not to wild than male, the 22nd century's great great grandson Yebishixiu sent cat robot, duo la a dream to modern.",
37 | "Simple minded, wild than male originally opened his own company, but unfortunately the collapse, after the rest of the buttocks debt, children eat the great suffering. So, Yebishixiu only intend to send the duo A dream of modern",
38 | "Doraemon reluctantly began to assist the daily life of wild than male.",
39 | "Although just started not too accustomed to, but the relationship between the two people also gradually change the close.",
40 | "That wild than male's dream is to dream lover's classmate classmate Shizuka source married later, the duo la a dream will try to help wild than male Shizuka's heart.",
41 | "As promised when Shizuka source finally marry the wild than male tasks, Doraemon was completing the program requirements",
42 | "Back to twenty-second Century in 48 hours. Do what, natural and lose some what the fate of the prophecy, no way is the Duo a dream with wild than male breakthrough.",
43 | "In the face of Doraemon leaving the impact, how can wild than male.",
44 | ]
45 | }
46 |
47 |
48 |
49 |
50 | /** 本地相册 */
51 | func showLocal(_ index: Int){
52 |
53 |
54 | let pbVC = PhotoBrowser()
55 |
56 | /** 设置相册展示样式 */
57 | pbVC.showType = showType
58 |
59 | /** 设置相册类型 */
60 | pbVC.photoType = PhotoBrowser.PhotoType.local
61 |
62 | //强制关闭显示一切信息
63 | pbVC.hideMsgForZoomAndDismissWithSingleTap = true
64 |
65 | var models: [PhotoBrowser.PhotoModel] = []
66 |
67 | let title = langType == LangType.chinese ? titleLocalCH : titleEN
68 | let desc = langType == LangType.chinese ? descLocalCH : descLocalEN
69 |
70 | //模型数据数组
71 | for i in 0 ..< 9 {
72 |
73 | let model = PhotoBrowser.PhotoModel(localImg:UIImage(named: "\(i+1).jpg")! , titleStr: title, descStr:desc[i], sourceView: displayView.subviews[i] as! UIView)
74 |
75 | models.append(model)
76 | }
77 |
78 | /** 设置数据 */
79 | pbVC.photoModels = models
80 |
81 | pbVC.show(inVC: self,index: index)
82 | }
83 |
84 |
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/PhotoBrowser/DisplayVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DisplayVC.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 冯成林 on 15/8/14.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class DisplayVC: UIViewController {
12 |
13 |
14 | var langType: LangType = LangType.chinese
15 |
16 | var photoType: PhotoType = PhotoType.local
17 |
18 | var showType: PhotoBrowser.ShowType = PhotoBrowser.ShowType.zoomAndDismissWithSingleTap
19 |
20 | lazy var localImages: [String] = {["1.jpg","2.jpg","3.jpg","4.jpg","5.jpg","6.jpg","7.jpg","8.jpg","9.jpg"]}()
21 |
22 | let displayView = DisplayView()
23 |
24 | lazy var hostThumbNailImageUrls: [String] = {
25 |
26 | return [
27 |
28 | "http://ios-android.cn/PB/ThumbNail/1.jpg",
29 | "http://ios-android.cn/PB/ThumbNail/2.jpg",
30 | "http://ios-android.cn/PB/ThumbNail/3.jpg",
31 | "http://ios-android.cn/PB/ThumbNail/4.jpg",
32 | "http://ios-android.cn/PB/ThumbNail/5.jpg",
33 | "http://ios-android.cn/PB/ThumbNail/6.jpg",
34 | "http://ios-android.cn/PB/ThumbNail/7.jpg",
35 | "http://ios-android.cn/PB/ThumbNail/8.jpg",
36 | "http://ios-android.cn/PB/ThumbNail/9.jpg",
37 | ]
38 | }()
39 |
40 | }
41 |
42 |
43 |
44 |
45 | extension DisplayVC{
46 |
47 |
48 | override func viewDidLoad() {
49 | super.viewDidLoad()
50 |
51 | self.view.backgroundColor = UIColor.white
52 |
53 | self.navigationItem.title = langType == LangType.chinese ? "照片浏览器终结者" : "Photo Browser Terminator"
54 |
55 | if photoType == PhotoType.local { //本地
56 | displayView.imgsPrepare(localImages, isLocal: true)
57 | }else{ //网络
58 | displayView.imgsPrepare(hostThumbNailImageUrls, isLocal: false)
59 | }
60 | view.addSubview(displayView)
61 |
62 | let wh = min(UIScreen.main.bounds.size.width, UIScreen.main.bounds.size.height)
63 |
64 | displayView.make_center(offsest: CGPoint.zero, width: wh, height: wh)
65 |
66 |
67 | displayView.tapedImageV = {[unowned self] index in
68 |
69 | if self.photoType == PhotoType.local { //本地
70 | self.showLocal(index)
71 | }else{ //网络
72 | self.showHost(index)
73 | }
74 | }
75 | }
76 |
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/PhotoBrowser/DisplayView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DisplayView.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 冯成林 on 15/8/14.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class DisplayView: UIView {
12 |
13 |
14 | var tapedImageV: ((_ index: Int)->())?
15 |
16 | }
17 |
18 |
19 | extension DisplayView{
20 |
21 | /** 准备 */
22 | func imgsPrepare(_ imgs: [String], isLocal: Bool){
23 |
24 | for i in 0 ..< imgs.count {
25 |
26 | let imgV = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
27 | imgV.backgroundColor = UIColor.lightGray
28 | imgV.isUserInteractionEnabled = true
29 | imgV.contentMode = UIViewContentMode.scaleAspectFill
30 | imgV.clipsToBounds = true
31 | imgV.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(DisplayView.tapAction(_:))))
32 | imgV.tag = i
33 | if isLocal {
34 | imgV.image = UIImage(named: imgs[i])
35 | }else{
36 | imgV.hnk_setImageFromURL(URL(string: imgs[i])!)
37 | }
38 | self.addSubview(imgV)
39 | }
40 | }
41 |
42 |
43 | func tapAction(_ tap: UITapGestureRecognizer){
44 | tapedImageV?(tap.view!.tag)
45 | }
46 |
47 |
48 |
49 | override func layoutSubviews() {
50 |
51 | super.layoutSubviews()
52 |
53 | let totalRow = 3
54 | let totalWidth = self.bounds.size.width
55 |
56 | let margin: CGFloat = 10
57 | let itemWH = (totalWidth - margin * CGFloat(totalRow + 1)) / CGFloat(totalRow)
58 |
59 | /** 数组遍历 */
60 | var i=0
61 |
62 | for view in self.subviews{
63 |
64 | let row = i / totalRow
65 | let col = i % totalRow
66 |
67 | let x = (CGFloat(col) + 1) * margin + CGFloat(col) * itemWH
68 | let y = (CGFloat(row) + 1) * margin + CGFloat(row) * itemWH
69 | let frame = CGRect(x: x, y: y, width: itemWH, height: itemWH)
70 | view.frame = frame
71 | i += 1
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintConfig.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | public typealias ConstraintInterfaceLayoutDirection = UIUserInterfaceLayoutDirection
27 | #else
28 | import AppKit
29 | public typealias ConstraintInterfaceLayoutDirection = NSUserInterfaceLayoutDirection
30 | #endif
31 |
32 |
33 | public struct ConstraintConfig {
34 |
35 | public static var interfaceLayoutDirection: ConstraintInterfaceLayoutDirection = .leftToRight
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintDescription.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public class ConstraintDescription {
32 |
33 | internal let item: LayoutConstraintItem
34 | internal var attributes: ConstraintAttributes
35 | internal var relation: ConstraintRelation? = nil
36 | internal var sourceLocation: (String, UInt)? = nil
37 | internal var label: String? = nil
38 | internal var related: ConstraintItem? = nil
39 | internal var multiplier: ConstraintMultiplierTarget = 1.0
40 | internal var constant: ConstraintConstantTarget = 0.0
41 | internal var priority: ConstraintPriorityTarget = 1000.0
42 | internal lazy var constraint: Constraint? = {
43 | guard let relation = self.relation,
44 | let related = self.related,
45 | let sourceLocation = self.sourceLocation else {
46 | return nil
47 | }
48 | let from = ConstraintItem(target: self.item, attributes: self.attributes)
49 |
50 | return Constraint(
51 | from: from,
52 | to: related,
53 | relation: relation,
54 | sourceLocation: sourceLocation,
55 | label: self.label,
56 | multiplier: self.multiplier,
57 | constant: self.constant,
58 | priority: self.priority
59 | )
60 | }()
61 |
62 | // MARK: Initialization
63 |
64 | internal init(item: LayoutConstraintItem, attributes: ConstraintAttributes) {
65 | self.item = item
66 | self.attributes = attributes
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintInsetTarget.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol ConstraintInsetTarget: ConstraintConstantTarget {
32 | }
33 |
34 | extension Int: ConstraintInsetTarget {
35 | }
36 |
37 | extension UInt: ConstraintInsetTarget {
38 | }
39 |
40 | extension Float: ConstraintInsetTarget {
41 | }
42 |
43 | extension Double: ConstraintInsetTarget {
44 | }
45 |
46 | extension CGFloat: ConstraintInsetTarget {
47 | }
48 |
49 | extension ConstraintInsets: ConstraintInsetTarget {
50 | }
51 |
52 | extension ConstraintInsetTarget {
53 |
54 | internal var constraintInsetTargetValue: ConstraintInsets {
55 | if let amount = self as? ConstraintInsets {
56 | return amount
57 | } else if let amount = self as? Float {
58 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
59 | } else if let amount = self as? Double {
60 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
61 | } else if let amount = self as? CGFloat {
62 | return ConstraintInsets(top: amount, left: amount, bottom: amount, right: amount)
63 | } else if let amount = self as? Int {
64 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
65 | } else if let amount = self as? UInt {
66 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
67 | } else {
68 | return ConstraintInsets(top: 0, left: 0, bottom: 0, right: 0)
69 | }
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintInsets.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | #if os(iOS) || os(tvOS)
32 | public typealias ConstraintInsets = UIEdgeInsets
33 | #else
34 | public typealias ConstraintInsets = EdgeInsets
35 | #endif
36 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public final class ConstraintItem {
32 |
33 | internal weak var target: AnyObject?
34 | internal let attributes: ConstraintAttributes
35 |
36 | internal init(target: AnyObject?, attributes: ConstraintAttributes) {
37 | self.target = target
38 | self.attributes = attributes
39 | }
40 |
41 | internal var layoutConstraintItem: LayoutConstraintItem? {
42 | return self.target as? LayoutConstraintItem
43 | }
44 |
45 | }
46 |
47 | public func ==(lhs: ConstraintItem, rhs: ConstraintItem) -> Bool {
48 | // pointer equality
49 | guard lhs !== rhs else {
50 | return true
51 | }
52 |
53 | // must both have valid targets and identical attributes
54 | guard let target1 = lhs.target,
55 | let target2 = rhs.target,
56 | target1 === target2 && lhs.attributes == rhs.attributes else {
57 | return false
58 | }
59 |
60 | return true
61 | }
62 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintLayoutGuide+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #endif
27 |
28 |
29 | @available(iOS 9.0, OSX 10.11, *)
30 | public extension ConstraintLayoutGuide {
31 |
32 | public var snp: ConstraintLayoutGuideDSL {
33 | return ConstraintLayoutGuideDSL(guide: self)
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintLayoutGuide.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | #if os(iOS) || os(tvOS)
32 | @available(iOS 9.0, *)
33 | public typealias ConstraintLayoutGuide = UILayoutGuide
34 | #else
35 | @available(OSX 10.11, *)
36 | public typealias ConstraintLayoutGuide = NSLayoutGuide
37 | #endif
38 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintLayoutGuideDSL.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | @available(iOS 9.0, OSX 10.11, *)
32 | public struct ConstraintLayoutGuideDSL: ConstraintAttributesDSL {
33 |
34 | @discardableResult
35 | public func prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
36 | return ConstraintMaker.prepareConstraints(item: self.guide, closure: closure)
37 | }
38 |
39 | public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
40 | ConstraintMaker.makeConstraints(item: self.guide, closure: closure)
41 | }
42 |
43 | public func remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
44 | ConstraintMaker.remakeConstraints(item: self.guide, closure: closure)
45 | }
46 |
47 | public func updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
48 | ConstraintMaker.updateConstraints(item: self.guide, closure: closure)
49 | }
50 |
51 | public func removeConstraints() {
52 | ConstraintMaker.removeConstraints(item: self.guide)
53 | }
54 |
55 | public var target: AnyObject? {
56 | return self.guide
57 | }
58 |
59 | internal let guide: ConstraintLayoutGuide
60 |
61 | internal init(guide: ConstraintLayoutGuide) {
62 | self.guide = guide
63 |
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintLayoutSupport.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | #if os(iOS) || os(tvOS)
32 | @available(iOS 8.0, *)
33 | public typealias ConstraintLayoutSupport = UILayoutSupport
34 | #else
35 | public class ConstraintLayoutSupport {}
36 | #endif
37 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintLayoutSupportDSL.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | @available(iOS 8.0, *)
32 | public struct ConstraintLayoutSupportDSL: ConstraintDSL {
33 |
34 | public var target: AnyObject? {
35 | return self.support
36 | }
37 |
38 | internal let support: ConstraintLayoutSupport
39 |
40 | internal init(support: ConstraintLayoutSupport) {
41 | self.support = support
42 |
43 | }
44 |
45 | public var top: ConstraintItem {
46 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.top)
47 | }
48 |
49 | public var bottom: ConstraintItem {
50 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.bottom)
51 | }
52 |
53 | public var height: ConstraintItem {
54 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.height)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintMakerEditable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public class ConstraintMakerEditable: ConstraintMakerPriortizable {
32 |
33 | @discardableResult
34 | public func multipliedBy(_ amount: ConstraintMultiplierTarget) -> ConstraintMakerEditable {
35 | self.description.multiplier = amount
36 | return self
37 | }
38 |
39 | @discardableResult
40 | public func dividedBy(_ amount: ConstraintMultiplierTarget) -> ConstraintMakerEditable {
41 | return self.multipliedBy(1.0 / amount.constraintMultiplierTargetValue)
42 | }
43 |
44 | @discardableResult
45 | public func offset(_ amount: ConstraintOffsetTarget) -> ConstraintMakerEditable {
46 | self.description.constant = amount.constraintOffsetTargetValue
47 | return self
48 | }
49 |
50 | @discardableResult
51 | public func inset(_ amount: ConstraintInsetTarget) -> ConstraintMakerEditable {
52 | self.description.constant = amount.constraintInsetTargetValue
53 | return self
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintMakerFinalizable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public class ConstraintMakerFinalizable {
32 |
33 | internal let description: ConstraintDescription
34 |
35 | internal init(_ description: ConstraintDescription) {
36 | self.description = description
37 | }
38 |
39 | @discardableResult
40 | public func labeled(_ label: String) -> ConstraintMakerFinalizable {
41 | self.description.label = label
42 | return self
43 | }
44 |
45 | public var constraint: Constraint {
46 | return self.description.constraint!
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintMakerPriortizable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public class ConstraintMakerPriortizable: ConstraintMakerFinalizable {
32 |
33 | @discardableResult
34 | public func priority(_ amount: ConstraintPriority) -> ConstraintMakerFinalizable {
35 | self.description.priority = amount.value
36 | return self
37 | }
38 |
39 | @discardableResult
40 | public func priority(_ amount: ConstraintPriorityTarget) -> ConstraintMakerFinalizable {
41 | self.description.priority = amount
42 | return self
43 | }
44 |
45 | @available(*, deprecated:3.0, message:"Use priority(.required) instead.")
46 | @discardableResult
47 | public func priorityRequired() -> ConstraintMakerFinalizable {
48 | return self.priority(.required)
49 | }
50 |
51 | @available(*, deprecated:3.0, message:"Use priority(.high) instead.")
52 | @discardableResult
53 | public func priorityHigh() -> ConstraintMakerFinalizable {
54 | return self.priority(.high)
55 | }
56 |
57 | @available(*, deprecated:3.0, message:"Use priority(.medium) instead.")
58 | @discardableResult
59 | public func priorityMedium() -> ConstraintMakerFinalizable {
60 | return self.priority(.medium)
61 | }
62 |
63 | @available(*, deprecated:3.0, message:"Use priority(.low) instead.")
64 | @discardableResult
65 | public func priorityLow() -> ConstraintMakerFinalizable {
66 | return self.priority(.low)
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintMultiplierTarget.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol ConstraintMultiplierTarget {
32 |
33 | var constraintMultiplierTargetValue: CGFloat { get }
34 |
35 | }
36 |
37 | extension Int: ConstraintMultiplierTarget {
38 |
39 | public var constraintMultiplierTargetValue: CGFloat {
40 | return CGFloat(self)
41 | }
42 |
43 | }
44 |
45 | extension UInt: ConstraintMultiplierTarget {
46 |
47 | public var constraintMultiplierTargetValue: CGFloat {
48 | return CGFloat(self)
49 | }
50 |
51 | }
52 |
53 | extension Float: ConstraintMultiplierTarget {
54 |
55 | public var constraintMultiplierTargetValue: CGFloat {
56 | return CGFloat(self)
57 | }
58 |
59 | }
60 |
61 | extension Double: ConstraintMultiplierTarget {
62 |
63 | public var constraintMultiplierTargetValue: CGFloat {
64 | return CGFloat(self)
65 | }
66 |
67 | }
68 |
69 | extension CGFloat: ConstraintMultiplierTarget {
70 |
71 | public var constraintMultiplierTargetValue: CGFloat {
72 | return self
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintOffsetTarget.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol ConstraintOffsetTarget: ConstraintConstantTarget {
32 | }
33 |
34 | extension Int: ConstraintOffsetTarget {
35 | }
36 |
37 | extension UInt: ConstraintOffsetTarget {
38 | }
39 |
40 | extension Float: ConstraintOffsetTarget {
41 | }
42 |
43 | extension Double: ConstraintOffsetTarget {
44 | }
45 |
46 | extension CGFloat: ConstraintOffsetTarget {
47 | }
48 |
49 | extension ConstraintOffsetTarget {
50 |
51 | internal var constraintOffsetTargetValue: CGFloat {
52 | let offset: CGFloat
53 | if let amount = self as? Float {
54 | offset = CGFloat(amount)
55 | } else if let amount = self as? Double {
56 | offset = CGFloat(amount)
57 | } else if let amount = self as? CGFloat {
58 | offset = CGFloat(amount)
59 | } else if let amount = self as? Int {
60 | offset = CGFloat(amount)
61 | } else if let amount = self as? UInt {
62 | offset = CGFloat(amount)
63 | } else {
64 | offset = 0.0
65 | }
66 | return offset
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintPriority.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 | public struct ConstraintPriority : ExpressibleByFloatLiteral, Equatable, Strideable {
31 | public typealias FloatLiteralType = Float
32 |
33 | public let value: Float
34 |
35 | public init(floatLiteral value: Float) {
36 | self.value = value
37 | }
38 |
39 | public init(_ value: Float) {
40 | self.value = value
41 | }
42 |
43 | public static var required: ConstraintPriority {
44 | return 1000.0
45 | }
46 |
47 | public static var high: ConstraintPriority {
48 | return 750.0
49 | }
50 |
51 | public static var medium: ConstraintPriority {
52 | #if os(OSX)
53 | return 501.0
54 | #else
55 | return 500.0
56 | #endif
57 |
58 | }
59 |
60 | public static var low: ConstraintPriority {
61 | return 250.0
62 | }
63 |
64 | public static func ==(lhs: ConstraintPriority, rhs: ConstraintPriority) -> Bool {
65 | return lhs.value == rhs.value
66 | }
67 |
68 | // MARK: Strideable
69 |
70 | public func advanced(by n: FloatLiteralType) -> ConstraintPriority {
71 | return ConstraintPriority(floatLiteral: value + n)
72 | }
73 |
74 | public func distance(to other: ConstraintPriority) -> FloatLiteralType {
75 | return other.value - value
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintPriorityTarget.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol ConstraintPriorityTarget {
32 |
33 | var constraintPriorityTargetValue: Float { get }
34 |
35 | }
36 |
37 | extension Int: ConstraintPriorityTarget {
38 |
39 | public var constraintPriorityTargetValue: Float {
40 | return Float(self)
41 | }
42 |
43 | }
44 |
45 | extension UInt: ConstraintPriorityTarget {
46 |
47 | public var constraintPriorityTargetValue: Float {
48 | return Float(self)
49 | }
50 |
51 | }
52 |
53 | extension Float: ConstraintPriorityTarget {
54 |
55 | public var constraintPriorityTargetValue: Float {
56 | return self
57 | }
58 |
59 | }
60 |
61 | extension Double: ConstraintPriorityTarget {
62 |
63 | public var constraintPriorityTargetValue: Float {
64 | return Float(self)
65 | }
66 |
67 | }
68 |
69 | extension CGFloat: ConstraintPriorityTarget {
70 |
71 | public var constraintPriorityTargetValue: Float {
72 | return Float(self)
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintRelatableTarget.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol ConstraintRelatableTarget {
32 | }
33 |
34 | extension Int: ConstraintRelatableTarget {
35 | }
36 |
37 | extension UInt: ConstraintRelatableTarget {
38 | }
39 |
40 | extension Float: ConstraintRelatableTarget {
41 | }
42 |
43 | extension Double: ConstraintRelatableTarget {
44 | }
45 |
46 | extension CGFloat: ConstraintRelatableTarget {
47 | }
48 |
49 | extension CGSize: ConstraintRelatableTarget {
50 | }
51 |
52 | extension CGPoint: ConstraintRelatableTarget {
53 | }
54 |
55 | extension ConstraintInsets: ConstraintRelatableTarget {
56 | }
57 |
58 | extension ConstraintItem: ConstraintRelatableTarget {
59 | }
60 |
61 | extension ConstraintView: ConstraintRelatableTarget {
62 | }
63 |
64 | @available(iOS 9.0, OSX 10.11, *)
65 | extension ConstraintLayoutGuide: ConstraintRelatableTarget {
66 | }
67 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintRelation.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | internal enum ConstraintRelation : Int {
32 | case equal = 1
33 | case lessThanOrEqual
34 | case greaterThanOrEqual
35 |
36 | internal var layoutRelation: NSLayoutRelation {
37 | get {
38 | switch(self) {
39 | case .equal:
40 | return .equal
41 | case .lessThanOrEqual:
42 | return .lessThanOrEqual
43 | case .greaterThanOrEqual:
44 | return .greaterThanOrEqual
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | #if os(iOS) || os(tvOS)
32 | public typealias ConstraintView = UIView
33 | #else
34 | public typealias ConstraintView = NSView
35 | #endif
36 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/ConstraintViewDSL.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public struct ConstraintViewDSL: ConstraintAttributesDSL {
32 |
33 | @discardableResult
34 | public func prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
35 | return ConstraintMaker.prepareConstraints(item: self.view, closure: closure)
36 | }
37 |
38 | public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
39 | ConstraintMaker.makeConstraints(item: self.view, closure: closure)
40 | }
41 |
42 | public func remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
43 | ConstraintMaker.remakeConstraints(item: self.view, closure: closure)
44 | }
45 |
46 | public func updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
47 | ConstraintMaker.updateConstraints(item: self.view, closure: closure)
48 | }
49 |
50 | public func removeConstraints() {
51 | ConstraintMaker.removeConstraints(item: self.view)
52 | }
53 |
54 | public var contentHuggingHorizontalPriority: Float {
55 | get {
56 | return self.view.contentHuggingPriority(for: .horizontal)
57 | }
58 | set {
59 | self.view.setContentHuggingPriority(newValue, for: .horizontal)
60 | }
61 | }
62 |
63 | public var contentHuggingVerticalPriority: Float {
64 | get {
65 | return self.view.contentHuggingPriority(for: .vertical)
66 | }
67 | set {
68 | self.view.setContentHuggingPriority(newValue, for: .vertical)
69 | }
70 | }
71 |
72 | public var contentCompressionResistanceHorizontalPriority: Float {
73 | get {
74 | return self.view.contentCompressionResistancePriority(for: .horizontal)
75 | }
76 | set {
77 | self.view.setContentCompressionResistancePriority(newValue, for: .horizontal)
78 | }
79 | }
80 |
81 | public var contentCompressionResistanceVerticalPriority: Float {
82 | get {
83 | return self.view.contentCompressionResistancePriority(for: .vertical)
84 | }
85 | set {
86 | self.view.setContentCompressionResistancePriority(newValue, for: .vertical)
87 | }
88 | }
89 |
90 | public var target: AnyObject? {
91 | return self.view
92 | }
93 |
94 | internal let view: ConstraintView
95 |
96 | internal init(view: ConstraintView) {
97 | self.view = view
98 |
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | $(CURRENT_PROJECT_VERSION)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/LayoutConstraint.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public class LayoutConstraint : NSLayoutConstraint {
32 |
33 | public var label: String? {
34 | get {
35 | return self.identifier
36 | }
37 | set {
38 | self.identifier = newValue
39 | }
40 | }
41 |
42 | internal weak var constraint: Constraint? = nil
43 |
44 | }
45 |
46 | internal func ==(lhs: LayoutConstraint, rhs: LayoutConstraint) -> Bool {
47 | guard lhs.firstItem === rhs.firstItem &&
48 | lhs.secondItem === rhs.secondItem &&
49 | lhs.firstAttribute == rhs.firstAttribute &&
50 | lhs.secondAttribute == rhs.secondAttribute &&
51 | lhs.relation == rhs.relation &&
52 | lhs.priority == rhs.priority &&
53 | lhs.multiplier == rhs.multiplier else {
54 | return false
55 | }
56 | return true
57 | }
58 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/LayoutConstraintItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol LayoutConstraintItem: class {
32 | }
33 |
34 | @available(iOS 9.0, OSX 10.11, *)
35 | extension ConstraintLayoutGuide : LayoutConstraintItem {
36 | }
37 |
38 | extension ConstraintView : LayoutConstraintItem {
39 | }
40 |
41 |
42 | extension LayoutConstraintItem {
43 |
44 | internal func prepare() {
45 | if let view = self as? ConstraintView {
46 | view.translatesAutoresizingMaskIntoConstraints = false
47 | }
48 | }
49 |
50 | internal var superview: ConstraintView? {
51 | if let view = self as? ConstraintView {
52 | return view.superview
53 | }
54 |
55 | if #available(iOS 9.0, OSX 10.11, *), let guide = self as? ConstraintLayoutGuide {
56 | return guide.owningView
57 | }
58 |
59 | return nil
60 | }
61 | internal var constraints: [Constraint] {
62 | return self.constraintsSet.allObjects as! [Constraint]
63 | }
64 |
65 | internal func add(constraints: [Constraint]) {
66 | let constraintsSet = self.constraintsSet
67 | for constraint in constraints {
68 | constraintsSet.add(constraint)
69 | }
70 | }
71 |
72 | internal func remove(constraints: [Constraint]) {
73 | let constraintsSet = self.constraintsSet
74 | for constraint in constraints {
75 | constraintsSet.remove(constraint)
76 | }
77 | }
78 |
79 | private var constraintsSet: NSMutableSet {
80 | let constraintsSet: NSMutableSet
81 |
82 | if let existing = objc_getAssociatedObject(self, &constraintsKey) as? NSMutableSet {
83 | constraintsSet = existing
84 | } else {
85 | constraintsSet = NSMutableSet()
86 | objc_setAssociatedObject(self, &constraintsKey, constraintsSet, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
87 | }
88 | return constraintsSet
89 |
90 | }
91 |
92 | }
93 | private var constraintsKey: UInt8 = 0
94 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/SnapKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #import
25 |
26 | FOUNDATION_EXPORT double SnapKitVersionNumber;
27 | FOUNDATION_EXPORT const unsigned char SnapKitVersionString[];
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/CFSnapKit/Source/UILayoutSupport+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #endif
27 |
28 |
29 | @available(iOS 8.0, *)
30 | public extension ConstraintLayoutSupport {
31 |
32 | public var snp: ConstraintLayoutSupportDSL {
33 | return ConstraintLayoutSupportDSL(support: self)
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/CGSize+Swift.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CGSize+Swift.swift
3 | // Haneke
4 | //
5 | // Created by Oriol Blanc Gimeno on 09/09/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension CGSize {
12 |
13 | func hnk_aspectFillSize(_ size: CGSize) -> CGSize {
14 | let scaleWidth = size.width / self.width
15 | let scaleHeight = size.height / self.height
16 | let scale = max(scaleWidth, scaleHeight)
17 |
18 | let resultSize = CGSize(width: self.width * scale, height: self.height * scale)
19 | return CGSize(width: ceil(resultSize.width), height: ceil(resultSize.height))
20 | }
21 |
22 | func hnk_aspectFitSize(_ size: CGSize) -> CGSize {
23 | let targetAspect = size.width / size.height
24 | let sourceAspect = self.width / self.height
25 | var resultSize = size
26 |
27 | if (targetAspect > sourceAspect) {
28 | resultSize.width = size.height * sourceAspect
29 | }
30 | else {
31 | resultSize.height = size.width / sourceAspect
32 | }
33 | return CGSize(width: ceil(resultSize.width), height: ceil(resultSize.height))
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/Data.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Data.swift
3 | // Haneke
4 | //
5 | // Created by Hermes Pique on 9/19/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // See: http://stackoverflow.com/questions/25922152/not-identical-to-self
12 | public protocol DataConvertible {
13 | associatedtype Result
14 |
15 | static func convertFromData(_ data:Data) -> Result?
16 | }
17 |
18 | public protocol DataRepresentable {
19 |
20 | func asData() -> Data!
21 | }
22 |
23 | private let imageSync = NSLock()
24 |
25 | extension UIImage : DataConvertible, DataRepresentable {
26 |
27 | public typealias Result = UIImage
28 |
29 | // HACK: UIImage data initializer is no longer thread safe. See: https://github.com/AFNetworking/AFNetworking/issues/2572#issuecomment-115854482
30 | static func safeImageWithData(_ data:Data) -> Result? {
31 | imageSync.lock()
32 | let image = UIImage(data:data, scale: scale)
33 | imageSync.unlock()
34 | return image
35 | }
36 |
37 | public class func convertFromData(_ data: Data) -> Result? {
38 | let image = UIImage.safeImageWithData(data)
39 | return image
40 | }
41 |
42 | public func asData() -> Data! {
43 | return self.hnk_data() as Data!
44 | }
45 |
46 | fileprivate static let scale = UIScreen.main.scale
47 |
48 | }
49 |
50 | extension String : DataConvertible, DataRepresentable {
51 |
52 | public typealias Result = String
53 |
54 | public static func convertFromData(_ data: Data) -> Result? {
55 | let string = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
56 | return string as Result?
57 | }
58 |
59 | public func asData() -> Data! {
60 | return self.data(using: String.Encoding.utf8)
61 | }
62 |
63 | }
64 |
65 | extension Data : DataConvertible, DataRepresentable {
66 |
67 | public typealias Result = Data
68 |
69 | public static func convertFromData(_ data: Data) -> Result? {
70 | return data
71 | }
72 |
73 | public func asData() -> Data! {
74 | return self
75 | }
76 |
77 | }
78 |
79 | public enum JSON : DataConvertible, DataRepresentable {
80 | public typealias Result = JSON
81 |
82 | case Dictionary([String:AnyObject])
83 | case Array([AnyObject])
84 |
85 | public static func convertFromData(_ data: Data) -> Result? {
86 | do {
87 | let object : Any = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions())
88 | switch (object) {
89 | case let dictionary as [String:AnyObject]:
90 | return JSON.Dictionary(dictionary)
91 | case let array as [AnyObject]:
92 | return JSON.Array(array)
93 | default:
94 | return nil
95 | }
96 | } catch {
97 | Log.error(message: "Invalid JSON data", error: error)
98 | return nil
99 | }
100 | }
101 |
102 | public func asData() -> Data! {
103 | switch (self) {
104 | case .Dictionary(let dictionary):
105 | return try? JSONSerialization.data(withJSONObject: dictionary, options: JSONSerialization.WritingOptions())
106 | case .Array(let array):
107 | return try? JSONSerialization.data(withJSONObject: array, options: JSONSerialization.WritingOptions())
108 | }
109 | }
110 |
111 | public var array : [AnyObject]! {
112 | switch (self) {
113 | case .Dictionary(_):
114 | return nil
115 | case .Array(let array):
116 | return array
117 | }
118 | }
119 |
120 | public var dictionary : [String:AnyObject]! {
121 | switch (self) {
122 | case .Dictionary(let dictionary):
123 | return dictionary
124 | case .Array(_):
125 | return nil
126 | }
127 | }
128 |
129 | }
130 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/DiskFetcher.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DiskFetcher.swift
3 | // Haneke
4 | //
5 | // Created by Joan Romano on 9/16/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension HanekeGlobals {
12 |
13 | // It'd be better to define this in the DiskFetcher class but Swift doesn't allow to declare an enum in a generic type
14 | public struct DiskFetcher {
15 |
16 | public enum ErrorCode : Int {
17 | case invalidData = -500
18 | }
19 |
20 | }
21 |
22 | }
23 |
24 | open class DiskFetcher : Fetcher {
25 |
26 | let path: String
27 | var cancelled = false
28 |
29 | public init(path: String) {
30 | self.path = path
31 | let key = path
32 | super.init(key: key)
33 | }
34 |
35 | // MARK: Fetcher
36 |
37 |
38 | open override func fetch(failure fail: @escaping ((Error?) -> ()), success succeed: @escaping (T.Result) -> ()) {
39 | self.cancelled = false
40 | DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async(execute: { [weak self] in
41 | if let strongSelf = self {
42 | strongSelf.privateFetch(failure: fail, success: succeed)
43 | }
44 | })
45 | }
46 |
47 | open override func cancelFetch() {
48 | self.cancelled = true
49 | }
50 |
51 | // MARK: Private
52 |
53 | fileprivate func privateFetch(failure fail: @escaping ((Error?) -> ()), success succeed: @escaping (T.Result) -> ()) {
54 | if self.cancelled {
55 | return
56 | }
57 |
58 | let data : Data
59 | do {
60 | data = try Data(contentsOf: URL(fileURLWithPath: self.path), options: Data.ReadingOptions())
61 | } catch {
62 | DispatchQueue.main.async {
63 | if self.cancelled {
64 | return
65 | }
66 | fail(error)
67 | }
68 | return
69 | }
70 |
71 | if self.cancelled {
72 | return
73 | }
74 |
75 | guard let value : T.Result = T.convertFromData(data) else {
76 | let localizedFormat = NSLocalizedString("Failed to convert value from data at path %@", comment: "Error description")
77 | let description = String(format:localizedFormat, self.path)
78 | let error = errorWithCode(HanekeGlobals.DiskFetcher.ErrorCode.invalidData.rawValue, description: description)
79 | DispatchQueue.main.async {
80 | fail(error)
81 | }
82 | return
83 | }
84 |
85 | DispatchQueue.main.async(execute: {
86 | if self.cancelled {
87 | return
88 | }
89 | succeed(value)
90 | })
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/Fetch.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Fetch.swift
3 | // Haneke
4 | //
5 | // Created by Hermes Pique on 9/28/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum FetchState {
12 | case pending
13 | // Using Wrapper as a workaround for error 'unimplemented IR generation feature non-fixed multi-payload enum layout'
14 | // See: http://swiftradar.tumblr.com/post/88314603360/swift-fails-to-compile-enum-with-two-data-cases
15 | // See: http://owensd.io/2014/08/06/fixed-enum-layout.html
16 | case success(Wrapper)
17 | case failure(Error?)
18 | }
19 |
20 | open class Fetch {
21 |
22 | public typealias Succeeder = (T) -> ()
23 |
24 | public typealias Failer = (Error?) -> ()
25 |
26 | fileprivate var onSuccess : Succeeder?
27 |
28 | fileprivate var onFailure : Failer?
29 |
30 | fileprivate var state : FetchState = FetchState.pending
31 |
32 | public init() {}
33 |
34 | @discardableResult open func onSuccess(_ onSuccess: @escaping Succeeder) -> Self {
35 | self.onSuccess = onSuccess
36 | switch self.state {
37 | case FetchState.success(let wrapper):
38 | onSuccess(wrapper.value)
39 | default:
40 | break
41 | }
42 | return self
43 | }
44 |
45 | @discardableResult open func onFailure(_ onFailure: @escaping Failer) -> Self {
46 | self.onFailure = onFailure
47 | switch self.state {
48 | case FetchState.failure(let error):
49 | onFailure(error)
50 | default:
51 | break
52 | }
53 | return self
54 | }
55 |
56 | func succeed(_ value: T) {
57 | self.state = FetchState.success(Wrapper(value))
58 | self.onSuccess?(value)
59 | }
60 |
61 | func fail(_ error: Error? = nil) {
62 | self.state = FetchState.failure(error)
63 | self.onFailure?(error)
64 | }
65 |
66 | var hasFailed : Bool {
67 | switch self.state {
68 | case FetchState.failure(_):
69 | return true
70 | default:
71 | return false
72 | }
73 | }
74 |
75 | var hasSucceeded : Bool {
76 | switch self.state {
77 | case FetchState.success(_):
78 | return true
79 | default:
80 | return false
81 | }
82 | }
83 |
84 | }
85 |
86 | open class Wrapper {
87 | open let value: T
88 | public init(_ value: T) { self.value = value }
89 | }
90 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/Fetcher.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Fetcher.swift
3 | // Haneke
4 | //
5 | // Created by Hermes Pique on 9/9/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // See: http://stackoverflow.com/questions/25915306/generic-closure-in-protocol
12 | open class Fetcher {
13 |
14 | open let key: String
15 |
16 | public init(key: String) {
17 | self.key = key
18 | }
19 |
20 | open func fetch(failure fail: @escaping ((Error?) -> ()), success succeed: @escaping (T.Result) -> ()) {}
21 |
22 | open func cancelFetch() {}
23 | }
24 |
25 | class SimpleFetcher : Fetcher {
26 |
27 | let getValue : () -> T.Result
28 |
29 | init(key: String, value getValue : @autoclosure @escaping () -> T.Result) {
30 | self.getValue = getValue
31 | super.init(key: key)
32 | }
33 |
34 | override func fetch(failure fail: @escaping ((Error?) -> ()), success succeed: @escaping (T.Result) -> ()) {
35 | let value = getValue()
36 | succeed(value)
37 | }
38 |
39 | override func cancelFetch() {}
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/Format.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Format.swift
3 | // Haneke
4 | //
5 | // Created by Hermes Pique on 8/27/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public struct Format {
12 |
13 | public let name: String
14 |
15 | public let diskCapacity : UInt64
16 |
17 | public var transform : ((T) -> (T))?
18 |
19 | public var convertToData : ((T) -> Data)?
20 |
21 | public init(name: String, diskCapacity : UInt64 = UINT64_MAX, transform: ((T) -> (T))? = nil) {
22 | self.name = name
23 | self.diskCapacity = diskCapacity
24 | self.transform = transform
25 | }
26 |
27 | public func apply(_ value : T) -> T {
28 | var transformed = value
29 | if let transform = self.transform {
30 | transformed = transform(value)
31 | }
32 | return transformed
33 | }
34 |
35 | var isIdentity : Bool {
36 | return self.transform == nil
37 | }
38 |
39 | }
40 |
41 | public struct ImageResizer {
42 |
43 | public enum ScaleMode: String {
44 | case Fill = "fill", AspectFit = "aspectfit", AspectFill = "aspectfill", None = "none"
45 | }
46 |
47 | public typealias T = UIImage
48 |
49 | public let allowUpscaling : Bool
50 |
51 | public let size : CGSize
52 |
53 | public let scaleMode: ScaleMode
54 |
55 | public let compressionQuality : Float
56 |
57 | public init(size: CGSize = CGSize.zero, scaleMode: ScaleMode = .None, allowUpscaling: Bool = true, compressionQuality: Float = 1.0) {
58 | self.size = size
59 | self.scaleMode = scaleMode
60 | self.allowUpscaling = allowUpscaling
61 | self.compressionQuality = compressionQuality
62 | }
63 |
64 | public func resizeImage(_ image: UIImage) -> UIImage {
65 | var resizeToSize: CGSize
66 | switch self.scaleMode {
67 | case .Fill:
68 | resizeToSize = self.size
69 | case .AspectFit:
70 | resizeToSize = image.size.hnk_aspectFitSize(self.size)
71 | case .AspectFill:
72 | resizeToSize = image.size.hnk_aspectFillSize(self.size)
73 | case .None:
74 | return image
75 | }
76 | assert(self.size.width > 0 && self.size.height > 0, "Expected non-zero size. Use ScaleMode.None to avoid resizing.")
77 |
78 | // If does not allow to scale up the image
79 | if (!self.allowUpscaling) {
80 | if (resizeToSize.width > image.size.width || resizeToSize.height > image.size.height) {
81 | return image
82 | }
83 | }
84 |
85 | // Avoid unnecessary computations
86 | if (resizeToSize.width == image.size.width && resizeToSize.height == image.size.height) {
87 | return image
88 | }
89 |
90 | let resizedImage = image.hnk_imageByScaling(toSize: resizeToSize)
91 | return resizedImage
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/Haneke.h:
--------------------------------------------------------------------------------
1 | //
2 | // Haneke.h
3 | // Haneke
4 | //
5 | // Created by Luis Ascorbe on 23/07/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for Haneke.
12 | FOUNDATION_EXPORT double HanekeVersionNumber;
13 |
14 | //! Project version string for Haneke.
15 | FOUNDATION_EXPORT const unsigned char HanekeVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/Haneke.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Haneke.swift
3 | // Haneke
4 | //
5 | // Created by Hermes Pique on 9/9/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public struct HanekeGlobals {
12 |
13 | public static let Domain = "io.haneke"
14 |
15 | }
16 |
17 | public struct Shared {
18 |
19 | public static var imageCache : Cache {
20 | struct Static {
21 | static let name = "shared-images"
22 | static let cache = Cache(name: name)
23 | }
24 | return Static.cache
25 | }
26 |
27 | public static var dataCache : Cache {
28 | struct Static {
29 | static let name = "shared-data"
30 | static let cache = Cache(name: name)
31 | }
32 | return Static.cache
33 | }
34 |
35 | public static var stringCache : Cache {
36 | struct Static {
37 | static let name = "shared-strings"
38 | static let cache = Cache(name: name)
39 | }
40 | return Static.cache
41 | }
42 |
43 | public static var JSONCache : Cache {
44 | struct Static {
45 | static let name = "shared-json"
46 | static let cache = Cache(name: name)
47 | }
48 | return Static.cache
49 | }
50 | }
51 |
52 | func errorWithCode(_ code: Int, description: String) -> Error {
53 | let userInfo = [NSLocalizedDescriptionKey: description]
54 | return NSError(domain: HanekeGlobals.Domain, code: code, userInfo: userInfo) as Error
55 | }
56 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/Info-iOS.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/Info-tvOS.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/Log.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Log.swift
3 | // Haneke
4 | //
5 | // Created by Hermes Pique on 11/10/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct Log {
12 |
13 | fileprivate static let Tag = "[HANEKE]"
14 |
15 | fileprivate enum Level : String {
16 | case Debug = "[DEBUG]"
17 | case Error = "[ERROR]"
18 | }
19 |
20 | fileprivate static func log(_ level: Level, _ message: @autoclosure () -> String, _ error: Error? = nil) {
21 | if let error = error {
22 | print("\(Tag)\(level.rawValue) \(message()) with error \(error)")
23 | } else {
24 | print("\(Tag)\(level.rawValue) \(message())")
25 | }
26 | }
27 |
28 | static func debug(message: @autoclosure () -> String, error: Error? = nil) {
29 | #if DEBUG
30 | log(.Debug, message, error)
31 | #endif
32 | }
33 |
34 | static func error(message: @autoclosure () -> String, error: Error? = nil) {
35 | log(.Error, message, error)
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/NSFileManager+Haneke.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSFileManager+Haneke.swift
3 | // Haneke
4 | //
5 | // Created by Hermes Pique on 8/26/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension FileManager {
12 |
13 | func enumerateContentsOfDirectory(atPath path: String, orderedByProperty property: String, ascending: Bool, usingBlock block: (URL, Int, inout Bool) -> Void ) {
14 |
15 | let directoryURL = URL(fileURLWithPath: path)
16 | do {
17 | let contents = try self.contentsOfDirectory(at: directoryURL, includingPropertiesForKeys: [URLResourceKey(rawValue: property)], options: FileManager.DirectoryEnumerationOptions())
18 | let sortedContents = contents.sorted(by: {(URL1: URL, URL2: URL) -> Bool in
19 |
20 | // Maybe there's a better way to do this. See: http://stackoverflow.com/questions/25502914/comparing-anyobject-in-swift
21 |
22 | var value1 : AnyObject?
23 | do {
24 | try (URL1 as NSURL).getResourceValue(&value1, forKey: URLResourceKey(rawValue: property))
25 | } catch {
26 | return true
27 | }
28 | var value2 : AnyObject?
29 | do {
30 | try (URL2 as NSURL).getResourceValue(&value2, forKey: URLResourceKey(rawValue: property))
31 | } catch {
32 | return false
33 | }
34 |
35 | if let string1 = value1 as? String, let string2 = value2 as? String {
36 | return ascending ? string1 < string2 : string2 < string1
37 | }
38 |
39 | if let date1 = value1 as? Date, let date2 = value2 as? Date {
40 | return ascending ? date1 < date2 : date2 < date1
41 | }
42 |
43 | if let number1 = value1 as? NSNumber, let number2 = value2 as? NSNumber {
44 | return ascending ? number1 < number2 : number2 < number1
45 | }
46 |
47 | return false
48 | })
49 |
50 | for (i, v) in sortedContents.enumerated() {
51 | var stop : Bool = false
52 | block(v, i, &stop)
53 | if stop { break }
54 | }
55 |
56 | } catch {
57 | Log.error(message: "Failed to list directory", error: error)
58 | }
59 | }
60 |
61 | }
62 |
63 | func < (lhs: NSNumber, rhs: NSNumber) -> Bool {
64 | return lhs.compare(rhs) == ComparisonResult.orderedAscending
65 | }
66 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/NSHTTPURLResponse+Haneke.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSHTTPURLResponse+Haneke.swift
3 | // Haneke
4 | //
5 | // Created by Hermes Pique on 1/2/16.
6 | // Copyright © 2016 Haneke. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension HTTPURLResponse {
12 |
13 | func hnk_isValidStatusCode() -> Bool {
14 | switch self.statusCode {
15 | case 200...201:
16 | return true
17 | default:
18 | return false
19 | }
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/NSURLResponse+Haneke.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSHTTPURLResponse+Haneke.swift
3 | // Haneke
4 | //
5 | // Created by Hermes Pique on 9/12/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension URLResponse {
12 |
13 | func hnk_validateLength(ofData data: Data) -> Bool {
14 | let expectedContentLength = self.expectedContentLength
15 | if (expectedContentLength > -1) {
16 | let dataLength = data.count
17 | return Int64(dataLength) >= expectedContentLength
18 | }
19 | return true
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/String+Haneke.swift:
--------------------------------------------------------------------------------
1 | //
2 | // String+Haneke.swift
3 | // Haneke
4 | //
5 | // Created by Hermes Pique on 8/30/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension String {
12 |
13 | func escapedFilename() -> String {
14 | return [ "\0":"%00", ":":"%3A", "/":"%2F" ]
15 | .reduce(self.components(separatedBy: "%").joined(separator: "%25")) {
16 | str, m in str.components(separatedBy: m.0).joined(separator: m.1)
17 | }
18 | }
19 |
20 | func MD5String() -> String {
21 | guard let data = self.data(using: String.Encoding.utf8) else {
22 | return self
23 | }
24 |
25 | let MD5Calculator = MD5(Array(data))
26 | let MD5Data = MD5Calculator.calculate()
27 | let resultBytes = UnsafeMutablePointer(mutating: MD5Data)
28 | let resultEnumerator = UnsafeBufferPointer(start: resultBytes, count: MD5Data.count)
29 | let MD5String = NSMutableString()
30 | for c in resultEnumerator {
31 | MD5String.appendFormat("%02x", c)
32 | }
33 | return MD5String as String
34 | }
35 |
36 | func MD5Filename() -> String {
37 | let MD5String = self.MD5String()
38 |
39 | // NSString.pathExtension alone could return a query string, which can lead to very long filenames.
40 | let pathExtension = URL(string: self)?.pathExtension ?? (self as NSString).pathExtension
41 |
42 | if pathExtension.characters.count > 0 {
43 | return (MD5String as NSString).appendingPathExtension(pathExtension) ?? MD5String
44 | } else {
45 | return MD5String
46 | }
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/UIImage+Haneke.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Haneke.swift
3 | // Haneke
4 | //
5 | // Created by Hermes Pique on 8/10/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIImage {
12 |
13 | func hnk_imageByScaling(toSize size: CGSize) -> UIImage {
14 | UIGraphicsBeginImageContextWithOptions(size, !hnk_hasAlpha(), 0.0)
15 | draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
16 | let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
17 | UIGraphicsEndImageContext()
18 | return resizedImage!
19 | }
20 |
21 | func hnk_hasAlpha() -> Bool {
22 | guard let alphaInfo = self.cgImage?.alphaInfo else { return false }
23 | switch alphaInfo {
24 | case .first, .last, .premultipliedFirst, .premultipliedLast, .alphaOnly:
25 | return true
26 | case .none, .noneSkipFirst, .noneSkipLast:
27 | return false
28 | }
29 | }
30 |
31 | func hnk_data(compressionQuality: Float = 1.0) -> Data! {
32 | let hasAlpha = self.hnk_hasAlpha()
33 | let data = hasAlpha ? UIImagePNGRepresentation(self) : UIImageJPEGRepresentation(self, CGFloat(compressionQuality))
34 | return data
35 | }
36 |
37 | func hnk_decompressedImage() -> UIImage! {
38 | let originalImageRef = self.cgImage
39 | let originalBitmapInfo = originalImageRef?.bitmapInfo
40 | guard let alphaInfo = originalImageRef?.alphaInfo else { return UIImage() }
41 |
42 | // See: http://stackoverflow.com/questions/23723564/which-cgimagealphainfo-should-we-use
43 | var bitmapInfo = originalBitmapInfo
44 | switch alphaInfo {
45 | case .none:
46 | let rawBitmapInfoWithoutAlpha = (bitmapInfo?.rawValue)! & ~CGBitmapInfo.alphaInfoMask.rawValue
47 | let rawBitmapInfo = rawBitmapInfoWithoutAlpha | CGImageAlphaInfo.noneSkipFirst.rawValue
48 | bitmapInfo = CGBitmapInfo(rawValue: rawBitmapInfo)
49 | case .premultipliedFirst, .premultipliedLast, .noneSkipFirst, .noneSkipLast:
50 | break
51 | case .alphaOnly, .last, .first: // Unsupported
52 | return self
53 | }
54 |
55 | let colorSpace = CGColorSpaceCreateDeviceRGB()
56 | let pixelSize = CGSize(width: self.size.width * self.scale, height: self.size.height * self.scale)
57 | guard let context = CGContext(data: nil, width: Int(ceil(pixelSize.width)), height: Int(ceil(pixelSize.height)), bitsPerComponent: (originalImageRef?.bitsPerComponent)!, bytesPerRow: 0, space: colorSpace, bitmapInfo: (bitmapInfo?.rawValue)!) else {
58 | return self
59 | }
60 |
61 | let imageRect = CGRect(x: 0, y: 0, width: pixelSize.width, height: pixelSize.height)
62 | UIGraphicsPushContext(context)
63 |
64 | // Flip coordinate system. See: http://stackoverflow.com/questions/506622/cgcontextdrawimage-draws-image-upside-down-when-passed-uiimage-cgimage
65 | context.translateBy(x: 0, y: pixelSize.height)
66 | context.scaleBy(x: 1.0, y: -1.0)
67 |
68 | // UIImage and drawInRect takes into account image orientation, unlike CGContextDrawImage.
69 | self.draw(in: imageRect)
70 | UIGraphicsPopContext()
71 |
72 | guard let decompressedImageRef = context.makeImage() else {
73 | return self
74 | }
75 |
76 | let scale = UIScreen.main.scale
77 | let image = UIImage(cgImage: decompressedImageRef, scale:scale, orientation:UIImageOrientation.up)
78 | return image
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/Haneke/UIView+Haneke.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Haneke.swift
3 | // Haneke
4 | //
5 | // Created by Joan Romano on 15/10/14.
6 | // Copyright (c) 2014 Haneke. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public extension HanekeGlobals {
12 |
13 | public struct UIKit {
14 |
15 | static func formatWithSize(_ size : CGSize, scaleMode : ImageResizer.ScaleMode, allowUpscaling: Bool = true) -> Format {
16 | let name = "auto-\(size.width)x\(size.height)-\(scaleMode.rawValue)"
17 | let cache = Shared.imageCache
18 | if let (format,_,_) = cache.formats[name] {
19 | return format
20 | }
21 |
22 | var format = Format(name: name,
23 | diskCapacity: HanekeGlobals.UIKit.DefaultFormat.DiskCapacity) {
24 | let resizer = ImageResizer(size:size,
25 | scaleMode: scaleMode,
26 | allowUpscaling: allowUpscaling,
27 | compressionQuality: HanekeGlobals.UIKit.DefaultFormat.CompressionQuality)
28 | return resizer.resizeImage($0)
29 | }
30 | format.convertToData = {(image : UIImage) -> Data in
31 | image.hnk_data(compressionQuality: HanekeGlobals.UIKit.DefaultFormat.CompressionQuality) as Data
32 | }
33 | return format
34 | }
35 |
36 | public struct DefaultFormat {
37 |
38 | public static let DiskCapacity : UInt64 = 50 * 1024 * 1024
39 | public static let CompressionQuality : Float = 0.75
40 |
41 | }
42 |
43 | static var SetImageAnimationDuration = 0.1
44 | static var SetImageFetcherKey = 0
45 | static var SetBackgroundImageFetcherKey = 1
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationAudioEqualizer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationAudioEqualizer.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationAudioEqualizer: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let lineSize = size.width / 9
34 | let x = (layer.bounds.size.width - lineSize * 7) / 2
35 | let y = (layer.bounds.size.height - size.height) / 2
36 | let duration: [CFTimeInterval] = [4.3, 2.5, 1.7, 3.1]
37 | let values = [0, 0.7, 0.4, 0.05, 0.95, 0.3, 0.9, 0.4, 0.15, 0.18, 0.75, 0.01]
38 |
39 | // Draw lines
40 | for i in 0 ..< 4 {
41 | let animation = CAKeyframeAnimation()
42 |
43 | animation.keyPath = "path"
44 | animation.isAdditive = true
45 | animation.values = []
46 |
47 | for j in 0 ..< values.count {
48 | let heightFactor = values[j]
49 | let height = size.height * CGFloat(heightFactor)
50 | let point = CGPoint(x: 0, y: size.height - height)
51 | let path = UIBezierPath(rect: CGRect(origin: point, size: CGSize(width: lineSize, height: height)))
52 |
53 | animation.values?.append(path.cgPath)
54 | }
55 | animation.duration = duration[i]
56 | animation.repeatCount = HUGE
57 | animation.isRemovedOnCompletion = false
58 |
59 | let line = NVActivityIndicatorShape.line.layerWith(size: CGSize(width: lineSize, height: size.height), color: color)
60 | let frame = CGRect(x: x + lineSize * 2 * CGFloat(i),
61 | y: y,
62 | width: lineSize,
63 | height: size.height)
64 |
65 | line.frame = frame
66 | line.add(animation, forKey: "animation")
67 | layer.addSublayer(line)
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallBeat.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallBeat.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallBeat: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let circleSpacing: CGFloat = 2
34 | let circleSize = (size.width - circleSpacing * 2) / 3
35 | let x = (layer.bounds.size.width - size.width) / 2
36 | let y = (layer.bounds.size.height - circleSize) / 2
37 | let duration: CFTimeInterval = 0.7
38 | let beginTime = CACurrentMediaTime()
39 | let beginTimes = [0.35, 0, 0.35]
40 |
41 | // Scale animation
42 | let scaleAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
43 |
44 | scaleAnimation.keyTimes = [0, 0.5, 1]
45 | scaleAnimation.values = [1, 0.75, 1]
46 | scaleAnimation.duration = duration
47 |
48 | // Opacity animation
49 | let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
50 |
51 | opacityAnimation.keyTimes = [0, 0.5, 1]
52 | opacityAnimation.values = [1, 0.2, 1]
53 | opacityAnimation.duration = duration
54 |
55 | // Aniamtion
56 | let animation = CAAnimationGroup()
57 |
58 | animation.animations = [scaleAnimation, opacityAnimation]
59 | animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
60 | animation.duration = duration
61 | animation.repeatCount = HUGE
62 | animation.isRemovedOnCompletion = false
63 |
64 | // Draw circles
65 | for i in 0 ..< 3 {
66 | let circle = NVActivityIndicatorShape.circle.layerWith(size: CGSize(width: circleSize, height: circleSize), color: color)
67 | let frame = CGRect(x: x + circleSize * CGFloat(i) + circleSpacing * CGFloat(i),
68 | y: y,
69 | width: circleSize,
70 | height: circleSize)
71 |
72 | animation.beginTime = beginTime + beginTimes[i]
73 | circle.frame = frame
74 | circle.add(animation, forKey: "animation")
75 | layer.addSublayer(circle)
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallClipRotate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorBallClipRotate.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallClipRotate: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let duration: CFTimeInterval = 0.75
34 |
35 | // Scale animation
36 | let scaleAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
37 |
38 | scaleAnimation.keyTimes = [0, 0.5, 1]
39 | scaleAnimation.values = [1, 0.6, 1]
40 |
41 | // Rotate animation
42 | let rotateAnimation = CAKeyframeAnimation(keyPath: "transform.rotation.z")
43 |
44 | rotateAnimation.keyTimes = scaleAnimation.keyTimes
45 | rotateAnimation.values = [0, Double.pi, 2 * Double.pi]
46 |
47 | // Animation
48 | let animation = CAAnimationGroup()
49 |
50 | animation.animations = [scaleAnimation, rotateAnimation]
51 | animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
52 | animation.duration = duration
53 | animation.repeatCount = HUGE
54 | animation.isRemovedOnCompletion = false
55 |
56 | // Draw circle
57 | let circle = NVActivityIndicatorShape.ringThirdFour.layerWith(size: CGSize(width: size.width, height: size.height), color: color)
58 | let frame = CGRect(x: (layer.bounds.size.width - size.width) / 2,
59 | y: (layer.bounds.size.height - size.height) / 2,
60 | width: size.width,
61 | height: size.height)
62 |
63 | circle.frame = frame
64 | circle.add(animation, forKey: "animation")
65 | layer.addSublayer(circle)
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallGridBeat.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallGridBeat.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallGridBeat: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let circleSpacing: CGFloat = 2
34 | let circleSize = (size.width - circleSpacing * 2) / 3
35 | let x = (layer.bounds.size.width - size.width) / 2
36 | let y = (layer.bounds.size.height - size.height) / 2
37 | let durations = [0.96, 0.93, 1.19, 1.13, 1.34, 0.94, 1.2, 0.82, 1.19]
38 | let beginTime = CACurrentMediaTime()
39 | let beginTimes = [0.36, 0.4, 0.68, 0.41, 0.71, -0.15, -0.12, 0.01, 0.32]
40 | let timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
41 |
42 | // Animation
43 | let animation = CAKeyframeAnimation(keyPath: "opacity")
44 |
45 | animation.keyTimes = [0, 0.5, 1]
46 | animation.timingFunctions = [timingFunction, timingFunction]
47 | animation.values = [1, 0.7, 1]
48 | animation.repeatCount = HUGE
49 | animation.isRemovedOnCompletion = false
50 |
51 | // Draw circles
52 | for i in 0 ..< 3 {
53 | for j in 0 ..< 3 {
54 | let circle = NVActivityIndicatorShape.circle.layerWith(size: CGSize(width: circleSize, height: circleSize), color: color)
55 | let frame = CGRect(x: x + circleSize * CGFloat(j) + circleSpacing * CGFloat(j),
56 | y: y + circleSize * CGFloat(i) + circleSpacing * CGFloat(i),
57 | width: circleSize,
58 | height: circleSize)
59 |
60 | animation.duration = durations[3 * i + j]
61 | animation.beginTime = beginTime + beginTimes[3 * i + j]
62 | circle.frame = frame
63 | circle.add(animation, forKey: "animation")
64 | layer.addSublayer(circle)
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallGridPulse.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallGridPulse.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallGridPulse: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let circleSpacing: CGFloat = 2
34 | let circleSize = (size.width - circleSpacing * 2) / 3
35 | let x = (layer.bounds.size.width - size.width) / 2
36 | let y = (layer.bounds.size.height - size.height) / 2
37 | let durations: [CFTimeInterval] = [0.72, 1.02, 1.28, 1.42, 1.45, 1.18, 0.87, 1.45, 1.06]
38 | let beginTime = CACurrentMediaTime()
39 | let beginTimes: [CFTimeInterval] = [ -0.06, 0.25, -0.17, 0.48, 0.31, 0.03, 0.46, 0.78, 0.45]
40 | let timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
41 |
42 | // Scale animation
43 | let scaleAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
44 |
45 | scaleAnimation.keyTimes = [0, 0.5, 1]
46 | scaleAnimation.timingFunctions = [timingFunction, timingFunction]
47 | scaleAnimation.values = [1, 0.5, 1]
48 |
49 | // Opacity animation
50 | let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
51 |
52 | opacityAnimation.keyTimes = [0, 0.5, 1]
53 | opacityAnimation.timingFunctions = [timingFunction, timingFunction]
54 | opacityAnimation.values = [1, 0.7, 1]
55 |
56 | // Animation
57 | let animation = CAAnimationGroup()
58 |
59 | animation.animations = [scaleAnimation, opacityAnimation]
60 | animation.repeatCount = HUGE
61 | animation.isRemovedOnCompletion = false
62 |
63 | // Draw circles
64 | for i in 0 ..< 3 {
65 | for j in 0 ..< 3 {
66 | let circle = NVActivityIndicatorShape.circle.layerWith(size: CGSize(width: circleSize, height: circleSize), color: color)
67 | let frame = CGRect(x: x + circleSize * CGFloat(j) + circleSpacing * CGFloat(j),
68 | y: y + circleSize * CGFloat(i) + circleSpacing * CGFloat(i),
69 | width: circleSize,
70 | height: circleSize)
71 |
72 | animation.duration = durations[3 * i + j]
73 | animation.beginTime = beginTime + beginTimes[3 * i + j]
74 | circle.frame = frame
75 | circle.add(animation, forKey: "animation")
76 | layer.addSublayer(circle)
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallPulse.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallPulse.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallPulse: NVActivityIndicatorAnimationDelegate {
31 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
32 | let circleSpacing: CGFloat = 2
33 | let circleSize: CGFloat = (size.width - 2 * circleSpacing) / 3
34 | let x: CGFloat = (layer.bounds.size.width - size.width) / 2
35 | let y: CGFloat = (layer.bounds.size.height - circleSize) / 2
36 | let duration: CFTimeInterval = 0.75
37 | let beginTime = CACurrentMediaTime()
38 | let beginTimes: [CFTimeInterval] = [0.12, 0.24, 0.36]
39 | let timingFunction = CAMediaTimingFunction(controlPoints: 0.2, 0.68, 0.18, 1.08)
40 | let animation = CAKeyframeAnimation(keyPath: "transform.scale")
41 |
42 | // Animation
43 | animation.keyTimes = [0, 0.3, 1]
44 | animation.timingFunctions = [timingFunction, timingFunction]
45 | animation.values = [1, 0.3, 1]
46 | animation.duration = duration
47 | animation.repeatCount = HUGE
48 | animation.isRemovedOnCompletion = false
49 |
50 | // Draw circles
51 | for i in 0 ..< 3 {
52 | let circle = NVActivityIndicatorShape.circle.layerWith(size: CGSize(width: circleSize, height: circleSize), color: color)
53 | let frame = CGRect(x: x + circleSize * CGFloat(i) + circleSpacing * CGFloat(i),
54 | y: y,
55 | width: circleSize,
56 | height: circleSize)
57 |
58 | animation.beginTime = beginTime + beginTimes[i]
59 | circle.frame = frame
60 | circle.add(animation, forKey: "animation")
61 | layer.addSublayer(circle)
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallPulseSync.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallPulseSync.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallPulseSync: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let circleSpacing: CGFloat = 2
34 | let circleSize = (size.width - circleSpacing * 2) / 3
35 | let x = (layer.bounds.size.width - size.width) / 2
36 | let y = (layer.bounds.size.height - circleSize) / 2
37 | let deltaY = (size.height / 2 - circleSize / 2) / 2
38 | let duration: CFTimeInterval = 0.6
39 | let beginTime = CACurrentMediaTime()
40 | let beginTimes: [CFTimeInterval] = [0.07, 0.14, 0.21]
41 | let timingFunciton = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
42 |
43 | // Animation
44 | let animation = CAKeyframeAnimation(keyPath: "transform.translation.y")
45 |
46 | animation.keyTimes = [0, 0.33, 0.66, 1]
47 | animation.timingFunctions = [timingFunciton, timingFunciton, timingFunciton]
48 | animation.values = [0, deltaY, -deltaY, 0]
49 | animation.duration = duration
50 | animation.repeatCount = HUGE
51 | animation.isRemovedOnCompletion = false
52 |
53 | // Draw circles
54 | for i in 0 ..< 3 {
55 | let circle = NVActivityIndicatorShape.circle.layerWith(size: CGSize(width: circleSize, height: circleSize), color: color)
56 | let frame = CGRect(x: x + circleSize * CGFloat(i) + circleSpacing * CGFloat(i),
57 | y: y,
58 | width: circleSize,
59 | height: circleSize)
60 |
61 | animation.beginTime = beginTime + beginTimes[i]
62 | circle.frame = frame
63 | circle.add(animation, forKey: "animation")
64 | layer.addSublayer(circle)
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallRotateChase.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallRotateChase.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallRotateChase: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let circleSize = size.width / 5
34 |
35 | // Draw circles
36 | for i in 0 ..< 5 {
37 | let factor = Float(i) * 1 / 5
38 | let circle = NVActivityIndicatorShape.circle.layerWith(size: CGSize(width: circleSize, height: circleSize), color: color)
39 | let animation = rotateAnimation(factor, x: layer.bounds.size.width / 2, y: layer.bounds.size.height / 2, size: CGSize(width: size.width - circleSize, height: size.height - circleSize))
40 |
41 | circle.frame = CGRect(x: 0, y: 0, width: circleSize, height: circleSize)
42 | circle.add(animation, forKey: "animation")
43 | layer.addSublayer(circle)
44 | }
45 | }
46 |
47 | func rotateAnimation(_ rate: Float, x: CGFloat, y: CGFloat, size: CGSize) -> CAAnimationGroup {
48 | let duration: CFTimeInterval = 1.5
49 | let fromScale = 1 - rate
50 | let toScale = 0.2 + rate
51 | let timeFunc = CAMediaTimingFunction(controlPoints: 0.5, 0.15 + rate, 0.25, 1)
52 |
53 | // Scale animation
54 | let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
55 | scaleAnimation.duration = duration
56 | scaleAnimation.repeatCount = HUGE
57 | scaleAnimation.fromValue = fromScale
58 | scaleAnimation.toValue = toScale
59 |
60 | // Position animation
61 | let positionAnimation = CAKeyframeAnimation(keyPath: "position")
62 | positionAnimation.duration = duration
63 | positionAnimation.repeatCount = HUGE
64 | positionAnimation.path = UIBezierPath(arcCenter: CGPoint(x: x, y: y), radius: size.width / 2, startAngle: CGFloat(3 * Double.pi * 0.5), endAngle: CGFloat(3 * Double.pi * 0.5 + 2 * Double.pi), clockwise: true).cgPath
65 |
66 | // Aniamtion
67 | let animation = CAAnimationGroup()
68 | animation.animations = [scaleAnimation, positionAnimation]
69 | animation.timingFunction = timeFunc
70 | animation.duration = duration
71 | animation.repeatCount = HUGE
72 | animation.isRemovedOnCompletion = false
73 |
74 | return animation
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallScale.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallScale.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallScale: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let duration: CFTimeInterval = 1
34 |
35 | // Scale animation
36 | let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
37 |
38 | scaleAnimation.duration = duration
39 | scaleAnimation.fromValue = 0
40 | scaleAnimation.toValue = 1
41 |
42 | // Opacity animation
43 | let opacityAnimation = CABasicAnimation(keyPath: "opacity")
44 |
45 | opacityAnimation.duration = duration
46 | opacityAnimation.fromValue = 1
47 | opacityAnimation.toValue = 0
48 |
49 | // Animation
50 | let animation = CAAnimationGroup()
51 |
52 | animation.animations = [scaleAnimation, opacityAnimation]
53 | animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
54 | animation.duration = duration
55 | animation.repeatCount = HUGE
56 | animation.isRemovedOnCompletion = false
57 |
58 | // Draw circle
59 | let circle = NVActivityIndicatorShape.circle.layerWith(size: size, color: color)
60 |
61 | circle.frame = CGRect(x: (layer.bounds.size.width - size.width) / 2,
62 | y: (layer.bounds.size.height - size.height) / 2,
63 | width: size.width,
64 | height: size.height)
65 | circle.add(animation, forKey: "animation")
66 | layer.addSublayer(circle)
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallScaleMultiple.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallScaleMultiple.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallScaleMultiple: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let duration: CFTimeInterval = 1
34 | let beginTime = CACurrentMediaTime()
35 | let beginTimes = [0, 0.2, 0.4]
36 |
37 | // Scale animation
38 | let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
39 |
40 | scaleAnimation.duration = duration
41 | scaleAnimation.fromValue = 0
42 | scaleAnimation.toValue = 1
43 |
44 | // Opacity animation
45 | let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
46 |
47 | opacityAnimation.duration = duration
48 | opacityAnimation.keyTimes = [0, 0.05, 1]
49 | opacityAnimation.values = [0, 1, 0]
50 |
51 | // Animation
52 | let animation = CAAnimationGroup()
53 |
54 | animation.animations = [scaleAnimation, opacityAnimation]
55 | animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
56 | animation.duration = duration
57 | animation.repeatCount = HUGE
58 | animation.isRemovedOnCompletion = false
59 |
60 | // Draw balls
61 | for i in 0 ..< 3 {
62 | let circle = NVActivityIndicatorShape.circle.layerWith(size: size, color: color)
63 | let frame = CGRect(x: (layer.bounds.size.width - size.width) / 2,
64 | y: (layer.bounds.size.height - size.height) / 2,
65 | width: size.width,
66 | height: size.height)
67 |
68 | animation.beginTime = beginTime + beginTimes[i]
69 | circle.frame = frame
70 | circle.opacity = 0
71 | circle.add(animation, forKey: "animation")
72 | layer.addSublayer(circle)
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallScaleRipple.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallScaleRipple.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallScaleRipple: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let duration: CFTimeInterval = 1
34 | let timingFunction = CAMediaTimingFunction(controlPoints: 0.21, 0.53, 0.56, 0.8)
35 |
36 | // Scale animation
37 | let scaleAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
38 |
39 | scaleAnimation.keyTimes = [0, 0.7]
40 | scaleAnimation.timingFunction = timingFunction
41 | scaleAnimation.values = [0.1, 1]
42 | scaleAnimation.duration = duration
43 |
44 | // Opacity animation
45 | let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
46 |
47 | opacityAnimation.keyTimes = [0, 0.7, 1]
48 | opacityAnimation.timingFunctions = [timingFunction, timingFunction]
49 | opacityAnimation.values = [1, 0.7, 0]
50 | opacityAnimation.duration = duration
51 |
52 | // Animation
53 | let animation = CAAnimationGroup()
54 |
55 | animation.animations = [scaleAnimation, opacityAnimation]
56 | animation.duration = duration
57 | animation.repeatCount = HUGE
58 | animation.isRemovedOnCompletion = false
59 |
60 | // Draw circle
61 | let circle = NVActivityIndicatorShape.ring.layerWith(size: size, color: color)
62 | let frame = CGRect(x: (layer.bounds.size.width - size.width) / 2,
63 | y: (layer.bounds.size.height - size.height) / 2,
64 | width: size.width,
65 | height: size.height)
66 |
67 | circle.frame = frame
68 | circle.add(animation, forKey: "animation")
69 | layer.addSublayer(circle)
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallScaleRippleMultiple.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallScaleRippleMultiple.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallScaleRippleMultiple: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let duration: CFTimeInterval = 1.25
34 | let beginTime = CACurrentMediaTime()
35 | let beginTimes = [0, 0.2, 0.4]
36 | let timingFunction = CAMediaTimingFunction(controlPoints: 0.21, 0.53, 0.56, 0.8)
37 |
38 | // Scale animation
39 | let scaleAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
40 |
41 | scaleAnimation.keyTimes = [0, 0.7]
42 | scaleAnimation.timingFunction = timingFunction
43 | scaleAnimation.values = [0, 1]
44 | scaleAnimation.duration = duration
45 |
46 | // Opacity animation
47 | let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
48 |
49 | opacityAnimation.keyTimes = [0, 0.7, 1]
50 | opacityAnimation.timingFunctions = [timingFunction, timingFunction]
51 | opacityAnimation.values = [1, 0.7, 0]
52 | opacityAnimation.duration = duration
53 |
54 | // Animation
55 | let animation = CAAnimationGroup()
56 |
57 | animation.animations = [scaleAnimation, opacityAnimation]
58 | animation.duration = duration
59 | animation.repeatCount = HUGE
60 | animation.isRemovedOnCompletion = false
61 |
62 | // Draw circles
63 | for i in 0 ..< 3 {
64 | let circle = NVActivityIndicatorShape.ring.layerWith(size: size, color: color)
65 | let frame = CGRect(x: (layer.bounds.size.width - size.width) / 2,
66 | y: (layer.bounds.size.height - size.height) / 2,
67 | width: size.width,
68 | height: size.height)
69 |
70 | animation.beginTime = beginTime + beginTimes[i]
71 | circle.frame = frame
72 | circle.add(animation, forKey: "animation")
73 | layer.addSublayer(circle)
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallZigZag.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallZigZag.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 | import QuartzCore
30 |
31 | class NVActivityIndicatorAnimationBallZigZag: NVActivityIndicatorAnimationDelegate {
32 |
33 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
34 | let circleSize: CGFloat = size.width / 5
35 | let duration: CFTimeInterval = 0.7
36 | let deltaX = size.width / 2 - circleSize / 2
37 | let deltaY = size.height / 2 - circleSize / 2
38 | let frame = CGRect(x: (layer.bounds.size.width - circleSize) / 2, y: (layer.bounds.size.height - circleSize) / 2, width: circleSize, height: circleSize)
39 |
40 | // Circle 1 animation
41 | let animation = CAKeyframeAnimation(keyPath: "transform")
42 |
43 | animation.keyTimes = [0, 0.33, 0.66, 1]
44 | animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
45 |
46 | animation.values = [
47 | NSValue(caTransform3D: CATransform3DMakeTranslation(0, 0, 0)),
48 | NSValue(caTransform3D: CATransform3DMakeTranslation(-deltaX, -deltaY, 0)),
49 | NSValue(caTransform3D: CATransform3DMakeTranslation(deltaX, -deltaY, 0)),
50 | NSValue(caTransform3D: CATransform3DMakeTranslation(0, 0, 0)),
51 | ]
52 | animation.duration = duration
53 | animation.repeatCount = HUGE
54 | animation.isRemovedOnCompletion = false
55 |
56 | // Draw circle 1
57 | circleAt(frame: frame, layer: layer, size: CGSize(width: circleSize, height: circleSize), color: color, animation: animation)
58 |
59 | // Circle 2 animation
60 | animation.values = [
61 | NSValue(caTransform3D: CATransform3DMakeTranslation(0, 0, 0)),
62 | NSValue(caTransform3D: CATransform3DMakeTranslation(deltaX, deltaY, 0)),
63 | NSValue(caTransform3D: CATransform3DMakeTranslation(-deltaX, deltaY, 0)),
64 | NSValue(caTransform3D: CATransform3DMakeTranslation(0, 0, 0)),
65 | ]
66 |
67 | // Draw circle 2
68 | circleAt(frame: frame, layer: layer, size: CGSize(width: circleSize, height: circleSize), color: color, animation: animation)
69 | }
70 |
71 | func circleAt(frame: CGRect, layer: CALayer, size: CGSize, color: UIColor, animation: CAAnimation) {
72 | let circle = NVActivityIndicatorShape.circle.layerWith(size: size, color: color)
73 |
74 | circle.frame = frame
75 | circle.add(animation, forKey: "animation")
76 | layer.addSublayer(circle)
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBallZigZagDeflect.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBallZigZagDeflect.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBallZigZagDeflect: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let circleSize: CGFloat = size.width / 5
34 | let duration: CFTimeInterval = 0.75
35 | let deltaX = size.width / 2 - circleSize / 2
36 | let deltaY = size.height / 2 - circleSize / 2
37 | let frame = CGRect(x: (layer.bounds.size.width - circleSize) / 2, y: (layer.bounds.size.height - circleSize) / 2, width: circleSize, height: circleSize)
38 |
39 | // Circle 1 animation
40 | let animation = CAKeyframeAnimation(keyPath: "transform")
41 |
42 | animation.keyTimes = [0, 0.33, 0.66, 1]
43 | animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
44 |
45 | animation.values = [
46 | NSValue(caTransform3D: CATransform3DMakeTranslation(0, 0, 0)),
47 | NSValue(caTransform3D: CATransform3DMakeTranslation(-deltaX, -deltaY, 0)),
48 | NSValue(caTransform3D: CATransform3DMakeTranslation(deltaX, -deltaY, 0)),
49 | NSValue(caTransform3D: CATransform3DMakeTranslation(0, 0, 0)),
50 | ]
51 | animation.duration = duration
52 | animation.repeatCount = HUGE
53 | animation.autoreverses = true
54 | animation.isRemovedOnCompletion = false
55 |
56 | // Draw circle 1
57 | circleAt(frame: frame, layer: layer, size: CGSize(width: circleSize, height: circleSize), color: color, animation: animation)
58 |
59 | // Circle 2 animation
60 | animation.values = [
61 | NSValue(caTransform3D: CATransform3DMakeTranslation(0, 0, 0)),
62 | NSValue(caTransform3D: CATransform3DMakeTranslation(deltaX, deltaY, 0)),
63 | NSValue(caTransform3D: CATransform3DMakeTranslation(-deltaX, deltaY, 0)),
64 | NSValue(caTransform3D: CATransform3DMakeTranslation(0, 0, 0)),
65 | ]
66 |
67 | // Draw circle 2
68 | circleAt(frame: frame, layer: layer, size: CGSize(width: circleSize, height: circleSize), color: color, animation: animation)
69 | }
70 |
71 | func circleAt(frame: CGRect, layer: CALayer, size: CGSize, color: UIColor, animation: CAAnimation) {
72 | let circle = NVActivityIndicatorShape.circle.layerWith(size: size, color: color)
73 |
74 | circle.frame = frame
75 | circle.add(animation, forKey: "animation")
76 | layer.addSublayer(circle)
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationBlank.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBlank.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationBlank: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in _: CALayer, size _: CGSize, color _: UIColor) {
33 | // Do nothing
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationLineScale.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationBarScale.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationLineScale: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let lineSize = size.width / 9
34 | let x = (layer.bounds.size.width - size.width) / 2
35 | let y = (layer.bounds.size.height - size.height) / 2
36 | let duration: CFTimeInterval = 1
37 | let beginTime = CACurrentMediaTime()
38 | let beginTimes = [0.1, 0.2, 0.3, 0.4, 0.5]
39 | let timingFunction = CAMediaTimingFunction(controlPoints: 0.2, 0.68, 0.18, 1.08)
40 |
41 | // Animation
42 | let animation = CAKeyframeAnimation(keyPath: "transform.scale.y")
43 |
44 | animation.keyTimes = [0, 0.5, 1]
45 | animation.timingFunctions = [timingFunction, timingFunction]
46 | animation.values = [1, 0.4, 1]
47 | animation.duration = duration
48 | animation.repeatCount = HUGE
49 | animation.isRemovedOnCompletion = false
50 |
51 | // Draw lines
52 | for i in 0 ..< 5 {
53 | let line = NVActivityIndicatorShape.line.layerWith(size: CGSize(width: lineSize, height: size.height), color: color)
54 | let frame = CGRect(x: x + lineSize * 2 * CGFloat(i), y: y, width: lineSize, height: size.height)
55 |
56 | animation.beginTime = beginTime + beginTimes[i]
57 | line.frame = frame
58 | line.add(animation, forKey: "animation")
59 | layer.addSublayer(line)
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationLineScaleParty.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationLineScaleParty.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationLineScaleParty: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let lineSize = size.width / 7
34 | let x = (layer.bounds.size.width - size.width) / 2
35 | let y = (layer.bounds.size.height - size.height) / 2
36 | let durations: [CFTimeInterval] = [1.26, 0.43, 1.01, 0.73]
37 | let beginTime = CACurrentMediaTime()
38 | let beginTimes: [CFTimeInterval] = [0.77, 0.29, 0.28, 0.74]
39 | let timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
40 |
41 | // Animation
42 | let animation = CAKeyframeAnimation(keyPath: "transform.scale")
43 |
44 | animation.keyTimes = [0, 0.5, 1]
45 | animation.timingFunctions = [timingFunction, timingFunction]
46 | animation.values = [1, 0.5, 1]
47 | animation.repeatCount = HUGE
48 | animation.isRemovedOnCompletion = false
49 |
50 | for i in 0 ..< 4 {
51 | let line = NVActivityIndicatorShape.line.layerWith(size: CGSize(width: lineSize, height: size.height), color: color)
52 | let frame = CGRect(x: x + lineSize * 2 * CGFloat(i), y: y, width: lineSize, height: size.height)
53 |
54 | animation.beginTime = beginTime + beginTimes[i]
55 | animation.duration = durations[i]
56 | line.frame = frame
57 | line.add(animation, forKey: "animation")
58 | layer.addSublayer(line)
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationLineScalePulseOut.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationLineScalePulseOut.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationLineScalePulseOut: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let lineSize = size.width / 9
34 | let x = (layer.bounds.size.width - size.width) / 2
35 | let y = (layer.bounds.size.height - size.height) / 2
36 | let duration: CFTimeInterval = 1
37 | let beginTime = CACurrentMediaTime()
38 | let beginTimes = [0.4, 0.2, 0, 0.2, 0.4]
39 | let timingFunction = CAMediaTimingFunction(controlPoints: 0.85, 0.25, 0.37, 0.85)
40 |
41 | // Animation
42 | let animation = CAKeyframeAnimation(keyPath: "transform.scale.y")
43 |
44 | animation.keyTimes = [0, 0.5, 1]
45 | animation.timingFunctions = [timingFunction, timingFunction]
46 | animation.values = [1, 0.4, 1]
47 | animation.duration = duration
48 | animation.repeatCount = HUGE
49 | animation.isRemovedOnCompletion = false
50 |
51 | // Draw lines
52 | for i in 0 ..< 5 {
53 | let line = NVActivityIndicatorShape.line.layerWith(size: CGSize(width: lineSize, height: size.height), color: color)
54 | let frame = CGRect(x: x + lineSize * 2 * CGFloat(i),
55 | y: y,
56 | width: lineSize,
57 | height: size.height)
58 |
59 | animation.beginTime = beginTime + beginTimes[i]
60 | line.frame = frame
61 | line.add(animation, forKey: "animation")
62 | layer.addSublayer(line)
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationLineScalePulseOutRapid.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationLineScalePulseOutRapid.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationLineScalePulseOutRapid: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let lineSize = size.width / 9
34 | let x = (layer.bounds.size.width - size.width) / 2
35 | let y = (layer.bounds.size.height - size.height) / 2
36 | let duration: CFTimeInterval = 0.9
37 | let beginTime = CACurrentMediaTime()
38 | let beginTimes = [0.5, 0.25, 0, 0.25, 0.5]
39 | let timingFunction = CAMediaTimingFunction(controlPoints: 0.11, 0.49, 0.38, 0.78)
40 |
41 | // Animation
42 | let animation = CAKeyframeAnimation(keyPath: "transform.scale.y")
43 |
44 | animation.keyTimes = [0, 0.8, 0.9]
45 | animation.timingFunctions = [timingFunction, timingFunction]
46 | animation.beginTime = beginTime
47 | animation.values = [1, 0.3, 1]
48 | animation.duration = duration
49 | animation.repeatCount = HUGE
50 | animation.isRemovedOnCompletion = false
51 |
52 | // Draw lines
53 | for i in 0 ..< 5 {
54 | let line = NVActivityIndicatorShape.line.layerWith(size: CGSize(width: lineSize, height: size.height), color: color)
55 | let frame = CGRect(x: x + lineSize * 2 * CGFloat(i),
56 | y: y,
57 | width: lineSize,
58 | height: size.height)
59 |
60 | animation.beginTime = beginTime + beginTimes[i]
61 | line.frame = frame
62 | line.add(animation, forKey: "animation")
63 | layer.addSublayer(line)
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationSemiCircleSpin.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationSemiCircleSpin.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationSemiCircleSpin: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let duration: CFTimeInterval = 0.6
34 |
35 | // Animation
36 | let animation = CAKeyframeAnimation(keyPath: "transform.rotation.z")
37 |
38 | animation.keyTimes = [0, 0.5, 1]
39 | animation.values = [0, Double.pi, 2 * Double.pi]
40 | animation.duration = duration
41 | animation.repeatCount = HUGE
42 | animation.isRemovedOnCompletion = false
43 |
44 | // Draw circle
45 | let circle = NVActivityIndicatorShape.circleSemi.layerWith(size: size, color: color)
46 | let frame = CGRect(
47 | x: (layer.bounds.width - size.width) / 2,
48 | y: (layer.bounds.height - size.height) / 2,
49 | width: size.width,
50 | height: size.height
51 | )
52 |
53 | circle.frame = frame
54 | circle.add(animation, forKey: "animation")
55 | layer.addSublayer(circle)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationSquareSpin.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationSquareSpin.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationSquareSpin: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let duration: CFTimeInterval = 3
34 | let timingFunction = CAMediaTimingFunction(controlPoints: 0.09, 0.57, 0.49, 0.9)
35 |
36 | // Animation
37 | let animation = CAKeyframeAnimation(keyPath: "transform")
38 |
39 | animation.keyTimes = [0, 0.25, 0.5, 0.75, 1]
40 | animation.timingFunctions = [timingFunction, timingFunction, timingFunction, timingFunction]
41 | animation.values = [
42 | NSValue(caTransform3D: CATransform3DConcat(createRotateXTransform(angle: 0), createRotateYTransform(angle: 0))),
43 | NSValue(caTransform3D: CATransform3DConcat(createRotateXTransform(angle: CGFloat(Double.pi)), createRotateYTransform(angle: 0))),
44 | NSValue(caTransform3D: CATransform3DConcat(createRotateXTransform(angle: CGFloat(Double.pi)), createRotateYTransform(angle: CGFloat(Double.pi)))),
45 | NSValue(caTransform3D: CATransform3DConcat(createRotateXTransform(angle: 0), createRotateYTransform(angle: CGFloat(Double.pi)))),
46 | NSValue(caTransform3D: CATransform3DConcat(createRotateXTransform(angle: 0), createRotateYTransform(angle: 0))),
47 | ]
48 | animation.duration = duration
49 | animation.repeatCount = HUGE
50 | animation.isRemovedOnCompletion = false
51 |
52 | // Draw square
53 | let square = NVActivityIndicatorShape.rectangle.layerWith(size: size, color: color)
54 | let frame = CGRect(x: (layer.bounds.size.width - size.width) / 2,
55 | y: (layer.bounds.size.height - size.height) / 2,
56 | width: size.width,
57 | height: size.height)
58 |
59 | square.frame = frame
60 | square.add(animation, forKey: "animation")
61 | layer.addSublayer(square)
62 | }
63 |
64 | func createRotateXTransform(angle: CGFloat) -> CATransform3D {
65 | var transform = CATransform3DMakeRotation(angle, 1, 0, 0)
66 |
67 | transform.m34 = CGFloat(-1) / 100
68 |
69 | return transform
70 | }
71 |
72 | func createRotateYTransform(angle: CGFloat) -> CATransform3D {
73 | var transform = CATransform3DMakeRotation(angle, 0, 1, 0)
74 |
75 | transform.m34 = CGFloat(-1) / 100
76 |
77 | return transform
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/Animations/NVActivityIndicatorAnimationTriangleSkewSpin.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorAnimationTriangleSkewSpin.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | class NVActivityIndicatorAnimationTriangleSkewSpin: NVActivityIndicatorAnimationDelegate {
31 |
32 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor) {
33 | let x = (layer.bounds.size.width - size.width) / 2
34 | let y = (layer.bounds.size.height - size.height) / 2
35 | let duration: CFTimeInterval = 3
36 | let timingFunction = CAMediaTimingFunction(controlPoints: 0.09, 0.57, 0.49, 0.9)
37 |
38 | // Animation
39 | let animation = CAKeyframeAnimation(keyPath: "transform")
40 |
41 | animation.keyTimes = [0, 0.25, 0.5, 0.75, 1]
42 | animation.timingFunctions = [timingFunction, timingFunction, timingFunction, timingFunction]
43 | animation.values = [
44 | NSValue(caTransform3D: CATransform3DConcat(createRotateXTransform(angle: 0), createRotateYTransform(angle: 0))),
45 | NSValue(caTransform3D: CATransform3DConcat(createRotateXTransform(angle: CGFloat(Double.pi)), createRotateYTransform(angle: 0))),
46 | NSValue(caTransform3D: CATransform3DConcat(createRotateXTransform(angle: CGFloat(Double.pi)), createRotateYTransform(angle: CGFloat(Double.pi)))),
47 | NSValue(caTransform3D: CATransform3DConcat(createRotateXTransform(angle: 0), createRotateYTransform(angle: CGFloat(Double.pi)))),
48 | NSValue(caTransform3D: CATransform3DConcat(createRotateXTransform(angle: 0), createRotateYTransform(angle: 0))),
49 | ]
50 | animation.duration = duration
51 | animation.repeatCount = HUGE
52 | animation.isRemovedOnCompletion = false
53 |
54 | // Draw triangle
55 | let triangle = NVActivityIndicatorShape.triangle.layerWith(size: size, color: color)
56 |
57 | triangle.frame = CGRect(x: x, y: y, width: size.width, height: size.height)
58 | triangle.add(animation, forKey: "animation")
59 | layer.addSublayer(triangle)
60 | }
61 |
62 | func createRotateXTransform(angle: CGFloat) -> CATransform3D {
63 | var transform = CATransform3DMakeRotation(angle, 1, 0, 0)
64 |
65 | transform.m34 = CGFloat(-1) / 100
66 |
67 | return transform
68 | }
69 |
70 | func createRotateYTransform(angle: CGFloat) -> CATransform3D {
71 | var transform = CATransform3DMakeRotation(angle, 0, 1, 0)
72 |
73 | transform.m34 = CGFloat(-1) / 100
74 |
75 | return transform
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/NVActivityIndicatorAnimationDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorDelegate.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | protocol NVActivityIndicatorAnimationDelegate {
31 | func setUpAnimation(in layer: CALayer, size: CGSize, color: UIColor)
32 | }
33 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/NVActivityIndicatorView.h:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorView.h
3 | // NVActivityIndicatorView
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | #import
29 |
30 | //! Project version number for NVActivityIndicatorView.
31 | FOUNDATION_EXPORT double NVActivityIndicatorViewVersionNumber;
32 |
33 | //! Project version string for NVActivityIndicatorView.
34 | FOUNDATION_EXPORT const unsigned char NVActivityIndicatorViewVersionString[];
35 |
36 | // In this header, you should import all the public headers of your framework using statements like #import
37 |
38 |
39 |
--------------------------------------------------------------------------------
/PhotoBrowser/Frameworks/NVActivityIndicatorView/NVActivityIndicatorViewable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NVActivityIndicatorViewable.swift
3 | // NVActivityIndicatorViewDemo
4 | //
5 | // The MIT License (MIT)
6 |
7 | // Copyright (c) 2016 Vinh Nguyen
8 |
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy
10 | // of this software and associated documentation files (the "Software"), to deal
11 | // in the Software without restriction, including without limitation the rights
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | // copies of the Software, and to permit persons to whom the Software is
14 | // furnished to do so, subject to the following conditions:
15 |
16 | // The above copyright notice and this permission notice shall be included in all
17 | // copies or substantial portions of the Software.
18 |
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | // SOFTWARE.
26 | //
27 |
28 | import UIKit
29 |
30 | /**
31 | * UIViewController conforms this protocol to be able to display NVActivityIndicatorView as UI blocker.
32 | *
33 | * This extends abilities of UIViewController to display and remove UI blocker.
34 | */
35 | public protocol NVActivityIndicatorViewable {}
36 |
37 | public extension NVActivityIndicatorViewable where Self: UIViewController {
38 |
39 | /**
40 | Display UI blocker.
41 |
42 | Appropriate NVActivityIndicatorView.DEFAULT_* values are used for omitted params.
43 |
44 | - parameter size: size of activity indicator view.
45 | - parameter message: message displayed under activity indicator view.
46 | - parameter messageFont: font of message displayed under activity indicator view.
47 | - parameter type: animation type.
48 | - parameter color: color of activity indicator view.
49 | - parameter padding: padding of activity indicator view.
50 | - parameter displayTimeThreshold: display time threshold to actually display UI blocker.
51 | - parameter minimumDisplayTime: minimum display time of UI blocker.
52 | */
53 | public final func startAnimating(
54 | _ size: CGSize? = nil,
55 | message: String? = nil,
56 | messageFont: UIFont? = nil,
57 | type: NVActivityIndicatorType? = nil,
58 | color: UIColor? = nil,
59 | padding: CGFloat? = nil,
60 | displayTimeThreshold: Int? = nil,
61 | minimumDisplayTime: Int? = nil,
62 | backgroundColor: UIColor? = nil,
63 | textColor: UIColor? = nil) {
64 | let activityData = ActivityData(size: size,
65 | message: message,
66 | messageFont: messageFont,
67 | type: type,
68 | color: color,
69 | padding: padding,
70 | displayTimeThreshold: displayTimeThreshold,
71 | minimumDisplayTime: minimumDisplayTime,
72 | backgroundColor: backgroundColor,
73 | textColor: textColor)
74 |
75 | NVActivityIndicatorPresenter.sharedInstance.startAnimating(activityData)
76 | }
77 |
78 | /**
79 | Remove UI blocker.
80 | */
81 | public final func stopAnimating() {
82 | NVActivityIndicatorPresenter.sharedInstance.stopAnimating()
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/LaunchImage-2.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "minimum-system-version" : "7.0",
7 | "scale" : "2x"
8 | },
9 | {
10 | "orientation" : "portrait",
11 | "idiom" : "iphone",
12 | "minimum-system-version" : "7.0",
13 | "subtype" : "retina4",
14 | "scale" : "2x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "minimum-system-version" : "7.0",
7 | "scale" : "2x"
8 | },
9 | {
10 | "orientation" : "portrait",
11 | "idiom" : "iphone",
12 | "minimum-system-version" : "7.0",
13 | "subtype" : "retina4",
14 | "scale" : "2x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/1.imageset/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/Images.xcassets/Local/1.imageset/1.jpg
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "1.jpg"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/10.imageset/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/Images.xcassets/Local/10.imageset/10.jpg
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/10.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "10.jpg"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/2.imageset/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/Images.xcassets/Local/2.imageset/2.jpg
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "2.jpg"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/3.imageset/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/Images.xcassets/Local/3.imageset/3.jpg
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "3.jpg"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/4.imageset/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/Images.xcassets/Local/4.imageset/4.jpg
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "4.jpg"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/5.imageset/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/Images.xcassets/Local/5.imageset/5.jpg
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "5.jpg"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/6.imageset/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/Images.xcassets/Local/6.imageset/6.jpg
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "6.jpg"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/7.imageset/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/Images.xcassets/Local/7.imageset/7.jpg
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "7.jpg"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/8.imageset/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/Images.xcassets/Local/8.imageset/8.jpg
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/8.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "8.jpg"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/9.imageset/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/Images.xcassets/Local/9.imageset/9.jpg
--------------------------------------------------------------------------------
/PhotoBrowser/Images.xcassets/Local/9.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "9.jpg"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PhotoBrowser/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UIViewControllerBasedStatusBarAppearance
40 |
41 | NSAppTransportSecurity
42 |
43 | NSAllowsArbitraryLoads
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/PhotoBrowser/LangVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 冯成林 on 15/8/14.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum LangType: Int{
12 |
13 | case english
14 | case chinese
15 | }
16 |
17 |
18 |
19 |
20 |
21 | class LangVC: UIViewController {
22 |
23 | override func viewDidLoad() {
24 | super.viewDidLoad()
25 |
26 | }
27 | }
28 |
29 |
30 | extension LangVC{
31 |
32 |
33 | @IBAction func btnClick(_ sender: UIButton) {
34 |
35 | let photoTypeChooseVC = PhotoTypeChooseVC(nibName: "PhotoTypeChooseVC", bundle: nil)
36 | photoTypeChooseVC.langType = LangType(rawValue: sender.tag)
37 | self.navigationController?.pushViewController(photoTypeChooseVC, animated: true)
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/PhotoBrowser/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/Common/PhotoBrowser+Common.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CFPhotoBroserVC+Common.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 成林 on 15/8/2.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | let CFPBExtraWidth: CGFloat = 20
13 | let CFPBThumbNailWH: CGFloat = 120
14 |
15 | let CFPBSingleTapNofi = "CFPBSingleTapNofi"
16 | let CFPBDismissBtnClickNoti = "CFPBDismissBtnClickNoti"
17 | let PhotoBrowserDidShowNoti = "PhotoBrowserDidShowNoti"
18 | let PhotoBrowserDidDismissNoti = "PhotoBrowserDidDismissNoti"
19 | let CFPBShowKey = "CFPBShowKey"
20 | let CFPBCacheKey = "CFPBCacheKey"
21 |
22 | extension CGSize{
23 |
24 | var sizeWithExtraWidth: CGSize {return CGSize(width: self.width + CFPBExtraWidth, height: self.height)}
25 |
26 | var sizeMinusExtraWidth: CGSize {return CGSize(width: self.width - CFPBExtraWidth, height: self.height)}
27 |
28 | /** 按比例缩放 */
29 | func ratioSize(_ ratio: CGFloat) -> CGSize{
30 |
31 | return CGSize(width: self.width / ratio, height: self.height / ratio) }
32 |
33 | static func decisionShowSize(_ imgSize: CGSize, contentSize: CGSize) ->CGSize{
34 |
35 | let heightRatio = imgSize.height / contentSize.height
36 | let widthRatio = imgSize.width / contentSize.width
37 |
38 | if heightRatio > 1 && widthRatio>1 {return imgSize.ratioSize(max(heightRatio, widthRatio))}
39 |
40 | if heightRatio > 1 && widthRatio <= 1 {return imgSize.ratioSize(heightRatio)}
41 |
42 | if heightRatio <= 1 && widthRatio > 1 {return imgSize.ratioSize(widthRatio)}
43 |
44 | if heightRatio <= 1 && widthRatio <= 1 {return imgSize.ratioSize(max(heightRatio, widthRatio))}
45 |
46 | return imgSize
47 | }
48 | }
49 |
50 | extension UIView{
51 |
52 | /** Debug */
53 | func debug(_ color: UIColor = UIColor.red, borderWidth: CGFloat = 5){
54 | self.layer.borderColor = color.cgColor
55 | self.layer.borderWidth = borderWidth
56 | }
57 |
58 | }
59 |
60 |
61 |
62 | extension UIImage{
63 |
64 | /** 源于色彩的UIImage,可自定义size */
65 | class func imageWithColor(_ color: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1), size: CGSize = CGSize(width: 1, height: 1)) -> UIImage{
66 |
67 | let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
68 |
69 | //开启一个图形上下文
70 | UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
71 |
72 | //获取图形上下文
73 | let context = UIGraphicsGetCurrentContext()
74 |
75 | context?.setFillColor(color.cgColor)
76 |
77 | context?.fill(rect)
78 |
79 | //获取图像
80 | let image = UIGraphicsGetImageFromCurrentImageContext()
81 |
82 | //关闭上下文
83 | UIGraphicsEndImageContext();
84 |
85 | return image!;
86 | }
87 | }
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/Common/pic.bundle/cancel@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/PhotoBrowser/Common/pic.bundle/cancel@2x.png
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/Common/pic.bundle/cancel@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/PhotoBrowser/Common/pic.bundle/cancel@3x.png
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/Common/pic.bundle/save@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/PhotoBrowser/Common/pic.bundle/save@2x.png
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/Common/pic.bundle/save@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/PhotoBrowser/54240e519f1fca65b850a65f11ae71138c673805/PhotoBrowser/PhotoBrowser/Common/pic.bundle/save@3x.png
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/Controller/PhotoBrowser+HUD.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoBrowser+HUD.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 冯成林 on 15/8/11.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | extension PhotoBrowser{
13 |
14 |
15 | /** 展示 */
16 | func showHUD(_ text: String,autoDismiss: Double){
17 |
18 | UIView.animate(withDuration: 0.25, animations: { () -> Void in
19 | self.hud.alpha = 1
20 | })
21 |
22 | hud.text = text
23 |
24 | self.view.addSubview(hud)
25 | hud.make_center(offsest: CGPoint.zero, width: 120, height: 44)
26 |
27 | if autoDismiss == -1 {return}
28 |
29 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(autoDismiss * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: {[unowned self] () -> Void in
30 |
31 | self.dismissHUD()
32 | })
33 | }
34 |
35 | /** 消失 */
36 | func dismissHUD(){
37 |
38 | UIView.animate(withDuration: 0.25, animations: {[unowned self] () -> Void in
39 |
40 | self.hud.alpha = 0
41 |
42 | }, completion: { (compelte) -> Void in
43 |
44 | self.hud.text = ""
45 |
46 | self.hud.removeFromSuperview()
47 | })
48 | }
49 |
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/Controller/PhotoBrowser+Indicator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoBrowser+Indicator.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 冯成林 on 15/8/13.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension PhotoBrowser{
12 |
13 | /** pagecontrol准备 */
14 | func pagecontrolPrepare(){
15 |
16 | if !hideMsgForZoomAndDismissWithSingleTap {return}
17 |
18 | view.addSubview(pagecontrol)
19 | pagecontrol.make_bottomInsets_bottomHeight(left: 0, bottom: 0, right: 0, bottomHeight: 37)
20 | pagecontrol.numberOfPages = photoModels.count
21 | pagecontrol.isEnabled = false
22 | }
23 |
24 | /** pageControl页面变动 */
25 | func pageControlPageChanged(_ page: Int){
26 |
27 | if page<0 || page>=photoModels.count {return}
28 |
29 | if showType == PhotoBrowser.ShowType.zoomAndDismissWithSingleTap && hideMsgForZoomAndDismissWithSingleTap{
30 |
31 | pagecontrol.currentPage = page
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/Controller/PhotoBrowser+PBType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoBrowser+PBType.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 成林 on 15/8/2.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | extension PhotoBrowser{
13 |
14 | /** 展示样式 */
15 | enum ShowType{
16 |
17 | /** push展示:网易新闻 */
18 | case push
19 |
20 | /** modal展示:可能有需要 */
21 | case modal
22 |
23 | /** frame放大模式:单击相册可关闭 */
24 | case zoomAndDismissWithSingleTap
25 |
26 | /** frame放大模式:点击按钮可关闭 */
27 | case zoomAndDismissWithCancelBtnClick
28 | }
29 |
30 |
31 | /** 相册类型 */
32 | enum PhotoType{
33 |
34 | /** 本地相册 */
35 | case local
36 |
37 | /** 服务器相册 */
38 | case host
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/Layout/Layout.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Layout.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 成林 on 15/7/29.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension PhotoBrowser{
12 |
13 |
14 | class Layout: UICollectionViewFlowLayout {
15 |
16 | override init(){
17 |
18 | super.init()
19 |
20 | /** 配置 */
21 | layoutSetting()
22 | }
23 |
24 | required init(coder aDecoder: NSCoder) {
25 | super.init(coder: aDecoder)!
26 | }
27 |
28 | /** 配置 */
29 | func layoutSetting(){
30 |
31 | let size = UIScreen.main.bounds.size
32 | self.itemSize = size.sizeWithExtraWidth
33 |
34 | self.minimumInteritemSpacing = 0
35 | self.minimumLineSpacing = 0
36 | self.sectionInset = UIEdgeInsets.zero
37 | self.scrollDirection = UICollectionViewScrollDirection.horizontal
38 | }
39 |
40 | }
41 |
42 |
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/Model/PhotoBrowser+Model.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CFPhotoBroserVC+Model.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 成林 on 15/8/10.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension PhotoBrowser{
12 |
13 | class PhotoModel{
14 |
15 | /** 本地相册模式下的本地相册数据 */
16 | var localImg: UIImage!
17 |
18 | /** 网络相册模式下的网络相册URL地址 */
19 | /** 高清 */
20 | var hostHDImgURL: String!
21 |
22 | /** 缩略图 */
23 | var hostThumbnailImg: UIImage!
24 |
25 | /** 标题 */
26 | var titleStr: String!
27 |
28 | /** 详细说明文字 */
29 | var descStr: String!
30 |
31 | /** 源ImageView: zoom模式需要传 */
32 | var sourceView: UIView!
33 |
34 | var isLocal: Bool!
35 |
36 | /** 暴力去除异常 */
37 | var excetionFlag = false
38 |
39 | /** 由于hanake有bug,增加此属性 */
40 | var modelCell: UICollectionViewCell!
41 |
42 | /** 本地相册专业初始化方法 */
43 | init(localImg: UIImage!, titleStr: String!, descStr: String!, sourceView: UIView!){
44 |
45 | self.isLocal = true
46 |
47 | self.localImg = localImg
48 | self.titleStr = titleStr
49 | self.descStr = descStr
50 | self.sourceView = sourceView
51 | excetionFlag = true
52 | }
53 |
54 |
55 | /** 本地相册专业初始化方法 */
56 | init(hostHDImgURL: String!, hostThumbnailImg: UIImage!, titleStr: String!, descStr: String!, sourceView: UIView!){
57 |
58 | self.isLocal = false
59 |
60 | self.hostHDImgURL = hostHDImgURL
61 | self.hostThumbnailImg = hostThumbnailImg
62 | self.titleStr = titleStr
63 | self.descStr = descStr
64 | self.sourceView = sourceView
65 | excetionFlag = true
66 | }
67 |
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/PhotoBrowser.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoBrowser.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 成林 on 15/7/29.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PhotoBrowser: UIViewController {
12 |
13 | lazy var collectionView: UICollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: Layout())
14 |
15 | /** 展示样式:请设置 */
16 | var showType: ShowType!
17 |
18 | /** 相册类型:请设置 */
19 | var photoType: PhotoType!
20 |
21 | /** 相册数据 */
22 | var photoModels: [PhotoModel]!{didSet{collectionView.reloadData()}}
23 |
24 | /** 强制关闭一切信息显示: 仅仅针对ZoomAndDismissWithSingleTap模式有效 */
25 | var hideMsgForZoomAndDismissWithSingleTap: Bool = false
26 |
27 | lazy var pagecontrol = UIPageControl()
28 |
29 | var page: Int = 0 {didSet{pageControlPageChanged(page)}}
30 |
31 | weak var vc: UIViewController!
32 |
33 | var isNavBarHidden: Bool!
34 | var isTabBarHidden: Bool!
35 | var isStatusBarHidden: Bool!
36 |
37 | var showIndex: Int = 0
38 |
39 | var dismissBtn,saveBtn: UIButton!
40 | var isHiddenBar: Bool = false
41 |
42 | lazy var photoArchiverArr: [Int] = []
43 |
44 | deinit{NotificationCenter.default.removeObserver(self);print("deinit")}
45 |
46 | lazy var hud: UILabel = {
47 |
48 | let hud = UILabel()
49 | hud.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
50 | hud.textColor = UIColor.white
51 | hud.alpha = 0
52 | hud.textAlignment = NSTextAlignment.center
53 | hud.layer.cornerRadius = 5
54 | hud.layer.masksToBounds = true
55 | return hud
56 | }()
57 | }
58 |
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/View/CollectionView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoBrowser+CollectionView.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 成林 on 15/7/29.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension PhotoBrowser{
12 |
13 |
14 | class CollectionView: UICollectionView {
15 |
16 |
17 | }
18 |
19 | }
20 |
21 |
22 |
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoBrowser/View/ShowImageView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShowImageView.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 冯成林 on 15/8/12.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ShowImageView: UIImageView {
12 | var showSize:CGSize!
13 | }
14 |
--------------------------------------------------------------------------------
/PhotoBrowser/PhotoTypeChooseVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TypeChooseVC.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 冯成林 on 15/8/14.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | enum PhotoType: Int {
13 |
14 | case local
15 | case host
16 | }
17 |
18 |
19 |
20 | class PhotoTypeChooseVC: UIViewController {
21 |
22 | var langType: LangType!
23 |
24 | @IBOutlet weak var titleLabel: UILabel!
25 |
26 | @IBOutlet weak var localBtn: UIButton!
27 |
28 | @IBOutlet weak var hostBtn: UIButton!
29 | }
30 |
31 | extension PhotoTypeChooseVC{
32 |
33 | override func viewDidLoad() {
34 |
35 | super.viewDidLoad()
36 |
37 | if langType == LangType.chinese {return}
38 |
39 | titleLabel.text = "Select Type"
40 | localBtn.setTitle("Local Album", for: UIControlState())
41 | localBtn.titleLabel?.font = UIFont.systemFont(ofSize: 20)
42 | hostBtn.setTitle("Host Album", for: UIControlState())
43 | hostBtn.titleLabel?.font = UIFont.systemFont(ofSize: 20)
44 | }
45 |
46 | @IBAction func btnClick(_ sender: UIButton) {
47 |
48 | let showTypeChooseVC = ShowTypeChooseTVC(style: UITableViewStyle.plain)
49 | showTypeChooseVC.langType = langType
50 | showTypeChooseVC.photoType = PhotoType(rawValue: sender.tag)
51 | self.navigationController?.pushViewController(showTypeChooseVC, animated: true)
52 | }
53 |
54 |
55 |
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/PhotoBrowser/ShowTypeChooseTVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShowTypeChooseVCTableViewController.swift
3 | // PhotoBrowser
4 | //
5 | // Created by 冯成林 on 15/8/14.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ShowTypeChooseTVC: UITableViewController {
12 |
13 | var langType: LangType!
14 |
15 | var photoType: PhotoType!
16 |
17 | let rid = "ShowTypeChooseTVCCell"
18 |
19 | lazy var dataList: [String] = {["Push","Modal","CancelBtnClickDissmiss","SingleTapDismiss"]}()
20 |
21 |
22 | }
23 |
24 | extension ShowTypeChooseTVC{
25 |
26 | override func viewDidLoad() {
27 | super.viewDidLoad()
28 | tableView.tableFooterView = UIView()
29 | }
30 |
31 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
32 | return dataList.count
33 | }
34 |
35 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
36 |
37 | let cell = tableView.dequeueReusableCell(withIdentifier: rid) ?? UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: rid)
38 |
39 | cell.textLabel?.text = dataList[indexPath.row]
40 | cell.textLabel?.font = UIFont.systemFont(ofSize: 24)
41 | return cell
42 | }
43 |
44 | override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
45 | return 80
46 | }
47 |
48 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
49 |
50 | let displayVC = DisplayVC()
51 | displayVC.langType = langType
52 | displayVC.photoType = photoType
53 |
54 | switch indexPath.row {
55 |
56 | case 0:displayVC.showType = PhotoBrowser.ShowType.push
57 | case 1:displayVC.showType = PhotoBrowser.ShowType.modal
58 | case 2:displayVC.showType = PhotoBrowser.ShowType.zoomAndDismissWithCancelBtnClick
59 | case 3:displayVC.showType = PhotoBrowser.ShowType.zoomAndDismissWithSingleTap
60 | default: break
61 | }
62 |
63 | self.navigationController?.pushViewController(displayVC, animated: true)
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/PhotoBrowserTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/PhotoBrowserTests/PhotoBrowserTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoBrowserTests.swift
3 | // PhotoBrowserTests
4 | //
5 | // Created by 成林 on 15/8/15.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import XCTest
11 |
12 | class PhotoBrowserTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | XCTAssert(true, "Pass")
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measure() {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------