├── HYNavigation.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── runlhy.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── runlhy.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── HYNavigation.xcscheme
│ └── xcschememanagement.plist
├── HYNavigation
├── AppDelegate
│ ├── AppDelegate.h
│ └── AppDelegate.m
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ ├── more_.imageset
│ │ ├── Contents.json
│ │ └── more_@2x.png
│ └── search_.imageset
│ │ ├── Contents.json
│ │ └── search_@2x.png
├── Base.lproj
│ └── LaunchScreen.storyboard
├── HYPageView
│ ├── HYPageView.h
│ └── HYPageView.m
├── Info.plist
├── Vendors
│ └── YYWebImage
│ │ ├── Cache
│ │ ├── YYCache.h
│ │ ├── YYCache.m
│ │ ├── YYDiskCache.h
│ │ ├── YYDiskCache.m
│ │ ├── YYKVStorage.h
│ │ ├── YYKVStorage.m
│ │ ├── YYMemoryCache.h
│ │ └── YYMemoryCache.m
│ │ ├── Categories
│ │ ├── CALayer+YYWebImage.h
│ │ ├── CALayer+YYWebImage.m
│ │ ├── MKAnnotationView+YYWebImage.h
│ │ ├── MKAnnotationView+YYWebImage.m
│ │ ├── UIButton+YYWebImage.h
│ │ ├── UIButton+YYWebImage.m
│ │ ├── UIImage+YYWebImage.h
│ │ ├── UIImage+YYWebImage.m
│ │ ├── UIImageView+YYWebImage.h
│ │ ├── UIImageView+YYWebImage.m
│ │ ├── _YYWebImageSetter.h
│ │ └── _YYWebImageSetter.m
│ │ ├── Image
│ │ ├── YYAnimatedImageView.h
│ │ ├── YYAnimatedImageView.m
│ │ ├── YYFrameImage.h
│ │ ├── YYFrameImage.m
│ │ ├── YYImage.h
│ │ ├── YYImage.m
│ │ ├── YYImageCoder.h
│ │ ├── YYImageCoder.m
│ │ ├── YYSpriteSheetImage.h
│ │ └── YYSpriteSheetImage.m
│ │ ├── YYImageCache.h
│ │ ├── YYImageCache.m
│ │ ├── YYWebImage.h
│ │ ├── YYWebImageManager.h
│ │ ├── YYWebImageManager.m
│ │ ├── YYWebImageOperation.h
│ │ └── YYWebImageOperation.m
├── ViewControllers
│ ├── FirstViewViewController.h
│ ├── FirstViewViewController.m
│ ├── ViewController.h
│ ├── ViewController.m
│ └── WoterFlow
│ │ ├── WaterFlowCollectionViewController.h
│ │ ├── WaterFlowCollectionViewController.m
│ │ ├── WaterFlowLayout.h
│ │ └── WaterFlowLayout.m
├── Views
│ ├── WaterFlowCollectionViewCell.h
│ ├── WaterFlowCollectionViewCell.m
│ └── WaterFlowCollectionViewCell.xib
├── main.m
└── x.txt
└── README.md
/HYNavigation.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HYNavigation.xcodeproj/project.xcworkspace/xcuserdata/runlhy.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runlhy/HYPageView/66daecc3b421ba4f03b23fce22954a905a29753e/HYNavigation.xcodeproj/project.xcworkspace/xcuserdata/runlhy.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/HYNavigation.xcodeproj/xcuserdata/runlhy.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/HYNavigation.xcodeproj/xcuserdata/runlhy.xcuserdatad/xcschemes/HYNavigation.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/HYNavigation.xcodeproj/xcuserdata/runlhy.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | HYNavigation.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 62E0406C1D99910E00D6BE9D
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/HYNavigation/AppDelegate/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // HYNavigation
4 | //
5 | // Created by runlhy on 16/9/26.
6 | // Copyright © 2016年 Pengcent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/HYNavigation/AppDelegate/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // HYNavigation
4 | //
5 | // Created by runlhy on 16/9/26.
6 | // Copyright © 2016年 Pengcent. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "ViewController.h"
11 | #import "FirstViewViewController.h"
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 |
19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
20 |
21 |
22 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
23 |
24 | ViewController *viewController = [[ViewController alloc] init];
25 | FirstViewViewController *f = [FirstViewViewController new];
26 | UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
27 | self.window.rootViewController = viewController;
28 |
29 | self.window.backgroundColor = [UIColor whiteColor];
30 |
31 | [self.window makeKeyAndVisible];
32 |
33 | return YES;
34 | }
35 |
36 | - (void)applicationWillResignActive:(UIApplication *)application {
37 | // 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.
38 | // 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.
39 | }
40 |
41 | - (void)applicationDidEnterBackground:(UIApplication *)application {
42 | // 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.
43 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
44 | }
45 |
46 | - (void)applicationWillEnterForeground:(UIApplication *)application {
47 | // 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.
48 | }
49 |
50 | - (void)applicationDidBecomeActive:(UIApplication *)application {
51 | // 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.
52 | }
53 |
54 | - (void)applicationWillTerminate:(UIApplication *)application {
55 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/HYNavigation/Assets.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 | }
--------------------------------------------------------------------------------
/HYNavigation/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/HYNavigation/Assets.xcassets/more_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "more_@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/HYNavigation/Assets.xcassets/more_.imageset/more_@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runlhy/HYPageView/66daecc3b421ba4f03b23fce22954a905a29753e/HYNavigation/Assets.xcassets/more_.imageset/more_@2x.png
--------------------------------------------------------------------------------
/HYNavigation/Assets.xcassets/search_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "search_@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/HYNavigation/Assets.xcassets/search_.imageset/search_@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runlhy/HYPageView/66daecc3b421ba4f03b23fce22954a905a29753e/HYNavigation/Assets.xcassets/search_.imageset/search_@2x.png
--------------------------------------------------------------------------------
/HYNavigation/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/HYNavigation/HYPageView/HYPageView.h:
--------------------------------------------------------------------------------
1 | //
2 | // HYPageView.h
3 | // HYNavigation
4 | //
5 | // Created by runlhy on 16/9/27.
6 | // Copyright © 2016年 Pengcent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef void(^ClickTitleBlock)(NSInteger);
12 |
13 | @interface HYPageView : UIScrollView
14 | typedef NS_ENUM(NSInteger, HYPageViewStyle) {
15 | HYPageViewStyleA,
16 | HYPageViewStyleB
17 | };
18 |
19 | /** TitleButton Block */
20 | @property (nonatomic, copy) ClickTitleBlock clickTitleBlock;
21 |
22 | // Personalized configuration properties
23 | @property (nonatomic, strong) UIFont *font;
24 | @property (nonatomic, strong) UIColor *selectedColor;
25 | @property (nonatomic, strong) UIColor *unselectedColor;
26 | @property (nonatomic, strong) UIColor *topTabBottomLineColor;
27 | @property (nonatomic, assign) CGFloat leftSpace;
28 | @property (nonatomic, assign) CGFloat rightSpace;
29 | @property (nonatomic, assign) CGFloat minSpace;
30 | @property (nonatomic, assign) NSInteger defaultSubscript;
31 | @property (nonatomic, assign) HYPageViewStyle pageViewStyle;
32 | /**
33 | default 20.
34 | For translucent status bar
35 | */
36 | @property (nonatomic, assign) CGFloat topSpace;
37 | @property (nonatomic, strong) UIButton *leftButton;
38 | @property (nonatomic, strong) UIButton *rightButton;
39 |
40 | /**
41 | default YES.
42 | */
43 | @property (nonatomic, assign) BOOL isAdapteNavigationBar;
44 | /**
45 | default NO.
46 | */
47 | @property (nonatomic, assign) BOOL isAnimated;
48 | /**
49 | default YES.
50 | */
51 | @property (nonatomic, assign) BOOL isTranslucent;
52 | /**
53 | default YES ,Valid when only one page can be filled with all buttons
54 | */
55 | @property (nonatomic, assign) BOOL isAverage;
56 | /**
57 | default YES .
58 | */
59 | @property (nonatomic, assign) BOOL isShowTopTabBottomLine;
60 | /**
61 | default YES .
62 | */
63 | @property (nonatomic, assign) BOOL bodyPageBounces;
64 | /**
65 | default YES .
66 | */
67 | @property (nonatomic, assign) BOOL bodyPageScrollEnabled;
68 | /**
69 | default NO .
70 | */
71 | @property (nonatomic, assign) BOOL topTabBounces;
72 |
73 |
74 |
75 | /**
76 | Initializes and returns a newly allocated view object with the specified frame rectangle.
77 |
78 | @param frame ...
79 | @param titles Some title
80 | @param controllers Name of some controllers
81 | @param parameters You need to set a property called "parameter" for your controller to receive.
82 |
83 | @return self
84 | */
85 | - (instancetype)initWithFrame:(CGRect)frame withTitles:(NSArray *)titles withViewControllers:(NSArray *)controllers withParameters:(NSArray *)parameters;
86 |
87 | @end
88 |
--------------------------------------------------------------------------------
/HYNavigation/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 | NSAppTransportSecurity
26 |
27 | NSAllowsArbitraryLoads
28 |
29 |
30 | UILaunchStoryboardName
31 | LaunchScreen
32 | UIRequiredDeviceCapabilities
33 |
34 | armv7
35 |
36 | UISupportedInterfaceOrientations
37 |
38 | UIInterfaceOrientationPortrait
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Cache/YYCache.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYCache.h
3 | // YYCache
4 | //
5 | // Created by ibireme on 15/2/13.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | #if __has_include()
15 | FOUNDATION_EXPORT double YYCacheVersionNumber;
16 | FOUNDATION_EXPORT const unsigned char YYCacheVersionString[];
17 | #import
18 | #import
19 | #import
20 | #elif __has_include()
21 | #import
22 | #import
23 | #import
24 | #else
25 | #import "YYMemoryCache.h"
26 | #import "YYDiskCache.h"
27 | #import "YYKVStorage.h"
28 | #endif
29 |
30 | NS_ASSUME_NONNULL_BEGIN
31 |
32 |
33 | /**
34 | `YYCache` is a thread safe key-value cache.
35 |
36 | It use `YYMemoryCache` to store objects in a small and fast memory cache,
37 | and use `YYDiskCache` to persisting objects to a large and slow disk cache.
38 | See `YYMemoryCache` and `YYDiskCache` for more information.
39 | */
40 | @interface YYCache : NSObject
41 |
42 | /** The name of the cache, readonly. */
43 | @property (copy, readonly) NSString *name;
44 |
45 | /** The underlying memory cache. see `YYMemoryCache` for more information.*/
46 | @property (strong, readonly) YYMemoryCache *memoryCache;
47 |
48 | /** The underlying disk cache. see `YYDiskCache` for more information.*/
49 | @property (strong, readonly) YYDiskCache *diskCache;
50 |
51 | /**
52 | Create a new instance with the specified name.
53 | Multiple instances with the same name will make the cache unstable.
54 |
55 | @param name The name of the cache. It will create a dictionary with the name in
56 | the app's caches dictionary for disk cache. Once initialized you should not
57 | read and write to this directory.
58 | @result A new cache object, or nil if an error occurs.
59 | */
60 | - (nullable instancetype)initWithName:(NSString *)name;
61 |
62 | /**
63 | Create a new instance with the specified path.
64 | Multiple instances with the same name will make the cache unstable.
65 |
66 | @param path Full path of a directory in which the cache will write data.
67 | Once initialized you should not read and write to this directory.
68 | @result A new cache object, or nil if an error occurs.
69 | */
70 | - (nullable instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;
71 |
72 | /**
73 | Convenience Initializers
74 | Create a new instance with the specified name.
75 | Multiple instances with the same name will make the cache unstable.
76 |
77 | @param name The name of the cache. It will create a dictionary with the name in
78 | the app's caches dictionary for disk cache. Once initialized you should not
79 | read and write to this directory.
80 | @result A new cache object, or nil if an error occurs.
81 | */
82 | + (nullable instancetype)cacheWithName:(NSString *)name;
83 |
84 | /**
85 | Convenience Initializers
86 | Create a new instance with the specified path.
87 | Multiple instances with the same name will make the cache unstable.
88 |
89 | @param path Full path of a directory in which the cache will write data.
90 | Once initialized you should not read and write to this directory.
91 | @result A new cache object, or nil if an error occurs.
92 | */
93 | + (nullable instancetype)cacheWithPath:(NSString *)path;
94 |
95 | - (instancetype)init UNAVAILABLE_ATTRIBUTE;
96 | + (instancetype)new UNAVAILABLE_ATTRIBUTE;
97 |
98 | #pragma mark - Access Methods
99 | ///=============================================================================
100 | /// @name Access Methods
101 | ///=============================================================================
102 |
103 | /**
104 | Returns a boolean value that indicates whether a given key is in cache.
105 | This method may blocks the calling thread until file read finished.
106 |
107 | @param key A string identifying the value. If nil, just return NO.
108 | @return Whether the key is in cache.
109 | */
110 | - (BOOL)containsObjectForKey:(NSString *)key;
111 |
112 | /**
113 | Returns a boolean value with the block that indicates whether a given key is in cache.
114 | This method returns immediately and invoke the passed block in background queue
115 | when the operation finished.
116 |
117 | @param key A string identifying the value. If nil, just return NO.
118 | @param block A block which will be invoked in background queue when finished.
119 | */
120 | - (void)containsObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, BOOL contains))block;
121 |
122 | /**
123 | Returns the value associated with a given key.
124 | This method may blocks the calling thread until file read finished.
125 |
126 | @param key A string identifying the value. If nil, just return nil.
127 | @return The value associated with key, or nil if no value is associated with key.
128 | */
129 | - (nullable id)objectForKey:(NSString *)key;
130 |
131 | /**
132 | Returns the value associated with a given key.
133 | This method returns immediately and invoke the passed block in background queue
134 | when the operation finished.
135 |
136 | @param key A string identifying the value. If nil, just return nil.
137 | @param block A block which will be invoked in background queue when finished.
138 | */
139 | - (void)objectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key, id object))block;
140 |
141 | /**
142 | Sets the value of the specified key in the cache.
143 | This method may blocks the calling thread until file write finished.
144 |
145 | @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`.
146 | @param key The key with which to associate the value. If nil, this method has no effect.
147 | */
148 | - (void)setObject:(nullable id)object forKey:(NSString *)key;
149 |
150 | /**
151 | Sets the value of the specified key in the cache.
152 | This method returns immediately and invoke the passed block in background queue
153 | when the operation finished.
154 |
155 | @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`.
156 | @param block A block which will be invoked in background queue when finished.
157 | */
158 | - (void)setObject:(nullable id)object forKey:(NSString *)key withBlock:(nullable void(^)(void))block;
159 |
160 | /**
161 | Removes the value of the specified key in the cache.
162 | This method may blocks the calling thread until file delete finished.
163 |
164 | @param key The key identifying the value to be removed. If nil, this method has no effect.
165 | */
166 | - (void)removeObjectForKey:(NSString *)key;
167 |
168 | /**
169 | Removes the value of the specified key in the cache.
170 | This method returns immediately and invoke the passed block in background queue
171 | when the operation finished.
172 |
173 | @param key The key identifying the value to be removed. If nil, this method has no effect.
174 | @param block A block which will be invoked in background queue when finished.
175 | */
176 | - (void)removeObjectForKey:(NSString *)key withBlock:(nullable void(^)(NSString *key))block;
177 |
178 | /**
179 | Empties the cache.
180 | This method may blocks the calling thread until file delete finished.
181 | */
182 | - (void)removeAllObjects;
183 |
184 | /**
185 | Empties the cache.
186 | This method returns immediately and invoke the passed block in background queue
187 | when the operation finished.
188 |
189 | @param block A block which will be invoked in background queue when finished.
190 | */
191 | - (void)removeAllObjectsWithBlock:(void(^)(void))block;
192 |
193 | /**
194 | Empties the cache with block.
195 | This method returns immediately and executes the clear operation with block in background.
196 |
197 | @warning You should not send message to this instance in these blocks.
198 | @param progress This block will be invoked during removing, pass nil to ignore.
199 | @param end This block will be invoked at the end, pass nil to ignore.
200 | */
201 | - (void)removeAllObjectsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress
202 | endBlock:(nullable void(^)(BOOL error))end;
203 |
204 | @end
205 |
206 | NS_ASSUME_NONNULL_END
207 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Cache/YYCache.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYCache.m
3 | // YYCache
4 | //
5 | // Created by ibireme on 15/2/13.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import "YYCache.h"
13 | #import "YYMemoryCache.h"
14 | #import "YYDiskCache.h"
15 |
16 | @implementation YYCache
17 |
18 | - (instancetype) init {
19 | NSLog(@"Use \"initWithName\" or \"initWithPath\" to create YYCache instance.");
20 | return [self initWithPath:@""];
21 | }
22 |
23 | - (instancetype)initWithName:(NSString *)name {
24 | if (name.length == 0) return nil;
25 | NSString *cacheFolder = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
26 | NSString *path = [cacheFolder stringByAppendingPathComponent:name];
27 | return [self initWithPath:path];
28 | }
29 |
30 | - (instancetype)initWithPath:(NSString *)path {
31 | if (path.length == 0) return nil;
32 | YYDiskCache *diskCache = [[YYDiskCache alloc] initWithPath:path];
33 | if (!diskCache) return nil;
34 | NSString *name = [path lastPathComponent];
35 | YYMemoryCache *memoryCache = [YYMemoryCache new];
36 | memoryCache.name = name;
37 |
38 | self = [super init];
39 | _name = name;
40 | _diskCache = diskCache;
41 | _memoryCache = memoryCache;
42 | return self;
43 | }
44 |
45 | + (instancetype)cacheWithName:(NSString *)name {
46 | return [[self alloc] initWithName:name];
47 | }
48 |
49 | + (instancetype)cacheWithPath:(NSString *)path {
50 | return [[self alloc] initWithPath:path];
51 | }
52 |
53 | - (BOOL)containsObjectForKey:(NSString *)key {
54 | return [_memoryCache containsObjectForKey:key] || [_diskCache containsObjectForKey:key];
55 | }
56 |
57 | - (void)containsObjectForKey:(NSString *)key withBlock:(void (^)(NSString *key, BOOL contains))block {
58 | if (!block) return;
59 |
60 | if ([_memoryCache containsObjectForKey:key]) {
61 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
62 | block(key, YES);
63 | });
64 | } else {
65 | [_diskCache containsObjectForKey:key withBlock:block];
66 | }
67 | }
68 |
69 | - (id)objectForKey:(NSString *)key {
70 | id object = [_memoryCache objectForKey:key];
71 | if (!object) {
72 | object = [_diskCache objectForKey:key];
73 | if (object) {
74 | [_memoryCache setObject:object forKey:key];
75 | }
76 | }
77 | return object;
78 | }
79 |
80 | - (void)objectForKey:(NSString *)key withBlock:(void (^)(NSString *key, id object))block {
81 | if (!block) return;
82 | id object = [_memoryCache objectForKey:key];
83 | if (object) {
84 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
85 | block(key, object);
86 | });
87 | } else {
88 | [_diskCache objectForKey:key withBlock:^(NSString *key, id object) {
89 | if (object && ![_memoryCache objectForKey:key]) {
90 | [_memoryCache setObject:object forKey:key];
91 | }
92 | block(key, object);
93 | }];
94 | }
95 | }
96 |
97 | - (void)setObject:(id)object forKey:(NSString *)key {
98 | [_memoryCache setObject:object forKey:key];
99 | [_diskCache setObject:object forKey:key];
100 | }
101 |
102 | - (void)setObject:(id)object forKey:(NSString *)key withBlock:(void (^)(void))block {
103 | [_memoryCache setObject:object forKey:key];
104 | [_diskCache setObject:object forKey:key withBlock:block];
105 | }
106 |
107 | - (void)removeObjectForKey:(NSString *)key {
108 | [_memoryCache removeObjectForKey:key];
109 | [_diskCache removeObjectForKey:key];
110 | }
111 |
112 | - (void)removeObjectForKey:(NSString *)key withBlock:(void (^)(NSString *key))block {
113 | [_memoryCache removeObjectForKey:key];
114 | [_diskCache removeObjectForKey:key withBlock:block];
115 | }
116 |
117 | - (void)removeAllObjects {
118 | [_memoryCache removeAllObjects];
119 | [_diskCache removeAllObjects];
120 | }
121 |
122 | - (void)removeAllObjectsWithBlock:(void(^)(void))block {
123 | [_memoryCache removeAllObjects];
124 | [_diskCache removeAllObjectsWithBlock:block];
125 | }
126 |
127 | - (void)removeAllObjectsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress
128 | endBlock:(void(^)(BOOL error))end {
129 | [_memoryCache removeAllObjects];
130 | [_diskCache removeAllObjectsWithProgressBlock:progress endBlock:end];
131 |
132 | }
133 |
134 | - (NSString *)description {
135 | if (_name) return [NSString stringWithFormat:@"<%@: %p> (%@)", self.class, self, _name];
136 | else return [NSString stringWithFormat:@"<%@: %p>", self.class, self];
137 | }
138 |
139 | @end
140 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Cache/YYKVStorage.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYKVStorage.h
3 | // YYCache
4 | //
5 | // Created by ibireme on 15/4/22.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | /**
17 | YYKVStorageItem is used by `YYKVStorage` to store key-value pair and meta data.
18 | Typically, you should not use this class directly.
19 | */
20 | @interface YYKVStorageItem : NSObject
21 | @property (nonatomic, strong) NSString *key; ///< key
22 | @property (nonatomic, strong) NSData *value; ///< value
23 | @property (nullable, nonatomic, strong) NSString *filename; ///< filename (nil if inline)
24 | @property (nonatomic) int size; ///< value's size in bytes
25 | @property (nonatomic) int modTime; ///< modification unix timestamp
26 | @property (nonatomic) int accessTime; ///< last access unix timestamp
27 | @property (nullable, nonatomic, strong) NSData *extendedData; ///< extended data (nil if no extended data)
28 | @end
29 |
30 | /**
31 | Storage type, indicated where the `YYKVStorageItem.value` stored.
32 |
33 | @discussion Typically, write data to sqlite is faster than extern file, but
34 | reading performance is dependent on data size. In my test (on iPhone 6 64G),
35 | read data from extern file is faster than from sqlite when the data is larger
36 | than 20KB.
37 |
38 | * If you want to store large number of small datas (such as contacts cache),
39 | use YYKVStorageTypeSQLite to get better performance.
40 | * If you want to store large files (such as image cache),
41 | use YYKVStorageTypeFile to get better performance.
42 | * You can use YYKVStorageTypeMixed and choice your storage type for each item.
43 |
44 | See for more information.
45 | */
46 | typedef NS_ENUM(NSUInteger, YYKVStorageType) {
47 |
48 | /// The `value` is stored as a file in file system.
49 | YYKVStorageTypeFile = 0,
50 |
51 | /// The `value` is stored in sqlite with blob type.
52 | YYKVStorageTypeSQLite = 1,
53 |
54 | /// The `value` is stored in file system or sqlite based on your choice.
55 | YYKVStorageTypeMixed = 2,
56 | };
57 |
58 |
59 |
60 | /**
61 | YYKVStorage is a key-value storage based on sqlite and file system.
62 | Typically, you should not use this class directly.
63 |
64 | @discussion The designated initializer for YYKVStorage is `initWithPath:type:`.
65 | After initialized, a directory is created based on the `path` to hold key-value data.
66 | Once initialized you should not read or write this directory without the instance.
67 |
68 | You may compile the latest version of sqlite and ignore the libsqlite3.dylib in
69 | iOS system to get 2x~4x speed up.
70 |
71 | @warning The instance of this class is *NOT* thread safe, you need to make sure
72 | that there's only one thread to access the instance at the same time. If you really
73 | need to process large amounts of data in multi-thread, you should split the data
74 | to multiple KVStorage instance (sharding).
75 | */
76 | @interface YYKVStorage : NSObject
77 |
78 | #pragma mark - Attribute
79 | ///=============================================================================
80 | /// @name Attribute
81 | ///=============================================================================
82 |
83 | @property (nonatomic, readonly) NSString *path; ///< The path of this storage.
84 | @property (nonatomic, readonly) YYKVStorageType type; ///< The type of this storage.
85 | @property (nonatomic) BOOL errorLogsEnabled; ///< Set `YES` to enable error logs for debug.
86 |
87 | #pragma mark - Initializer
88 | ///=============================================================================
89 | /// @name Initializer
90 | ///=============================================================================
91 | - (instancetype)init UNAVAILABLE_ATTRIBUTE;
92 | + (instancetype)new UNAVAILABLE_ATTRIBUTE;
93 |
94 | /**
95 | The designated initializer.
96 |
97 | @param path Full path of a directory in which the storage will write data. If
98 | the directory is not exists, it will try to create one, otherwise it will
99 | read the data in this directory.
100 | @param type The storage type. After first initialized you should not change the
101 | type of the specified path.
102 | @return A new storage object, or nil if an error occurs.
103 | @warning Multiple instances with the same path will make the storage unstable.
104 | */
105 | - (nullable instancetype)initWithPath:(NSString *)path type:(YYKVStorageType)type NS_DESIGNATED_INITIALIZER;
106 |
107 |
108 | #pragma mark - Save Items
109 | ///=============================================================================
110 | /// @name Save Items
111 | ///=============================================================================
112 |
113 | /**
114 | Save an item or update the item with 'key' if it already exists.
115 |
116 | @discussion This method will save the item.key, item.value, item.filename and
117 | item.extendedData to disk or sqlite, other properties will be ignored. item.key
118 | and item.value should not be empty (nil or zero length).
119 |
120 | If the `type` is YYKVStorageTypeFile, then the item.filename should not be empty.
121 | If the `type` is YYKVStorageTypeSQLite, then the item.filename will be ignored.
122 | It the `type` is YYKVStorageTypeMixed, then the item.value will be saved to file
123 | system if the item.filename is not empty, otherwise it will be saved to sqlite.
124 |
125 | @param item An item.
126 | @return Whether succeed.
127 | */
128 | - (BOOL)saveItem:(YYKVStorageItem *)item;
129 |
130 | /**
131 | Save an item or update the item with 'key' if it already exists.
132 |
133 | @discussion This method will save the key-value pair to sqlite. If the `type` is
134 | YYKVStorageTypeFile, then this method will failed.
135 |
136 | @param key The key, should not be empty (nil or zero length).
137 | @param value The key, should not be empty (nil or zero length).
138 | @return Whether succeed.
139 | */
140 | - (BOOL)saveItemWithKey:(NSString *)key value:(NSData *)value;
141 |
142 | /**
143 | Save an item or update the item with 'key' if it already exists.
144 |
145 | @discussion
146 | If the `type` is YYKVStorageTypeFile, then the `filename` should not be empty.
147 | If the `type` is YYKVStorageTypeSQLite, then the `filename` will be ignored.
148 | It the `type` is YYKVStorageTypeMixed, then the `value` will be saved to file
149 | system if the `filename` is not empty, otherwise it will be saved to sqlite.
150 |
151 | @param key The key, should not be empty (nil or zero length).
152 | @param value The key, should not be empty (nil or zero length).
153 | @param filename The filename.
154 | @param extendedData The extended data for this item (pass nil to ignore it).
155 |
156 | @return Whether succeed.
157 | */
158 | - (BOOL)saveItemWithKey:(NSString *)key
159 | value:(NSData *)value
160 | filename:(nullable NSString *)filename
161 | extendedData:(nullable NSData *)extendedData;
162 |
163 | #pragma mark - Remove Items
164 | ///=============================================================================
165 | /// @name Remove Items
166 | ///=============================================================================
167 |
168 | /**
169 | Remove an item with 'key'.
170 |
171 | @param key The item's key.
172 | @return Whether succeed.
173 | */
174 | - (BOOL)removeItemForKey:(NSString *)key;
175 |
176 | /**
177 | Remove items with an array of keys.
178 |
179 | @param keys An array of specified keys.
180 |
181 | @return Whether succeed.
182 | */
183 | - (BOOL)removeItemForKeys:(NSArray *)keys;
184 |
185 | /**
186 | Remove all items which `value` is larger than a specified size.
187 |
188 | @param size The maximum size in bytes.
189 | @return Whether succeed.
190 | */
191 | - (BOOL)removeItemsLargerThanSize:(int)size;
192 |
193 | /**
194 | Remove all items which last access time is earlier than a specified timestamp.
195 |
196 | @param time The specified unix timestamp.
197 | @return Whether succeed.
198 | */
199 | - (BOOL)removeItemsEarlierThanTime:(int)time;
200 |
201 | /**
202 | Remove items to make the total size not larger than a specified size.
203 | The least recently used (LRU) items will be removed first.
204 |
205 | @param maxSize The specified size in bytes.
206 | @return Whether succeed.
207 | */
208 | - (BOOL)removeItemsToFitSize:(int)maxSize;
209 |
210 | /**
211 | Remove items to make the total count not larger than a specified count.
212 | The least recently used (LRU) items will be removed first.
213 |
214 | @param maxCount The specified item count.
215 | @return Whether succeed.
216 | */
217 | - (BOOL)removeItemsToFitCount:(int)maxCount;
218 |
219 | /**
220 | Remove all items in background queue.
221 |
222 | @discussion This method will remove the files and sqlite database to a trash
223 | folder, and then clear the folder in background queue. So this method is much
224 | faster than `removeAllItemsWithProgressBlock:endBlock:`.
225 |
226 | @return Whether succeed.
227 | */
228 | - (BOOL)removeAllItems;
229 |
230 | /**
231 | Remove all items.
232 |
233 | @warning You should not send message to this instance in these blocks.
234 | @param progress This block will be invoked during removing, pass nil to ignore.
235 | @param end This block will be invoked at the end, pass nil to ignore.
236 | */
237 | - (void)removeAllItemsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress
238 | endBlock:(nullable void(^)(BOOL error))end;
239 |
240 |
241 | #pragma mark - Get Items
242 | ///=============================================================================
243 | /// @name Get Items
244 | ///=============================================================================
245 |
246 | /**
247 | Get item with a specified key.
248 |
249 | @param key A specified key.
250 | @return Item for the key, or nil if not exists / error occurs.
251 | */
252 | - (nullable YYKVStorageItem *)getItemForKey:(NSString *)key;
253 |
254 | /**
255 | Get item information with a specified key.
256 | The `value` in this item will be ignored.
257 |
258 | @param key A specified key.
259 | @return Item information for the key, or nil if not exists / error occurs.
260 | */
261 | - (nullable YYKVStorageItem *)getItemInfoForKey:(NSString *)key;
262 |
263 | /**
264 | Get item value with a specified key.
265 |
266 | @param key A specified key.
267 | @return Item's value, or nil if not exists / error occurs.
268 | */
269 | - (nullable NSData *)getItemValueForKey:(NSString *)key;
270 |
271 | /**
272 | Get items with an array of keys.
273 |
274 | @param keys An array of specified keys.
275 | @return An array of `YYKVStorageItem`, or nil if not exists / error occurs.
276 | */
277 | - (nullable NSArray *)getItemForKeys:(NSArray *)keys;
278 |
279 | /**
280 | Get item infomartions with an array of keys.
281 | The `value` in items will be ignored.
282 |
283 | @param keys An array of specified keys.
284 | @return An array of `YYKVStorageItem`, or nil if not exists / error occurs.
285 | */
286 | - (nullable NSArray *)getItemInfoForKeys:(NSArray *)keys;
287 |
288 | /**
289 | Get items value with an array of keys.
290 |
291 | @param keys An array of specified keys.
292 | @return A dictionary which key is 'key' and value is 'value', or nil if not
293 | exists / error occurs.
294 | */
295 | - (nullable NSDictionary *)getItemValueForKeys:(NSArray *)keys;
296 |
297 | #pragma mark - Get Storage Status
298 | ///=============================================================================
299 | /// @name Get Storage Status
300 | ///=============================================================================
301 |
302 | /**
303 | Whether an item exists for a specified key.
304 |
305 | @param key A specified key.
306 |
307 | @return `YES` if there's an item exists for the key, `NO` if not exists or an error occurs.
308 | */
309 | - (BOOL)itemExistsForKey:(NSString *)key;
310 |
311 | /**
312 | Get total item count.
313 | @return Total item count, -1 when an error occurs.
314 | */
315 | - (int)getItemsCount;
316 |
317 | /**
318 | Get item value's total size in bytes.
319 | @return Total size in bytes, -1 when an error occurs.
320 | */
321 | - (int)getItemsSize;
322 |
323 | @end
324 |
325 | NS_ASSUME_NONNULL_END
326 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Cache/YYMemoryCache.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYMemoryCache.h
3 | // YYCache
4 | //
5 | // Created by ibireme on 15/2/7.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | /**
17 | YYMemoryCache is a fast in-memory cache that stores key-value pairs.
18 | In contrast to NSDictionary, keys are retained and not copied.
19 | The API and performance is similar to `NSCache`, all methods are thread-safe.
20 |
21 | YYMemoryCache objects differ from NSCache in a few ways:
22 |
23 | * It uses LRU (least-recently-used) to remove objects; NSCache's eviction method
24 | is non-deterministic.
25 | * It can be controlled by cost, count and age; NSCache's limits are imprecise.
26 | * It can be configured to automatically evict objects when receive memory
27 | warning or app enter background.
28 |
29 | The time of `Access Methods` in YYMemoryCache is typically in constant time (O(1)).
30 | */
31 | @interface YYMemoryCache : NSObject
32 |
33 | #pragma mark - Attribute
34 | ///=============================================================================
35 | /// @name Attribute
36 | ///=============================================================================
37 |
38 | /** The name of the cache. Default is nil. */
39 | @property (nullable, copy) NSString *name;
40 |
41 | /** The number of objects in the cache (read-only) */
42 | @property (readonly) NSUInteger totalCount;
43 |
44 | /** The total cost of objects in the cache (read-only). */
45 | @property (readonly) NSUInteger totalCost;
46 |
47 |
48 | #pragma mark - Limit
49 | ///=============================================================================
50 | /// @name Limit
51 | ///=============================================================================
52 |
53 | /**
54 | The maximum number of objects the cache should hold.
55 |
56 | @discussion The default value is NSUIntegerMax, which means no limit.
57 | This is not a strict limit—if the cache goes over the limit, some objects in the
58 | cache could be evicted later in backgound thread.
59 | */
60 | @property NSUInteger countLimit;
61 |
62 | /**
63 | The maximum total cost that the cache can hold before it starts evicting objects.
64 |
65 | @discussion The default value is NSUIntegerMax, which means no limit.
66 | This is not a strict limit—if the cache goes over the limit, some objects in the
67 | cache could be evicted later in backgound thread.
68 | */
69 | @property NSUInteger costLimit;
70 |
71 | /**
72 | The maximum expiry time of objects in cache.
73 |
74 | @discussion The default value is DBL_MAX, which means no limit.
75 | This is not a strict limit—if an object goes over the limit, the object could
76 | be evicted later in backgound thread.
77 | */
78 | @property NSTimeInterval ageLimit;
79 |
80 | /**
81 | The auto trim check time interval in seconds. Default is 5.0.
82 |
83 | @discussion The cache holds an internal timer to check whether the cache reaches
84 | its limits, and if the limit is reached, it begins to evict objects.
85 | */
86 | @property NSTimeInterval autoTrimInterval;
87 |
88 | /**
89 | If `YES`, the cache will remove all objects when the app receives a memory warning.
90 | The default value is `YES`.
91 | */
92 | @property BOOL shouldRemoveAllObjectsOnMemoryWarning;
93 |
94 | /**
95 | If `YES`, The cache will remove all objects when the app enter background.
96 | The default value is `YES`.
97 | */
98 | @property BOOL shouldRemoveAllObjectsWhenEnteringBackground;
99 |
100 | /**
101 | A block to be executed when the app receives a memory warning.
102 | The default value is nil.
103 | */
104 | @property (nullable, copy) void(^didReceiveMemoryWarningBlock)(YYMemoryCache *cache);
105 |
106 | /**
107 | A block to be executed when the app enter background.
108 | The default value is nil.
109 | */
110 | @property (nullable, copy) void(^didEnterBackgroundBlock)(YYMemoryCache *cache);
111 |
112 | /**
113 | If `YES`, the key-value pair will be released on main thread, otherwise on
114 | background thread. Default is NO.
115 |
116 | @discussion You may set this value to `YES` if the key-value object contains
117 | the instance which should be released in main thread (such as UIView/CALayer).
118 | */
119 | @property BOOL releaseOnMainThread;
120 |
121 | /**
122 | If `YES`, the key-value pair will be released asynchronously to avoid blocking
123 | the access methods, otherwise it will be released in the access method
124 | (such as removeObjectForKey:). Default is YES.
125 | */
126 | @property BOOL releaseAsynchronously;
127 |
128 |
129 | #pragma mark - Access Methods
130 | ///=============================================================================
131 | /// @name Access Methods
132 | ///=============================================================================
133 |
134 | /**
135 | Returns a Boolean value that indicates whether a given key is in cache.
136 |
137 | @param key An object identifying the value. If nil, just return `NO`.
138 | @return Whether the key is in cache.
139 | */
140 | - (BOOL)containsObjectForKey:(id)key;
141 |
142 | /**
143 | Returns the value associated with a given key.
144 |
145 | @param key An object identifying the value. If nil, just return nil.
146 | @return The value associated with key, or nil if no value is associated with key.
147 | */
148 | - (nullable id)objectForKey:(id)key;
149 |
150 | /**
151 | Sets the value of the specified key in the cache (0 cost).
152 |
153 | @param object The object to be stored in the cache. If nil, it calls `removeObjectForKey:`.
154 | @param key The key with which to associate the value. If nil, this method has no effect.
155 | @discussion Unlike an NSMutableDictionary object, a cache does not copy the key
156 | objects that are put into it.
157 | */
158 | - (void)setObject:(nullable id)object forKey:(id)key;
159 |
160 | /**
161 | Sets the value of the specified key in the cache, and associates the key-value
162 | pair with the specified cost.
163 |
164 | @param object The object to store in the cache. If nil, it calls `removeObjectForKey`.
165 | @param key The key with which to associate the value. If nil, this method has no effect.
166 | @param cost The cost with which to associate the key-value pair.
167 | @discussion Unlike an NSMutableDictionary object, a cache does not copy the key
168 | objects that are put into it.
169 | */
170 | - (void)setObject:(nullable id)object forKey:(id)key withCost:(NSUInteger)cost;
171 |
172 | /**
173 | Removes the value of the specified key in the cache.
174 |
175 | @param key The key identifying the value to be removed. If nil, this method has no effect.
176 | */
177 | - (void)removeObjectForKey:(id)key;
178 |
179 | /**
180 | Empties the cache immediately.
181 | */
182 | - (void)removeAllObjects;
183 |
184 |
185 | #pragma mark - Trim
186 | ///=============================================================================
187 | /// @name Trim
188 | ///=============================================================================
189 |
190 | /**
191 | Removes objects from the cache with LRU, until the `totalCount` is below or equal to
192 | the specified value.
193 | @param count The total count allowed to remain after the cache has been trimmed.
194 | */
195 | - (void)trimToCount:(NSUInteger)count;
196 |
197 | /**
198 | Removes objects from the cache with LRU, until the `totalCost` is or equal to
199 | the specified value.
200 | @param cost The total cost allowed to remain after the cache has been trimmed.
201 | */
202 | - (void)trimToCost:(NSUInteger)cost;
203 |
204 | /**
205 | Removes objects from the cache with LRU, until all expiry objects removed by the
206 | specified value.
207 | @param age The maximum age (in seconds) of objects.
208 | */
209 | - (void)trimToAge:(NSTimeInterval)age;
210 |
211 | @end
212 |
213 | NS_ASSUME_NONNULL_END
214 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Categories/CALayer+YYWebImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // CALayer+YYWebImage.h
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/23.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 | #import
14 |
15 | #if __has_include()
16 | #import
17 | #else
18 | #import "YYWebImageManager.h"
19 | #endif
20 |
21 | NS_ASSUME_NONNULL_BEGIN
22 |
23 | /**
24 | Web image methods for CALayer.
25 | It will set image to layer.contents.
26 | */
27 | @interface CALayer (YYWebImage)
28 |
29 | #pragma mark - image
30 |
31 | /**
32 | Current image URL.
33 |
34 | @discussion Set a new value to this property will cancel the previous request
35 | operation and create a new request operation to fetch image. Set nil to clear
36 | the image and image URL.
37 | */
38 | @property (nullable, nonatomic, strong) NSURL *yy_imageURL;
39 |
40 | /**
41 | Set the view's `image` with a specified URL.
42 |
43 | @param imageURL The image url (remote or local file path).
44 | @param placeholder The image to be set initially, until the image request finishes.
45 | */
46 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL placeholder:(nullable UIImage *)placeholder;
47 |
48 | /**
49 | Set the view's `image` with a specified URL.
50 |
51 | @param imageURL The image url (remote or local file path).
52 | @param options The options to use when request the image.
53 | */
54 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL options:(YYWebImageOptions)options;
55 |
56 | /**
57 | Set the view's `image` with a specified URL.
58 |
59 | @param imageURL The image url (remote or local file path).
60 | @param placeholder The image to be set initially, until the image request finishes.
61 | @param options The options to use when request the image.
62 | @param completion The block invoked (on main thread) when image request completed.
63 | */
64 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
65 | placeholder:(nullable UIImage *)placeholder
66 | options:(YYWebImageOptions)options
67 | completion:(nullable YYWebImageCompletionBlock)completion;
68 |
69 | /**
70 | Set the view's `image` with a specified URL.
71 |
72 | @param imageURL The image url (remote or local file path).
73 | @param placeholder The image to be set initially, until the image request finishes.
74 | @param options The options to use when request the image.
75 | @param progress The block invoked (on main thread) during image request.
76 | @param transform The block invoked (on background thread) to do additional image process.
77 | @param completion The block invoked (on main thread) when image request completed.
78 | */
79 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
80 | placeholder:(nullable UIImage *)placeholder
81 | options:(YYWebImageOptions)options
82 | progress:(nullable YYWebImageProgressBlock)progress
83 | transform:(nullable YYWebImageTransformBlock)transform
84 | completion:(nullable YYWebImageCompletionBlock)completion;
85 |
86 | /**
87 | Set the view's `image` with a specified URL.
88 |
89 | @param imageURL The image url (remote or local file path).
90 | @param placeholder he image to be set initially, until the image request finishes.
91 | @param options The options to use when request the image.
92 | @param manager The manager to create image request operation.
93 | @param progress The block invoked (on main thread) during image request.
94 | @param transform The block invoked (on background thread) to do additional image process.
95 | @param completion The block invoked (on main thread) when image request completed.
96 | */
97 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
98 | placeholder:(nullable UIImage *)placeholder
99 | options:(YYWebImageOptions)options
100 | manager:(nullable YYWebImageManager *)manager
101 | progress:(nullable YYWebImageProgressBlock)progress
102 | transform:(nullable YYWebImageTransformBlock)transform
103 | completion:(nullable YYWebImageCompletionBlock)completion;
104 |
105 | /**
106 | Cancel the current image request.
107 | */
108 | - (void)yy_cancelCurrentImageRequest;
109 |
110 | @end
111 |
112 | NS_ASSUME_NONNULL_END
113 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Categories/CALayer+YYWebImage.m:
--------------------------------------------------------------------------------
1 | //
2 | // CALayer+YYWebImage.m
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/23.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import "CALayer+YYWebImage.h"
13 | #import "YYWebImageOperation.h"
14 | #import "_YYWebImageSetter.h"
15 | #import
16 |
17 | // Dummy class for category
18 | @interface CALayer_YYWebImage : NSObject @end
19 | @implementation CALayer_YYWebImage @end
20 |
21 |
22 | static int _YYWebImageSetterKey;
23 |
24 | @implementation CALayer (YYWebImage)
25 |
26 | - (NSURL *)yy_imageURL {
27 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey);
28 | return setter.imageURL;
29 | }
30 |
31 | - (void)setYy_imageURL:(NSURL *)imageURL {
32 | [self yy_setImageWithURL:imageURL
33 | placeholder:nil
34 | options:kNilOptions
35 | manager:nil
36 | progress:nil
37 | transform:nil
38 | completion:nil];
39 | }
40 |
41 | - (void)yy_setImageWithURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder {
42 | [self yy_setImageWithURL:imageURL
43 | placeholder:placeholder
44 | options:kNilOptions
45 | manager:nil
46 | progress:nil
47 | transform:nil
48 | completion:nil];
49 | }
50 |
51 | - (void)yy_setImageWithURL:(NSURL *)imageURL options:(YYWebImageOptions)options {
52 | [self yy_setImageWithURL:imageURL
53 | placeholder:nil
54 | options:options
55 | manager:nil
56 | progress:nil
57 | transform:nil
58 | completion:nil];
59 | }
60 |
61 | - (void)yy_setImageWithURL:(NSURL *)imageURL
62 | placeholder:(UIImage *)placeholder
63 | options:(YYWebImageOptions)options
64 | completion:(YYWebImageCompletionBlock)completion {
65 | [self yy_setImageWithURL:imageURL
66 | placeholder:placeholder
67 | options:options
68 | manager:nil
69 | progress:nil
70 | transform:nil
71 | completion:completion];
72 | }
73 |
74 | - (void)yy_setImageWithURL:(NSURL *)imageURL
75 | placeholder:(UIImage *)placeholder
76 | options:(YYWebImageOptions)options
77 | progress:(YYWebImageProgressBlock)progress
78 | transform:(YYWebImageTransformBlock)transform
79 | completion:(YYWebImageCompletionBlock)completion {
80 | [self yy_setImageWithURL:imageURL
81 | placeholder:placeholder
82 | options:options
83 | manager:nil
84 | progress:progress
85 | transform:transform
86 | completion:completion];
87 | }
88 |
89 | - (void)yy_setImageWithURL:(NSURL *)imageURL
90 | placeholder:(UIImage *)placeholder
91 | options:(YYWebImageOptions)options
92 | manager:(YYWebImageManager *)manager
93 | progress:(YYWebImageProgressBlock)progress
94 | transform:(YYWebImageTransformBlock)transform
95 | completion:(YYWebImageCompletionBlock)completion {
96 | if ([imageURL isKindOfClass:[NSString class]]) imageURL = [NSURL URLWithString:(id)imageURL];
97 | manager = manager ? manager : [YYWebImageManager sharedManager];
98 |
99 |
100 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey);
101 | if (!setter) {
102 | setter = [_YYWebImageSetter new];
103 | objc_setAssociatedObject(self, &_YYWebImageSetterKey, setter, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
104 | }
105 | int32_t sentinel = [setter cancelWithNewURL:imageURL];
106 |
107 | _yy_dispatch_sync_on_main_queue(^{
108 | if ((options & YYWebImageOptionSetImageWithFadeAnimation) &&
109 | !(options & YYWebImageOptionAvoidSetImage)) {
110 | [self removeAnimationForKey:_YYWebImageFadeAnimationKey];
111 | }
112 |
113 | if (!imageURL) {
114 | if (!(options & YYWebImageOptionIgnorePlaceHolder)) {
115 | self.contents = (id)placeholder.CGImage;
116 | }
117 | return;
118 | }
119 |
120 | // get the image from memory as quickly as possible
121 | UIImage *imageFromMemory = nil;
122 | if (manager.cache &&
123 | !(options & YYWebImageOptionUseNSURLCache) &&
124 | !(options & YYWebImageOptionRefreshImageCache)) {
125 | imageFromMemory = [manager.cache getImageForKey:[manager cacheKeyForURL:imageURL] withType:YYImageCacheTypeMemory];
126 | }
127 | if (imageFromMemory) {
128 | if (!(options & YYWebImageOptionAvoidSetImage)) {
129 | self.contents = (id)imageFromMemory.CGImage;
130 | }
131 | if(completion) completion(imageFromMemory, imageURL, YYWebImageFromMemoryCacheFast, YYWebImageStageFinished, nil);
132 | return;
133 | }
134 |
135 | if (!(options & YYWebImageOptionIgnorePlaceHolder)) {
136 | self.contents = (id)placeholder.CGImage;
137 | }
138 |
139 | __weak typeof(self) _self = self;
140 | dispatch_async([_YYWebImageSetter setterQueue], ^{
141 | YYWebImageProgressBlock _progress = nil;
142 | if (progress) _progress = ^(NSInteger receivedSize, NSInteger expectedSize) {
143 | dispatch_async(dispatch_get_main_queue(), ^{
144 | progress(receivedSize, expectedSize);
145 | });
146 | };
147 |
148 | __block int32_t newSentinel = 0;
149 | __block __weak typeof(setter) weakSetter = nil;
150 | YYWebImageCompletionBlock _completion = ^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) {
151 | __strong typeof(_self) self = _self;
152 | BOOL setImage = (stage == YYWebImageStageFinished || stage == YYWebImageStageProgress) && image && !(options & YYWebImageOptionAvoidSetImage);
153 | BOOL showFade = (options & YYWebImageOptionSetImageWithFadeAnimation);
154 | dispatch_async(dispatch_get_main_queue(), ^{
155 | BOOL sentinelChanged = weakSetter && weakSetter.sentinel != newSentinel;
156 | if (setImage && self && !sentinelChanged) {
157 | if (showFade) {
158 | CATransition *transition = [CATransition animation];
159 | transition.duration = stage == YYWebImageStageFinished ? _YYWebImageFadeTime : _YYWebImageProgressiveFadeTime;
160 | transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
161 | transition.type = kCATransitionFade;
162 | [self addAnimation:transition forKey:_YYWebImageFadeAnimationKey];
163 | }
164 | self.contents = (id)image.CGImage;
165 | }
166 | if (completion) {
167 | if (sentinelChanged) {
168 | completion(nil, url, YYWebImageFromNone, YYWebImageStageCancelled, nil);
169 | } else {
170 | completion(image, url, from, stage, error);
171 | }
172 | }
173 | });
174 | };
175 |
176 | newSentinel = [setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
177 | weakSetter = setter;
178 | });
179 |
180 |
181 | });
182 | }
183 |
184 | - (void)yy_cancelCurrentImageRequest {
185 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey);
186 | if (setter) [setter cancel];
187 | }
188 |
189 | @end
190 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Categories/MKAnnotationView+YYWebImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // MKAnnotationView+YYWebImage.h
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/23.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 | #import
14 |
15 | #if __has_include()
16 | #import
17 | #else
18 | #import "YYWebImageManager.h"
19 | #endif
20 |
21 | NS_ASSUME_NONNULL_BEGIN
22 |
23 | /**
24 | Web image methods for MKAnnotationView.
25 | */
26 | @interface MKAnnotationView (YYWebImage)
27 |
28 | /**
29 | Current image URL.
30 |
31 | @discussion Set a new value to this property will cancel the previous request
32 | operation and create a new request operation to fetch image. Set nil to clear
33 | the image and image URL.
34 | */
35 | @property (nullable, nonatomic, strong) NSURL *yy_imageURL;
36 |
37 | /**
38 | Set the view's `image` with a specified URL.
39 |
40 | @param imageURL The image url (remote or local file path).
41 | @param placeholder The image to be set initially, until the image request finishes.
42 | */
43 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL placeholder:(nullable UIImage *)placeholder;
44 |
45 | /**
46 | Set the view's `image` with a specified URL.
47 |
48 | @param imageURL The image url (remote or local file path).
49 | @param options The options to use when request the image.
50 | */
51 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL options:(YYWebImageOptions)options;
52 |
53 | /**
54 | Set the view's `image` with a specified URL.
55 |
56 | @param imageURL The image url (remote or local file path).
57 | @param placeholder The image to be set initially, until the image request finishes.
58 | @param options The options to use when request the image.
59 | @param completion The block invoked (on main thread) when image request completed.
60 | */
61 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
62 | placeholder:(nullable UIImage *)placeholder
63 | options:(YYWebImageOptions)options
64 | completion:(nullable YYWebImageCompletionBlock)completion;
65 |
66 | /**
67 | Set the view's `image` with a specified URL.
68 |
69 | @param imageURL The image url (remote or local file path).
70 | @param placeholder The image to be set initially, until the image request finishes.
71 | @param options The options to use when request the image.
72 | @param progress The block invoked (on main thread) during image request.
73 | @param transform The block invoked (on background thread) to do additional image process.
74 | @param completion The block invoked (on main thread) when image request completed.
75 | */
76 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
77 | placeholder:(nullable UIImage *)placeholder
78 | options:(YYWebImageOptions)options
79 | progress:(nullable YYWebImageProgressBlock)progress
80 | transform:(nullable YYWebImageTransformBlock)transform
81 | completion:(nullable YYWebImageCompletionBlock)completion;
82 |
83 | /**
84 | Set the view's `image` with a specified URL.
85 |
86 | @param imageURL The image url (remote or local file path).
87 | @param placeholder he image to be set initially, until the image request finishes.
88 | @param options The options to use when request the image.
89 | @param manager The manager to create image request operation.
90 | @param progress The block invoked (on main thread) during image request.
91 | @param transform The block invoked (on background thread) to do additional image process.
92 | @param completion The block invoked (on main thread) when image request completed.
93 | */
94 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
95 | placeholder:(nullable UIImage *)placeholder
96 | options:(YYWebImageOptions)options
97 | manager:(nullable YYWebImageManager *)manager
98 | progress:(nullable YYWebImageProgressBlock)progress
99 | transform:(nullable YYWebImageTransformBlock)transform
100 | completion:(nullable YYWebImageCompletionBlock)completion;
101 |
102 | /**
103 | Cancel the current image request.
104 | */
105 | - (void)yy_cancelCurrentImageRequest;
106 |
107 | @end
108 |
109 | NS_ASSUME_NONNULL_END
110 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Categories/MKAnnotationView+YYWebImage.m:
--------------------------------------------------------------------------------
1 | //
2 | // MKAnnotationView+YYWebImage.m
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/23.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import "MKAnnotationView+YYWebImage.h"
13 | #import "YYWebImageOperation.h"
14 | #import "_YYWebImageSetter.h"
15 | #import
16 |
17 | // Dummy class for category
18 | @interface MKAnnotationView_YYWebImage : NSObject @end
19 | @implementation MKAnnotationView_YYWebImage @end
20 |
21 |
22 | static int _YYWebImageSetterKey;
23 |
24 | @implementation MKAnnotationView (YYWebImage)
25 |
26 | - (NSURL *)yy_imageURL {
27 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey);
28 | return setter.imageURL;
29 | }
30 |
31 | - (void)setYy_imageURL:(NSURL *)imageURL {
32 | [self yy_setImageWithURL:imageURL
33 | placeholder:nil
34 | options:kNilOptions
35 | manager:nil
36 | progress:nil
37 | transform:nil
38 | completion:nil];
39 | }
40 |
41 | - (void)yy_setImageWithURL:(NSURL *)imageURL placeholder:(UIImage *)placeholder {
42 | [self yy_setImageWithURL:imageURL
43 | placeholder:placeholder
44 | options:kNilOptions
45 | manager:nil
46 | progress:nil
47 | transform:nil
48 | completion:nil];
49 | }
50 |
51 | - (void)yy_setImageWithURL:(NSURL *)imageURL options:(YYWebImageOptions)options {
52 | [self yy_setImageWithURL:imageURL
53 | placeholder:nil
54 | options:options
55 | manager:nil
56 | progress:nil
57 | transform:nil
58 | completion:nil];
59 | }
60 |
61 | - (void)yy_setImageWithURL:(NSURL *)imageURL
62 | placeholder:(UIImage *)placeholder
63 | options:(YYWebImageOptions)options
64 | completion:(YYWebImageCompletionBlock)completion {
65 | [self yy_setImageWithURL:imageURL
66 | placeholder:placeholder
67 | options:options
68 | manager:nil
69 | progress:nil
70 | transform:nil
71 | completion:completion];
72 | }
73 |
74 | - (void)yy_setImageWithURL:(NSURL *)imageURL
75 | placeholder:(UIImage *)placeholder
76 | options:(YYWebImageOptions)options
77 | progress:(YYWebImageProgressBlock)progress
78 | transform:(YYWebImageTransformBlock)transform
79 | completion:(YYWebImageCompletionBlock)completion {
80 | [self yy_setImageWithURL:imageURL
81 | placeholder:placeholder
82 | options:options
83 | manager:nil
84 | progress:progress
85 | transform:transform
86 | completion:completion];
87 | }
88 |
89 | - (void)yy_setImageWithURL:(NSURL *)imageURL
90 | placeholder:(UIImage *)placeholder
91 | options:(YYWebImageOptions)options
92 | manager:(YYWebImageManager *)manager
93 | progress:(YYWebImageProgressBlock)progress
94 | transform:(YYWebImageTransformBlock)transform
95 | completion:(YYWebImageCompletionBlock)completion {
96 | if ([imageURL isKindOfClass:[NSString class]]) imageURL = [NSURL URLWithString:(id)imageURL];
97 | manager = manager ? manager : [YYWebImageManager sharedManager];
98 |
99 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey);
100 | if (!setter) {
101 | setter = [_YYWebImageSetter new];
102 | objc_setAssociatedObject(self, &_YYWebImageSetterKey, setter, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
103 | }
104 | int32_t sentinel = [setter cancelWithNewURL:imageURL];
105 |
106 | _yy_dispatch_sync_on_main_queue(^{
107 | if ((options & YYWebImageOptionSetImageWithFadeAnimation) &&
108 | !(options & YYWebImageOptionAvoidSetImage)) {
109 | if (!self.highlighted) {
110 | [self.layer removeAnimationForKey:_YYWebImageFadeAnimationKey];
111 | }
112 | }
113 | if (!imageURL) {
114 | if (!(options & YYWebImageOptionIgnorePlaceHolder)) {
115 | self.image = placeholder;
116 | }
117 | return;
118 | }
119 |
120 | // get the image from memory as quickly as possible
121 | UIImage *imageFromMemory = nil;
122 | if (manager.cache &&
123 | !(options & YYWebImageOptionUseNSURLCache) &&
124 | !(options & YYWebImageOptionRefreshImageCache)) {
125 | imageFromMemory = [manager.cache getImageForKey:[manager cacheKeyForURL:imageURL] withType:YYImageCacheTypeMemory];
126 | }
127 | if (imageFromMemory) {
128 | if (!(options & YYWebImageOptionAvoidSetImage)) {
129 | self.image = imageFromMemory;
130 | }
131 | if(completion) completion(imageFromMemory, imageURL, YYWebImageFromMemoryCacheFast, YYWebImageStageFinished, nil);
132 | return;
133 | }
134 |
135 | if (!(options & YYWebImageOptionIgnorePlaceHolder)) {
136 | self.image = placeholder;
137 | }
138 |
139 | __weak typeof(self) _self = self;
140 | dispatch_async([_YYWebImageSetter setterQueue], ^{
141 | YYWebImageProgressBlock _progress = nil;
142 | if (progress) _progress = ^(NSInteger receivedSize, NSInteger expectedSize) {
143 | dispatch_async(dispatch_get_main_queue(), ^{
144 | progress(receivedSize, expectedSize);
145 | });
146 | };
147 |
148 | __block int32_t newSentinel = 0;
149 | __block __weak typeof(setter) weakSetter = nil;
150 | YYWebImageCompletionBlock _completion = ^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) {
151 | __strong typeof(_self) self = _self;
152 | BOOL setImage = (stage == YYWebImageStageFinished || stage == YYWebImageStageProgress) && image && !(options & YYWebImageOptionAvoidSetImage);
153 | BOOL showFade = ((options & YYWebImageOptionSetImageWithFadeAnimation) && !self.highlighted);
154 | dispatch_async(dispatch_get_main_queue(), ^{
155 | BOOL sentinelChanged = weakSetter && weakSetter.sentinel != newSentinel;
156 | if (setImage && self && !sentinelChanged) {
157 | if (showFade) {
158 | CATransition *transition = [CATransition animation];
159 | transition.duration = stage == YYWebImageStageFinished ? _YYWebImageFadeTime : _YYWebImageProgressiveFadeTime;
160 | transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
161 | transition.type = kCATransitionFade;
162 | [self.layer addAnimation:transition forKey:_YYWebImageFadeAnimationKey];
163 | }
164 | self.image = image;
165 | }
166 | if (completion) {
167 | if (sentinelChanged) {
168 | completion(nil, url, YYWebImageFromNone, YYWebImageStageCancelled, nil);
169 | } else {
170 | completion(image, url, from, stage, error);
171 | }
172 | }
173 | });
174 | };
175 |
176 | newSentinel = [setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
177 | weakSetter = setter;
178 | });
179 | });
180 | }
181 |
182 | - (void)yy_cancelCurrentImageRequest {
183 | _YYWebImageSetter *setter = objc_getAssociatedObject(self, &_YYWebImageSetterKey);
184 | if (setter) [setter cancel];
185 | }
186 |
187 | @end
188 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Categories/UIButton+YYWebImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIButton+YYWebImage.h
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/23.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | #if __has_include()
15 | #import
16 | #else
17 | #import "YYWebImageManager.h"
18 | #endif
19 |
20 | NS_ASSUME_NONNULL_BEGIN
21 |
22 | /**
23 | Web image methods for UIButton.
24 | */
25 | @interface UIButton (YYWebImage)
26 |
27 | #pragma mark - image
28 |
29 | /**
30 | Current image URL for the specified state.
31 | @return The image URL, or nil.
32 | */
33 | - (nullable NSURL *)yy_imageURLForState:(UIControlState)state;
34 |
35 | /**
36 | Set the button's image with a specified URL for the specified state.
37 |
38 | @param imageURL The image url (remote or local file path).
39 | @param state The state that uses the specified image.
40 | @param placeholder The image to be set initially, until the image request finishes.
41 | */
42 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
43 | forState:(UIControlState)state
44 | placeholder:(nullable UIImage *)placeholder;
45 |
46 | /**
47 | Set the button's image with a specified URL for the specified state.
48 |
49 | @param imageURL The image url (remote or local file path).
50 | @param state The state that uses the specified image.
51 | @param options The options to use when request the image.
52 | */
53 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
54 | forState:(UIControlState)state
55 | options:(YYWebImageOptions)options;
56 |
57 | /**
58 | Set the button's image with a specified URL for the specified state.
59 |
60 | @param imageURL The image url (remote or local file path).
61 | @param state The state that uses the specified image.
62 | @param placeholder The image to be set initially, until the image request finishes.
63 | @param options The options to use when request the image.
64 | @param completion The block invoked (on main thread) when image request completed.
65 | */
66 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
67 | forState:(UIControlState)state
68 | placeholder:(nullable UIImage *)placeholder
69 | options:(YYWebImageOptions)options
70 | completion:(nullable YYWebImageCompletionBlock)completion;
71 |
72 | /**
73 | Set the button's image with a specified URL for the specified state.
74 |
75 | @param imageURL The image url (remote or local file path).
76 | @param state The state that uses the specified image.
77 | @param placeholder The image to be set initially, until the image request finishes.
78 | @param options The options to use when request the image.
79 | @param progress The block invoked (on main thread) during image request.
80 | @param transform The block invoked (on background thread) to do additional image process.
81 | @param completion The block invoked (on main thread) when image request completed.
82 | */
83 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
84 | forState:(UIControlState)state
85 | placeholder:(nullable UIImage *)placeholder
86 | options:(YYWebImageOptions)options
87 | progress:(nullable YYWebImageProgressBlock)progress
88 | transform:(nullable YYWebImageTransformBlock)transform
89 | completion:(nullable YYWebImageCompletionBlock)completion;
90 |
91 | /**
92 | Set the button's image with a specified URL for the specified state.
93 |
94 | @param imageURL The image url (remote or local file path).
95 | @param state The state that uses the specified image.
96 | @param placeholder The image to be set initially, until the image request finishes.
97 | @param options The options to use when request the image.
98 | @param manager The manager to create image request operation.
99 | @param progress The block invoked (on main thread) during image request.
100 | @param transform The block invoked (on background thread) to do additional image process.
101 | @param completion The block invoked (on main thread) when image request completed.
102 | */
103 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
104 | forState:(UIControlState)state
105 | placeholder:(nullable UIImage *)placeholder
106 | options:(YYWebImageOptions)options
107 | manager:(nullable YYWebImageManager *)manager
108 | progress:(nullable YYWebImageProgressBlock)progress
109 | transform:(nullable YYWebImageTransformBlock)transform
110 | completion:(nullable YYWebImageCompletionBlock)completion;
111 |
112 | /**
113 | Cancel the current image request for a specified state.
114 | @param state The state that uses the specified image.
115 | */
116 | - (void)yy_cancelImageRequestForState:(UIControlState)state;
117 |
118 |
119 |
120 | #pragma mark - background image
121 |
122 | /**
123 | Current backgroundImage URL for the specified state.
124 | @return The image URL, or nil.
125 | */
126 | - (nullable NSURL *)yy_backgroundImageURLForState:(UIControlState)state;
127 |
128 | /**
129 | Set the button's backgroundImage with a specified URL for the specified state.
130 |
131 | @param imageURL The image url (remote or local file path).
132 | @param state The state that uses the specified image.
133 | @param placeholder The image to be set initially, until the image request finishes.
134 | */
135 | - (void)yy_setBackgroundImageWithURL:(nullable NSURL *)imageURL
136 | forState:(UIControlState)state
137 | placeholder:(nullable UIImage *)placeholder;
138 |
139 | /**
140 | Set the button's backgroundImage with a specified URL for the specified state.
141 |
142 | @param imageURL The image url (remote or local file path).
143 | @param state The state that uses the specified image.
144 | @param options The options to use when request the image.
145 | */
146 | - (void)yy_setBackgroundImageWithURL:(nullable NSURL *)imageURL
147 | forState:(UIControlState)state
148 | options:(YYWebImageOptions)options;
149 |
150 | /**
151 | Set the button's backgroundImage with a specified URL for the specified state.
152 |
153 | @param imageURL The image url (remote or local file path).
154 | @param state The state that uses the specified image.
155 | @param placeholder The image to be set initially, until the image request finishes.
156 | @param options The options to use when request the image.
157 | @param completion The block invoked (on main thread) when image request completed.
158 | */
159 | - (void)yy_setBackgroundImageWithURL:(nullable NSURL *)imageURL
160 | forState:(UIControlState)state
161 | placeholder:(nullable UIImage *)placeholder
162 | options:(YYWebImageOptions)options
163 | completion:(nullable YYWebImageCompletionBlock)completion;
164 |
165 | /**
166 | Set the button's backgroundImage with a specified URL for the specified state.
167 |
168 | @param imageURL The image url (remote or local file path).
169 | @param state The state that uses the specified image.
170 | @param placeholder The image to be set initially, until the image request finishes.
171 | @param options The options to use when request the image.
172 | @param progress The block invoked (on main thread) during image request.
173 | @param transform The block invoked (on background thread) to do additional image process.
174 | @param completion The block invoked (on main thread) when image request completed.
175 | */
176 | - (void)yy_setBackgroundImageWithURL:(nullable NSURL *)imageURL
177 | forState:(UIControlState)state
178 | placeholder:(nullable UIImage *)placeholder
179 | options:(YYWebImageOptions)options
180 | progress:(nullable YYWebImageProgressBlock)progress
181 | transform:(nullable YYWebImageTransformBlock)transform
182 | completion:(nullable YYWebImageCompletionBlock)completion;
183 |
184 | /**
185 | Set the button's backgroundImage with a specified URL for the specified state.
186 |
187 | @param imageURL The image url (remote or local file path).
188 | @param state The state that uses the specified image.
189 | @param placeholder The image to be set initially, until the image request finishes.
190 | @param options The options to use when request the image.
191 | @param manager The manager to create image request operation.
192 | @param progress The block invoked (on main thread) during image request.
193 | @param transform The block invoked (on background thread) to do additional image process.
194 | @param completion The block invoked (on main thread) when image request completed.
195 | */
196 | - (void)yy_setBackgroundImageWithURL:(nullable NSURL *)imageURL
197 | forState:(UIControlState)state
198 | placeholder:(nullable UIImage *)placeholder
199 | options:(YYWebImageOptions)options
200 | manager:(nullable YYWebImageManager *)manager
201 | progress:(nullable YYWebImageProgressBlock)progress
202 | transform:(nullable YYWebImageTransformBlock)transform
203 | completion:(nullable YYWebImageCompletionBlock)completion;
204 |
205 | /**
206 | Cancel the current backgroundImage request for a specified state.
207 | @param state The state that uses the specified image.
208 | */
209 | - (void)yy_cancelBackgroundImageRequestForState:(UIControlState)state;
210 |
211 | @end
212 |
213 | NS_ASSUME_NONNULL_END
214 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Categories/UIImage+YYWebImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+YYWebImage.h
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 13/4/4.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | /**
17 | Provide some commen method for `UIImage`.
18 | Image process is based on CoreGraphic and vImage.
19 | */
20 | @interface UIImage (YYWebImage)
21 |
22 | #pragma mark - Create image
23 | ///=============================================================================
24 | /// @name Create image
25 | ///=============================================================================
26 |
27 | /**
28 | Create an animated image with GIF data. After created, you can access
29 | the images via property '.images'. If the data is not animated gif, this
30 | function is same as [UIImage imageWithData:data scale:scale];
31 |
32 | @discussion It has a better display performance, but costs more memory
33 | (width * height * frames Bytes). It only suited to display small
34 | gif such as animated emoticon. If you want to display large gif,
35 | see `YYImage`.
36 |
37 | @param data GIF data.
38 |
39 | @param scale The scale factor
40 |
41 | @return A new image created from GIF, or nil when an error occurs.
42 | */
43 | + (nullable UIImage *)yy_imageWithSmallGIFData:(NSData *)data scale:(CGFloat)scale;
44 |
45 | /**
46 | Create and return a 1x1 point size image with the given color.
47 |
48 | @param color The color.
49 | */
50 | + (nullable UIImage *)yy_imageWithColor:(UIColor *)color;
51 |
52 | /**
53 | Create and return a pure color image with the given color and size.
54 |
55 | @param color The color.
56 | @param size New image's type.
57 | */
58 | + (nullable UIImage *)yy_imageWithColor:(UIColor *)color size:(CGSize)size;
59 |
60 | /**
61 | Create and return an image with custom draw code.
62 |
63 | @param size The image size.
64 | @param drawBlock The draw block.
65 |
66 | @return The new image.
67 | */
68 | + (nullable UIImage *)yy_imageWithSize:(CGSize)size drawBlock:(void (^)(CGContextRef context))drawBlock;
69 |
70 | #pragma mark - Image Info
71 | ///=============================================================================
72 | /// @name Image Info
73 | ///=============================================================================
74 |
75 | /**
76 | Whether this image has alpha channel.
77 | */
78 | - (BOOL)yy_hasAlphaChannel;
79 |
80 |
81 | #pragma mark - Modify Image
82 | ///=============================================================================
83 | /// @name Modify Image
84 | ///=============================================================================
85 |
86 | /**
87 | Draws the entire image in the specified rectangle, content changed with
88 | the contentMode.
89 |
90 | @discussion This method draws the entire image in the current graphics context,
91 | respecting the image's orientation setting. In the default coordinate system,
92 | images are situated down and to the right of the origin of the specified
93 | rectangle. This method respects any transforms applied to the current graphics
94 | context, however.
95 |
96 | @param rect The rectangle in which to draw the image.
97 |
98 | @param contentMode Draw content mode
99 |
100 | @param clips A Boolean value that determines whether content are confined to the rect.
101 | */
102 | - (void)yy_drawInRect:(CGRect)rect withContentMode:(UIViewContentMode)contentMode clipsToBounds:(BOOL)clips;
103 |
104 | /**
105 | Returns a new image which is scaled from this image.
106 | The image will be stretched as needed.
107 |
108 | @param size The new size to be scaled, values should be positive.
109 |
110 | @return The new image with the given size.
111 | */
112 | - (nullable UIImage *)yy_imageByResizeToSize:(CGSize)size;
113 |
114 | /**
115 | Returns a new image which is scaled from this image.
116 | The image content will be changed with thencontentMode.
117 |
118 | @param size The new size to be scaled, values should be positive.
119 |
120 | @param contentMode The content mode for image content.
121 |
122 | @return The new image with the given size.
123 | */
124 | - (nullable UIImage *)yy_imageByResizeToSize:(CGSize)size contentMode:(UIViewContentMode)contentMode;
125 |
126 | /**
127 | Returns a new image which is cropped from this image.
128 |
129 | @param rect Image's inner rect.
130 |
131 | @return The new image, or nil if an error occurs.
132 | */
133 | - (nullable UIImage *)yy_imageByCropToRect:(CGRect)rect;
134 |
135 | /**
136 | Returns a new image which is edge inset from this image.
137 |
138 | @param insets Inset (positive) for each of the edges, values can be negative to 'outset'.
139 |
140 | @param color Extend edge's fill color, nil means clear color.
141 |
142 | @return The new image, or nil if an error occurs.
143 | */
144 | - (nullable UIImage *)yy_imageByInsetEdge:(UIEdgeInsets)insets withColor:(nullable UIColor *)color;
145 |
146 | /**
147 | Rounds a new image with a given corner size.
148 |
149 | @param radius The radius of each corner oval. Values larger than half the
150 | rectangle's width or height are clamped appropriately to half
151 | the width or height.
152 | */
153 | - (nullable UIImage *)yy_imageByRoundCornerRadius:(CGFloat)radius;
154 |
155 | /**
156 | Rounds a new image with a given corner size.
157 |
158 | @param radius The radius of each corner oval. Values larger than half the
159 | rectangle's width or height are clamped appropriately to
160 | half the width or height.
161 |
162 | @param borderWidth The inset border line width. Values larger than half the rectangle's
163 | width or height are clamped appropriately to half the width
164 | or height.
165 |
166 | @param borderColor The border stroke color. nil means clear color.
167 | */
168 | - (nullable UIImage *)yy_imageByRoundCornerRadius:(CGFloat)radius
169 | borderWidth:(CGFloat)borderWidth
170 | borderColor:(nullable UIColor *)borderColor;
171 |
172 | /**
173 | Rounds a new image with a given corner size.
174 |
175 | @param radius The radius of each corner oval. Values larger than half the
176 | rectangle's width or height are clamped appropriately to
177 | half the width or height.
178 |
179 | @param corners A bitmask value that identifies the corners that you want
180 | rounded. You can use this parameter to round only a subset
181 | of the corners of the rectangle.
182 |
183 | @param borderWidth The inset border line width. Values larger than half the rectangle's
184 | width or height are clamped appropriately to half the width
185 | or height.
186 |
187 | @param borderColor The border stroke color. nil means clear color.
188 |
189 | @param borderLineJoin The border line join.
190 | */
191 | - (nullable UIImage *)yy_imageByRoundCornerRadius:(CGFloat)radius
192 | corners:(UIRectCorner)corners
193 | borderWidth:(CGFloat)borderWidth
194 | borderColor:(nullable UIColor *)borderColor
195 | borderLineJoin:(CGLineJoin)borderLineJoin;
196 |
197 | /**
198 | Returns a new rotated image (relative to the center).
199 |
200 | @param radians Rotated radians in counterclockwise.⟲
201 |
202 | @param fitSize YES: new image's size is extend to fit all content.
203 | NO: image's size will not change, content may be clipped.
204 | */
205 | - (nullable UIImage *)yy_imageByRotate:(CGFloat)radians fitSize:(BOOL)fitSize;
206 |
207 | /**
208 | Returns a new image rotated counterclockwise by a quarter‑turn (90°). ⤺
209 | The width and height will be exchanged.
210 | */
211 | - (nullable UIImage *)yy_imageByRotateLeft90;
212 |
213 | /**
214 | Returns a new image rotated clockwise by a quarter‑turn (90°). ⤼
215 | The width and height will be exchanged.
216 | */
217 | - (nullable UIImage *)yy_imageByRotateRight90;
218 |
219 | /**
220 | Returns a new image rotated 180° . ↻
221 | */
222 | - (nullable UIImage *)yy_imageByRotate180;
223 |
224 | /**
225 | Returns a vertically flipped image. ⥯
226 | */
227 | - (nullable UIImage *)yy_imageByFlipVertical;
228 |
229 | /**
230 | Returns a horizontally flipped image. ⇋
231 | */
232 | - (nullable UIImage *)yy_imageByFlipHorizontal;
233 |
234 |
235 | #pragma mark - Image Effect
236 | ///=============================================================================
237 | /// @name Image Effect
238 | ///=============================================================================
239 |
240 | /**
241 | Tint the image in alpha channel with the given color.
242 |
243 | @param color The color.
244 | */
245 | - (nullable UIImage *)yy_imageByTintColor:(UIColor *)color;
246 |
247 | /**
248 | Returns a grayscaled image.
249 | */
250 | - (nullable UIImage *)yy_imageByGrayscale;
251 |
252 | /**
253 | Applies a blur effect to this image. Suitable for blur any content.
254 | */
255 | - (nullable UIImage *)yy_imageByBlurSoft;
256 |
257 | /**
258 | Applies a blur effect to this image. Suitable for blur any content except pure white.
259 | (same as iOS Control Panel)
260 | */
261 | - (nullable UIImage *)yy_imageByBlurLight;
262 |
263 | /**
264 | Applies a blur effect to this image. Suitable for displaying black text.
265 | (same as iOS Navigation Bar White)
266 | */
267 | - (nullable UIImage *)yy_imageByBlurExtraLight;
268 |
269 | /**
270 | Applies a blur effect to this image. Suitable for displaying white text.
271 | (same as iOS Notification Center)
272 | */
273 | - (nullable UIImage *)yy_imageByBlurDark;
274 |
275 | /**
276 | Applies a blur and tint color to this image.
277 |
278 | @param tintColor The tint color.
279 | */
280 | - (nullable UIImage *)yy_imageByBlurWithTint:(UIColor *)tintColor;
281 |
282 | /**
283 | Applies a blur, tint color, and saturation adjustment to this image,
284 | optionally within the area specified by @a maskImage.
285 |
286 | @param blurRadius The radius of the blur in points, 0 means no blur effect.
287 |
288 | @param tintColor An optional UIColor object that is uniformly blended with
289 | the result of the blur and saturation operations. The
290 | alpha channel of this color determines how strong the
291 | tint is. nil means no tint.
292 |
293 | @param tintBlendMode The @a tintColor blend mode. Default is kCGBlendModeNormal (0).
294 |
295 | @param saturation A value of 1.0 produces no change in the resulting image.
296 | Values less than 1.0 will desaturation the resulting image
297 | while values greater than 1.0 will have the opposite effect.
298 | 0 means gray scale.
299 |
300 | @param maskImage If specified, @a inputImage is only modified in the area(s)
301 | defined by this mask. This must be an image mask or it
302 | must meet the requirements of the mask parameter of
303 | CGContextClipToMask.
304 |
305 | @return image with effect, or nil if an error occurs (e.g. no
306 | enough memory).
307 | */
308 | - (nullable UIImage *)yy_imageByBlurRadius:(CGFloat)blurRadius
309 | tintColor:(nullable UIColor *)tintColor
310 | tintMode:(CGBlendMode)tintBlendMode
311 | saturation:(CGFloat)saturation
312 | maskImage:(nullable UIImage *)maskImage;
313 |
314 | @end
315 |
316 | NS_ASSUME_NONNULL_END
317 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Categories/UIImageView+YYWebImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImageView+YYWebImage.h
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/23.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | #if __has_include()
15 | #import
16 | #else
17 | #import "YYWebImageManager.h"
18 | #endif
19 |
20 | NS_ASSUME_NONNULL_BEGIN
21 |
22 | /**
23 | Web image methods for UIImageView.
24 | */
25 | @interface UIImageView (YYWebImage)
26 |
27 | #pragma mark - image
28 |
29 | /**
30 | Current image URL.
31 |
32 | @discussion Set a new value to this property will cancel the previous request
33 | operation and create a new request operation to fetch image. Set nil to clear
34 | the image and image URL.
35 | */
36 | @property (nullable, nonatomic, strong) NSURL *yy_imageURL;
37 |
38 | /**
39 | Set the view's `image` with a specified URL.
40 |
41 | @param imageURL The image url (remote or local file path).
42 | @param placeholder The image to be set initially, until the image request finishes.
43 | */
44 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL placeholder:(nullable UIImage *)placeholder;
45 |
46 | /**
47 | Set the view's `image` with a specified URL.
48 |
49 | @param imageURL The image url (remote or local file path).
50 | @param options The options to use when request the image.
51 | */
52 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL options:(YYWebImageOptions)options;
53 |
54 | /**
55 | Set the view's `image` with a specified URL.
56 |
57 | @param imageURL The image url (remote or local file path).
58 | @param placeholder The image to be set initially, until the image request finishes.
59 | @param options The options to use when request the image.
60 | @param completion The block invoked (on main thread) when image request completed.
61 | */
62 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
63 | placeholder:(nullable UIImage *)placeholder
64 | options:(YYWebImageOptions)options
65 | completion:(nullable YYWebImageCompletionBlock)completion;
66 |
67 | /**
68 | Set the view's `image` with a specified URL.
69 |
70 | @param imageURL The image url (remote or local file path).
71 | @param placeholder The image to be set initially, until the image request finishes.
72 | @param options The options to use when request the image.
73 | @param progress The block invoked (on main thread) during image request.
74 | @param transform The block invoked (on background thread) to do additional image process.
75 | @param completion The block invoked (on main thread) when image request completed.
76 | */
77 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
78 | placeholder:(nullable UIImage *)placeholder
79 | options:(YYWebImageOptions)options
80 | progress:(nullable YYWebImageProgressBlock)progress
81 | transform:(nullable YYWebImageTransformBlock)transform
82 | completion:(nullable YYWebImageCompletionBlock)completion;
83 |
84 | /**
85 | Set the view's `image` with a specified URL.
86 |
87 | @param imageURL The image url (remote or local file path).
88 | @param placeholder he image to be set initially, until the image request finishes.
89 | @param options The options to use when request the image.
90 | @param manager The manager to create image request operation.
91 | @param progress The block invoked (on main thread) during image request.
92 | @param transform The block invoked (on background thread) to do additional image process.
93 | @param completion The block invoked (on main thread) when image request completed.
94 | */
95 | - (void)yy_setImageWithURL:(nullable NSURL *)imageURL
96 | placeholder:(nullable UIImage *)placeholder
97 | options:(YYWebImageOptions)options
98 | manager:(nullable YYWebImageManager *)manager
99 | progress:(nullable YYWebImageProgressBlock)progress
100 | transform:(nullable YYWebImageTransformBlock)transform
101 | completion:(nullable YYWebImageCompletionBlock)completion;
102 |
103 | /**
104 | Cancel the current image request.
105 | */
106 | - (void)yy_cancelCurrentImageRequest;
107 |
108 |
109 |
110 | #pragma mark - highlight image
111 |
112 | /**
113 | Current highlighted image URL.
114 |
115 | @discussion Set a new value to this property will cancel the previous request
116 | operation and create a new request operation to fetch image. Set nil to clear
117 | the highlighted image and image URL.
118 | */
119 | @property (nullable, nonatomic, strong) NSURL *yy_highlightedImageURL;
120 |
121 | /**
122 | Set the view's `highlightedImage` with a specified URL.
123 |
124 | @param imageURL The image url (remote or local file path).
125 | @param placeholder The image to be set initially, until the image request finishes.
126 | */
127 | - (void)yy_setHighlightedImageWithURL:(nullable NSURL *)imageURL placeholder:(nullable UIImage *)placeholder;
128 |
129 | /**
130 | Set the view's `highlightedImage` with a specified URL.
131 |
132 | @param imageURL The image url (remote or local file path).
133 | @param options The options to use when request the image.
134 | */
135 | - (void)yy_setHighlightedImageWithURL:(nullable NSURL *)imageURL options:(YYWebImageOptions)options;
136 |
137 | /**
138 | Set the view's `highlightedImage` with a specified URL.
139 |
140 | @param imageURL The image url (remote or local file path).
141 | @param placeholder The image to be set initially, until the image request finishes.
142 | @param options The options to use when request the image.
143 | @param completion The block invoked (on main thread) when image request completed.
144 | */
145 | - (void)yy_setHighlightedImageWithURL:(nullable NSURL *)imageURL
146 | placeholder:(nullable UIImage *)placeholder
147 | options:(YYWebImageOptions)options
148 | completion:(nullable YYWebImageCompletionBlock)completion;
149 |
150 | /**
151 | Set the view's `highlightedImage` with a specified URL.
152 |
153 | @param imageURL The image url (remote or local file path).
154 | @param placeholder The image to be set initially, until the image request finishes.
155 | @param options The options to use when request the image.
156 | @param progress The block invoked (on main thread) during image request.
157 | @param transform The block invoked (on background thread) to do additional image process.
158 | @param completion The block invoked (on main thread) when image request completed.
159 | */
160 | - (void)yy_setHighlightedImageWithURL:(nullable NSURL *)imageURL
161 | placeholder:(nullable UIImage *)placeholder
162 | options:(YYWebImageOptions)options
163 | progress:(nullable YYWebImageProgressBlock)progress
164 | transform:(nullable YYWebImageTransformBlock)transform
165 | completion:(nullable YYWebImageCompletionBlock)completion;
166 |
167 | /**
168 | Set the view's `highlightedImage` with a specified URL.
169 |
170 | @param imageURL The image url (remote or local file path).
171 | @param placeholder The image to be set initially, until the image request finishes.
172 | @param options The options to use when request the image.
173 | @param manager The manager to create image request operation.
174 | @param progress The block invoked (on main thread) during image request.
175 | @param transform The block invoked (on background thread) to do additional image process.
176 | @param completion The block invoked (on main thread) when image request completed.
177 | */
178 | - (void)yy_setHighlightedImageWithURL:(nullable NSURL *)imageURL
179 | placeholder:(nullable UIImage *)placeholder
180 | options:(YYWebImageOptions)options
181 | manager:(nullable YYWebImageManager *)manager
182 | progress:(nullable YYWebImageProgressBlock)progress
183 | transform:(nullable YYWebImageTransformBlock)transform
184 | completion:(nullable YYWebImageCompletionBlock)completion;
185 |
186 | /**
187 | Cancel the current highlighed image request.
188 | */
189 | - (void)yy_cancelCurrentHighlightedImageRequest;
190 |
191 | @end
192 |
193 | NS_ASSUME_NONNULL_END
194 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Categories/_YYWebImageSetter.h:
--------------------------------------------------------------------------------
1 | //
2 | // _YYWebImageSetter.h
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/7/15.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 | #import
12 | #import
13 |
14 | #if __has_include()
15 | #import
16 | #else
17 | #import "YYWebImageManager.h"
18 | #endif
19 |
20 | NS_ASSUME_NONNULL_BEGIN
21 |
22 | /**
23 | Submits a block for execution on a main queue and waits until the block completes.
24 | */
25 | static inline void _yy_dispatch_sync_on_main_queue(void (^block)()) {
26 | if (pthread_main_np()) {
27 | block();
28 | } else {
29 | dispatch_sync(dispatch_get_main_queue(), block);
30 | }
31 | }
32 |
33 | extern NSString *const _YYWebImageFadeAnimationKey;
34 | extern const NSTimeInterval _YYWebImageFadeTime;
35 | extern const NSTimeInterval _YYWebImageProgressiveFadeTime;
36 |
37 | /**
38 | Private class used by web image categories.
39 | Typically, you should not use this class directly.
40 | */
41 | @interface _YYWebImageSetter : NSObject
42 | /// Current image url.
43 | @property (nullable, nonatomic, readonly) NSURL *imageURL;
44 | /// Current sentinel.
45 | @property (nonatomic, readonly) int32_t sentinel;
46 |
47 | /// Create new operation for web image and return a sentinel value.
48 | - (int32_t)setOperationWithSentinel:(int32_t)sentinel
49 | url:(nullable NSURL *)imageURL
50 | options:(YYWebImageOptions)options
51 | manager:(YYWebImageManager *)manager
52 | progress:(nullable YYWebImageProgressBlock)progress
53 | transform:(nullable YYWebImageTransformBlock)transform
54 | completion:(nullable YYWebImageCompletionBlock)completion;
55 |
56 | /// Cancel and return a sentinel value. The imageURL will be set to nil.
57 | - (int32_t)cancel;
58 |
59 | /// Cancel and return a sentinel value. The imageURL will be set to new value.
60 | - (int32_t)cancelWithNewURL:(nullable NSURL *)imageURL;
61 |
62 | /// A queue to set operation.
63 | + (dispatch_queue_t)setterQueue;
64 |
65 | @end
66 |
67 | NS_ASSUME_NONNULL_END
68 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Categories/_YYWebImageSetter.m:
--------------------------------------------------------------------------------
1 | //
2 | // _YYWebImageSetter.m
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/7/15.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import "_YYWebImageSetter.h"
13 | #import "YYWebImageOperation.h"
14 | #import
15 |
16 | NSString *const _YYWebImageFadeAnimationKey = @"YYWebImageFade";
17 | const NSTimeInterval _YYWebImageFadeTime = 0.2;
18 | const NSTimeInterval _YYWebImageProgressiveFadeTime = 0.4;
19 |
20 |
21 | @implementation _YYWebImageSetter {
22 | dispatch_semaphore_t _lock;
23 | NSURL *_imageURL;
24 | NSOperation *_operation;
25 | int32_t _sentinel;
26 | }
27 |
28 | - (instancetype)init {
29 | self = [super init];
30 | _lock = dispatch_semaphore_create(1);
31 | return self;
32 | }
33 |
34 | - (NSURL *)imageURL {
35 | dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
36 | NSURL *imageURL = _imageURL;
37 | dispatch_semaphore_signal(_lock);
38 | return imageURL;
39 | }
40 |
41 | - (void)dealloc {
42 | OSAtomicIncrement32(&_sentinel);
43 | [_operation cancel];
44 | }
45 |
46 | - (int32_t)setOperationWithSentinel:(int32_t)sentinel
47 | url:(NSURL *)imageURL
48 | options:(YYWebImageOptions)options
49 | manager:(YYWebImageManager *)manager
50 | progress:(YYWebImageProgressBlock)progress
51 | transform:(YYWebImageTransformBlock)transform
52 | completion:(YYWebImageCompletionBlock)completion {
53 | if (sentinel != _sentinel) {
54 | if (completion) completion(nil, imageURL, YYWebImageFromNone, YYWebImageStageCancelled, nil);
55 | return _sentinel;
56 | }
57 |
58 | NSOperation *operation = [manager requestImageWithURL:imageURL options:options progress:progress transform:transform completion:completion];
59 | if (!operation && completion) {
60 | NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : @"YYWebImageOperation create failed." };
61 | completion(nil, imageURL, YYWebImageFromNone, YYWebImageStageFinished, [NSError errorWithDomain:@"com.ibireme.webimage" code:-1 userInfo:userInfo]);
62 | }
63 |
64 | dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
65 | if (sentinel == _sentinel) {
66 | if (_operation) [_operation cancel];
67 | _operation = operation;
68 | sentinel = OSAtomicIncrement32(&_sentinel);
69 | } else {
70 | [operation cancel];
71 | }
72 | dispatch_semaphore_signal(_lock);
73 | return sentinel;
74 | }
75 |
76 | - (int32_t)cancel {
77 | return [self cancelWithNewURL:nil];
78 | }
79 |
80 | - (int32_t)cancelWithNewURL:(NSURL *)imageURL {
81 | int32_t sentinel;
82 | dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
83 | if (_operation) {
84 | [_operation cancel];
85 | _operation = nil;
86 | }
87 | _imageURL = imageURL;
88 | sentinel = OSAtomicIncrement32(&_sentinel);
89 | dispatch_semaphore_signal(_lock);
90 | return sentinel;
91 | }
92 |
93 | + (dispatch_queue_t)setterQueue {
94 | static dispatch_queue_t queue;
95 | static dispatch_once_t onceToken;
96 | dispatch_once(&onceToken, ^{
97 | queue = dispatch_queue_create("com.ibireme.webimage.setter", DISPATCH_QUEUE_SERIAL);
98 | dispatch_set_target_queue(queue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
99 | });
100 | return queue;
101 | }
102 |
103 | @end
104 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Image/YYAnimatedImageView.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYAnimatedImageView.h
3 | // YYImage
4 | //
5 | // Created by ibireme on 14/10/19.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | /**
17 | An image view for displaying animated image.
18 |
19 | @discussion It is a fully compatible `UIImageView` subclass.
20 | If the `image` or `highlightedImage` property adopt to the `YYAnimatedImage` protocol,
21 | then it can be used to play the multi-frame animation. The animation can also be
22 | controlled with the UIImageView methods `-startAnimating`, `-stopAnimating` and `-isAnimating`.
23 |
24 | This view request the frame data just in time. When the device has enough free memory,
25 | this view may cache some or all future frames in an inner buffer for lower CPU cost.
26 | Buffer size is dynamically adjusted based on the current state of the device memory.
27 |
28 | Sample Code:
29 |
30 | // ani@3x.gif
31 | YYImage *image = [YYImage imageNamed:@"ani"];
32 | YYAnimatedImageView *imageView = [YYAnimatedImageView alloc] initWithImage:image];
33 | [view addSubView:imageView];
34 | */
35 | @interface YYAnimatedImageView : UIImageView
36 |
37 | /**
38 | If the image has more than one frame, set this value to `YES` will automatically
39 | play/stop the animation when the view become visible/invisible.
40 |
41 | The default value is `YES`.
42 | */
43 | @property (nonatomic) BOOL autoPlayAnimatedImage;
44 |
45 | /**
46 | Index of the currently displayed frame (index from 0).
47 |
48 | Set a new value to this property will cause to display the new frame immediately.
49 | If the new value is invalid, this method has no effect.
50 |
51 | You can add an observer to this property to observe the playing status.
52 | */
53 | @property (nonatomic) NSUInteger currentAnimatedImageIndex;
54 |
55 | /**
56 | Whether the image view is playing animation currently.
57 |
58 | You can add an observer to this property to observe the playing status.
59 | */
60 | @property (nonatomic, readonly) BOOL currentIsPlayingAnimation;
61 |
62 | /**
63 | The animation timer's runloop mode, default is `NSRunLoopCommonModes`.
64 |
65 | Set this property to `NSDefaultRunLoopMode` will make the animation pause during
66 | UIScrollView scrolling.
67 | */
68 | @property (nonatomic, copy) NSString *runloopMode;
69 |
70 | /**
71 | The max size (in bytes) for inner frame buffer size, default is 0 (dynamically).
72 |
73 | When the device has enough free memory, this view will request and decode some or
74 | all future frame image into an inner buffer. If this property's value is 0, then
75 | the max buffer size will be dynamically adjusted based on the current state of
76 | the device free memory. Otherwise, the buffer size will be limited by this value.
77 |
78 | When receive memory warning or app enter background, the buffer will be released
79 | immediately, and may grow back at the right time.
80 | */
81 | @property (nonatomic) NSUInteger maxBufferSize;
82 |
83 | @end
84 |
85 |
86 |
87 | /**
88 | The YYAnimatedImage protocol declares the required methods for animated image
89 | display with YYAnimatedImageView.
90 |
91 | Subclass a UIImage and implement this protocol, so that instances of that class
92 | can be set to YYAnimatedImageView.image or YYAnimatedImageView.highlightedImage
93 | to display animation.
94 |
95 | See `YYImage` and `YYFrameImage` for example.
96 | */
97 | @protocol YYAnimatedImage
98 | @required
99 | /// Total animated frame count.
100 | /// It the frame count is less than 1, then the methods below will be ignored.
101 | - (NSUInteger)animatedImageFrameCount;
102 |
103 | /// Animation loop count, 0 means infinite looping.
104 | - (NSUInteger)animatedImageLoopCount;
105 |
106 | /// Bytes per frame (in memory). It may used to optimize memory buffer size.
107 | - (NSUInteger)animatedImageBytesPerFrame;
108 |
109 | /// Returns the frame image from a specified index.
110 | /// This method may be called on background thread.
111 | /// @param index Frame index (zero based).
112 | - (nullable UIImage *)animatedImageFrameAtIndex:(NSUInteger)index;
113 |
114 | /// Returns the frames's duration from a specified index.
115 | /// @param index Frame index (zero based).
116 | - (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index;
117 |
118 | @optional
119 | /// A rectangle in image coordinates defining the subrectangle of the image that
120 | /// will be displayed. The rectangle should not outside the image's bounds.
121 | /// It may used to display sprite animation with a single image (sprite sheet).
122 | - (CGRect)animatedImageContentsRectAtIndex:(NSUInteger)index;
123 | @end
124 |
125 | NS_ASSUME_NONNULL_END
126 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Image/YYFrameImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYFrameImage.h
3 | // YYImage
4 | //
5 | // Created by ibireme on 14/12/9.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | #if __has_include()
15 | #import
16 | #elif __has_include()
17 | #import
18 | #else
19 | #import "YYAnimatedImageView.h"
20 | #endif
21 |
22 | NS_ASSUME_NONNULL_BEGIN
23 |
24 | /**
25 | An image to display frame-based animation.
26 |
27 | @discussion It is a fully compatible `UIImage` subclass.
28 | It only support system image format such as png and jpeg.
29 | The animation can be played by YYAnimatedImageView.
30 |
31 | Sample Code:
32 |
33 | NSArray *paths = @[@"/ani/frame1.png", @"/ani/frame2.png", @"/ani/frame3.png"];
34 | NSArray *times = @[@0.1, @0.2, @0.1];
35 | YYFrameImage *image = [YYFrameImage alloc] initWithImagePaths:paths frameDurations:times repeats:YES];
36 | YYAnimatedImageView *imageView = [YYAnimatedImageView alloc] initWithImage:image];
37 | [view addSubView:imageView];
38 | */
39 | @interface YYFrameImage : UIImage
40 |
41 | /**
42 | Create a frame animated image from files.
43 |
44 | @param paths An array of NSString objects, contains the full or
45 | partial path to each image file.
46 | e.g. @[@"/ani/1.png",@"/ani/2.png",@"/ani/3.png"]
47 |
48 | @param oneFrameDuration The duration (in seconds) per frame.
49 |
50 | @param loopCount The animation loop count, 0 means infinite.
51 |
52 | @return An initialized YYFrameImage object, or nil when an error occurs.
53 | */
54 | - (nullable instancetype)initWithImagePaths:(NSArray *)paths
55 | oneFrameDuration:(NSTimeInterval)oneFrameDuration
56 | loopCount:(NSUInteger)loopCount;
57 |
58 | /**
59 | Create a frame animated image from files.
60 |
61 | @param paths An array of NSString objects, contains the full or
62 | partial path to each image file.
63 | e.g. @[@"/ani/frame1.png",@"/ani/frame2.png",@"/ani/frame3.png"]
64 |
65 | @param frameDurations An array of NSNumber objects, contains the duration (in seconds) per frame.
66 | e.g. @[@0.1, @0.2, @0.3];
67 |
68 | @param loopCount The animation loop count, 0 means infinite.
69 |
70 | @return An initialized YYFrameImage object, or nil when an error occurs.
71 | */
72 | - (nullable instancetype)initWithImagePaths:(NSArray *)paths
73 | frameDurations:(NSArray *)frameDurations
74 | loopCount:(NSUInteger)loopCount;
75 |
76 | /**
77 | Create a frame animated image from an array of data.
78 |
79 | @param dataArray An array of NSData objects.
80 |
81 | @param oneFrameDuration The duration (in seconds) per frame.
82 |
83 | @param loopCount The animation loop count, 0 means infinite.
84 |
85 | @return An initialized YYFrameImage object, or nil when an error occurs.
86 | */
87 | - (nullable instancetype)initWithImageDataArray:(NSArray *)dataArray
88 | oneFrameDuration:(NSTimeInterval)oneFrameDuration
89 | loopCount:(NSUInteger)loopCount;
90 |
91 | /**
92 | Create a frame animated image from an array of data.
93 |
94 | @param dataArray An array of NSData objects.
95 |
96 | @param frameDurations An array of NSNumber objects, contains the duration (in seconds) per frame.
97 | e.g. @[@0.1, @0.2, @0.3];
98 |
99 | @param loopCount The animation loop count, 0 means infinite.
100 |
101 | @return An initialized YYFrameImage object, or nil when an error occurs.
102 | */
103 | - (nullable instancetype)initWithImageDataArray:(NSArray *)dataArray
104 | frameDurations:(NSArray *)frameDurations
105 | loopCount:(NSUInteger)loopCount;
106 |
107 | @end
108 |
109 | NS_ASSUME_NONNULL_END
110 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Image/YYFrameImage.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYFrameImage.m
3 | // YYImage
4 | //
5 | // Created by ibireme on 14/12/9.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import "YYFrameImage.h"
13 | #import "YYImageCoder.h"
14 |
15 |
16 | /**
17 | Return the path scale.
18 |
19 | e.g.
20 |
21 | Path | Scale |
22 | "icon.png" | 1 |
23 | "icon@2x.png" | 2 |
24 | "icon@2.5x.png" | 2.5 |
25 | "icon@2x" | 1 |
26 | "icon@2x..png" | 1 |
27 | "icon@2x.png/" | 1 |
28 |
29 | */
30 | static CGFloat _NSStringPathScale(NSString *string) {
31 | if (string.length == 0 || [string hasSuffix:@"/"]) return 1;
32 | NSString *name = string.stringByDeletingPathExtension;
33 | __block CGFloat scale = 1;
34 |
35 | NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:@"@[0-9]+\\.?[0-9]*x$" options:NSRegularExpressionAnchorsMatchLines error:nil];
36 | [pattern enumerateMatchesInString:name options:kNilOptions range:NSMakeRange(0, name.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
37 | if (result.range.location >= 3) {
38 | scale = [string substringWithRange:NSMakeRange(result.range.location + 1, result.range.length - 2)].doubleValue;
39 | }
40 | }];
41 |
42 | return scale;
43 | }
44 |
45 |
46 |
47 | @implementation YYFrameImage {
48 | NSUInteger _loopCount;
49 | NSUInteger _oneFrameBytes;
50 | NSArray *_imagePaths;
51 | NSArray *_imageDatas;
52 | NSArray *_frameDurations;
53 | }
54 |
55 | - (instancetype)initWithImagePaths:(NSArray *)paths oneFrameDuration:(NSTimeInterval)oneFrameDuration loopCount:(NSUInteger)loopCount {
56 | NSMutableArray *durations = [NSMutableArray new];
57 | for (int i = 0, max = (int)paths.count; i < max; i++) {
58 | [durations addObject:@(oneFrameDuration)];
59 | }
60 | return [self initWithImagePaths:paths frameDurations:durations loopCount:loopCount];
61 | }
62 |
63 | - (instancetype)initWithImagePaths:(NSArray *)paths frameDurations:(NSArray *)frameDurations loopCount:(NSUInteger)loopCount {
64 | if (paths.count == 0) return nil;
65 | if (paths.count != frameDurations.count) return nil;
66 |
67 | NSString *firstPath = paths[0];
68 | NSData *firstData = [NSData dataWithContentsOfFile:firstPath];
69 | CGFloat scale = _NSStringPathScale(firstPath);
70 | UIImage *firstCG = [[[UIImage alloc] initWithData:firstData] yy_imageByDecoded];
71 | self = [self initWithCGImage:firstCG.CGImage scale:scale orientation:UIImageOrientationUp];
72 | if (!self) return nil;
73 | long frameByte = CGImageGetBytesPerRow(firstCG.CGImage) * CGImageGetHeight(firstCG.CGImage);
74 | _oneFrameBytes = (NSUInteger)frameByte;
75 | _imagePaths = paths.copy;
76 | _frameDurations = frameDurations.copy;
77 | _loopCount = loopCount;
78 |
79 | return self;
80 | }
81 |
82 | - (instancetype)initWithImageDataArray:(NSArray *)dataArray oneFrameDuration:(NSTimeInterval)oneFrameDuration loopCount:(NSUInteger)loopCount {
83 | NSMutableArray *durations = [NSMutableArray new];
84 | for (int i = 0, max = (int)dataArray.count; i < max; i++) {
85 | [durations addObject:@(oneFrameDuration)];
86 | }
87 | return [self initWithImageDataArray:dataArray frameDurations:durations loopCount:loopCount];
88 | }
89 |
90 | - (instancetype)initWithImageDataArray:(NSArray *)dataArray frameDurations:(NSArray *)frameDurations loopCount:(NSUInteger)loopCount {
91 | if (dataArray.count == 0) return nil;
92 | if (dataArray.count != frameDurations.count) return nil;
93 |
94 | NSData *firstData = dataArray[0];
95 | CGFloat scale = [UIScreen mainScreen].scale;
96 | UIImage *firstCG = [[[UIImage alloc] initWithData:firstData] yy_imageByDecoded];
97 | self = [self initWithCGImage:firstCG.CGImage scale:scale orientation:UIImageOrientationUp];
98 | if (!self) return nil;
99 | long frameByte = CGImageGetBytesPerRow(firstCG.CGImage) * CGImageGetHeight(firstCG.CGImage);
100 | _oneFrameBytes = (NSUInteger)frameByte;
101 | _imageDatas = dataArray.copy;
102 | _frameDurations = frameDurations.copy;
103 | _loopCount = loopCount;
104 |
105 | return self;
106 | }
107 |
108 | #pragma mark - YYAnimtedImage
109 |
110 | - (NSUInteger)animatedImageFrameCount {
111 | if (_imagePaths) {
112 | return _imagePaths.count;
113 | } else if (_imageDatas) {
114 | return _imageDatas.count;
115 | } else {
116 | return 1;
117 | }
118 | }
119 |
120 | - (NSUInteger)animatedImageLoopCount {
121 | return _loopCount;
122 | }
123 |
124 | - (NSUInteger)animatedImageBytesPerFrame {
125 | return _oneFrameBytes;
126 | }
127 |
128 | - (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {
129 | if (_imagePaths) {
130 | if (index >= _imagePaths.count) return nil;
131 | NSString *path = _imagePaths[index];
132 | CGFloat scale = _NSStringPathScale(path);
133 | NSData *data = [NSData dataWithContentsOfFile:path];
134 | return [[UIImage imageWithData:data scale:scale] yy_imageByDecoded];
135 | } else if (_imageDatas) {
136 | if (index >= _imageDatas.count) return nil;
137 | NSData *data = _imageDatas[index];
138 | return [[UIImage imageWithData:data scale:[UIScreen mainScreen].scale] yy_imageByDecoded];
139 | } else {
140 | return index == 0 ? self : nil;
141 | }
142 | }
143 |
144 | - (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {
145 | if (index >= _frameDurations.count) return 0;
146 | NSNumber *num = _frameDurations[index];
147 | return [num doubleValue];
148 | }
149 |
150 | @end
151 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Image/YYImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYImage.h
3 | // YYImage
4 | //
5 | // Created by ibireme on 14/10/20.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | #if __has_include()
15 | FOUNDATION_EXPORT double YYImageVersionNumber;
16 | FOUNDATION_EXPORT const unsigned char YYImageVersionString[];
17 | #import
18 | #import
19 | #import
20 | #import
21 | #elif __has_include()
22 | #import
23 | #import
24 | #import
25 | #import
26 | #else
27 | #import "YYFrameImage.h"
28 | #import "YYSpriteSheetImage.h"
29 | #import "YYImageCoder.h"
30 | #import "YYAnimatedImageView.h"
31 | #endif
32 |
33 | NS_ASSUME_NONNULL_BEGIN
34 |
35 |
36 | /**
37 | A YYImage object is a high-level way to display animated image data.
38 |
39 | @discussion It is a fully compatible `UIImage` subclass. It extends the UIImage
40 | to support animated WebP, APNG and GIF format image data decoding. It also
41 | support NSCoding protocol to archive and unarchive multi-frame image data.
42 |
43 | If the image is created from multi-frame image data, and you want to play the
44 | animation, try replace UIImageView with `YYAnimatedImageView`.
45 |
46 | Sample Code:
47 |
48 | // animation@3x.webp
49 | YYImage *image = [YYImage imageNamed:@"animation.webp"];
50 | YYAnimatedImageView *imageView = [YYAnimatedImageView alloc] initWithImage:image];
51 | [view addSubView:imageView];
52 |
53 | */
54 | @interface YYImage : UIImage
55 |
56 | + (nullable YYImage *)imageNamed:(NSString *)name; // no cache!
57 | + (nullable YYImage *)imageWithContentsOfFile:(NSString *)path;
58 | + (nullable YYImage *)imageWithData:(NSData *)data;
59 | + (nullable YYImage *)imageWithData:(NSData *)data scale:(CGFloat)scale;
60 |
61 | /**
62 | If the image is created from data or file, then the value indicates the data type.
63 | */
64 | @property (nonatomic, readonly) YYImageType animatedImageType;
65 |
66 | /**
67 | If the image is created from animated image data (multi-frame GIF/APNG/WebP),
68 | this property stores the original image data.
69 | */
70 | @property (nullable, nonatomic, readonly) NSData *animatedImageData;
71 |
72 | /**
73 | The total memory usage (in bytes) if all frame images was loaded into memory.
74 | The value is 0 if the image is not created from a multi-frame image data.
75 | */
76 | @property (nonatomic, readonly) NSUInteger animatedImageMemorySize;
77 |
78 | /**
79 | Preload all frame image to memory.
80 |
81 | @discussion Set this property to `YES` will block the calling thread to decode
82 | all animation frame image to memory, set to `NO` will release the preloaded frames.
83 | If the image is shared by lots of image views (such as emoticon), preload all
84 | frames will reduce the CPU cost.
85 |
86 | See `animatedImageMemorySize` for memory cost.
87 | */
88 | @property (nonatomic) BOOL preloadAllAnimatedImageFrames;
89 |
90 | @end
91 |
92 | NS_ASSUME_NONNULL_END
93 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Image/YYImage.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYImage.m
3 | // YYImage
4 | //
5 | // Created by ibireme on 14/10/20.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import "YYImage.h"
13 |
14 | /**
15 | An array of NSNumber objects, shows the best order for path scale search.
16 | e.g. iPhone3GS:@[@1,@2,@3] iPhone5:@[@2,@3,@1] iPhone6 Plus:@[@3,@2,@1]
17 | */
18 | static NSArray *_NSBundlePreferredScales() {
19 | static NSArray *scales;
20 | static dispatch_once_t onceToken;
21 | dispatch_once(&onceToken, ^{
22 | CGFloat screenScale = [UIScreen mainScreen].scale;
23 | if (screenScale <= 1) {
24 | scales = @[@1,@2,@3];
25 | } else if (screenScale <= 2) {
26 | scales = @[@2,@3,@1];
27 | } else {
28 | scales = @[@3,@2,@1];
29 | }
30 | });
31 | return scales;
32 | }
33 |
34 | /**
35 | Add scale modifier to the file name (without path extension),
36 | From @"name" to @"name@2x".
37 |
38 | e.g.
39 |
40 | Before | After(scale:2) |
41 | "icon" | "icon@2x" |
42 | "icon " | "icon @2x" |
43 | "icon.top" | "icon.top@2x" |
44 | "/p/name" | "/p/name@2x" |
45 | "/path/" | "/path/" |
46 |
47 |
48 | @param scale Resource scale.
49 | @return String by add scale modifier, or just return if it's not end with file name.
50 | */
51 | static NSString *_NSStringByAppendingNameScale(NSString *string, CGFloat scale) {
52 | if (!string) return nil;
53 | if (fabs(scale - 1) <= __FLT_EPSILON__ || string.length == 0 || [string hasSuffix:@"/"]) return string.copy;
54 | return [string stringByAppendingFormat:@"@%@x", @(scale)];
55 | }
56 |
57 | /**
58 | Return the path scale.
59 |
60 | e.g.
61 |
62 | Path | Scale |
63 | "icon.png" | 1 |
64 | "icon@2x.png" | 2 |
65 | "icon@2.5x.png" | 2.5 |
66 | "icon@2x" | 1 |
67 | "icon@2x..png" | 1 |
68 | "icon@2x.png/" | 1 |
69 |
70 | */
71 | static CGFloat _NSStringPathScale(NSString *string) {
72 | if (string.length == 0 || [string hasSuffix:@"/"]) return 1;
73 | NSString *name = string.stringByDeletingPathExtension;
74 | __block CGFloat scale = 1;
75 |
76 | NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:@"@[0-9]+\\.?[0-9]*x$" options:NSRegularExpressionAnchorsMatchLines error:nil];
77 | [pattern enumerateMatchesInString:name options:kNilOptions range:NSMakeRange(0, name.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
78 | if (result.range.location >= 3) {
79 | scale = [string substringWithRange:NSMakeRange(result.range.location + 1, result.range.length - 2)].doubleValue;
80 | }
81 | }];
82 |
83 | return scale;
84 | }
85 |
86 |
87 | @implementation YYImage {
88 | YYImageDecoder *_decoder;
89 | NSArray *_preloadedFrames;
90 | dispatch_semaphore_t _preloadedLock;
91 | NSUInteger _bytesPerFrame;
92 | }
93 |
94 | + (YYImage *)imageNamed:(NSString *)name {
95 | if (name.length == 0) return nil;
96 | if ([name hasSuffix:@"/"]) return nil;
97 |
98 | NSString *res = name.stringByDeletingPathExtension;
99 | NSString *ext = name.pathExtension;
100 | NSString *path = nil;
101 | CGFloat scale = 1;
102 |
103 | // If no extension, guess by system supported (same as UIImage).
104 | NSArray *exts = ext.length > 0 ? @[ext] : @[@"", @"png", @"jpeg", @"jpg", @"gif", @"webp", @"apng"];
105 | NSArray *scales = _NSBundlePreferredScales();
106 | for (int s = 0; s < scales.count; s++) {
107 | scale = ((NSNumber *)scales[s]).floatValue;
108 | NSString *scaledName = _NSStringByAppendingNameScale(res, scale);
109 | for (NSString *e in exts) {
110 | path = [[NSBundle mainBundle] pathForResource:scaledName ofType:e];
111 | if (path) break;
112 | }
113 | if (path) break;
114 | }
115 | if (path.length == 0) return nil;
116 |
117 | NSData *data = [NSData dataWithContentsOfFile:path];
118 | if (data.length == 0) return nil;
119 |
120 | return [[self alloc] initWithData:data scale:scale];
121 | }
122 |
123 | + (YYImage *)imageWithContentsOfFile:(NSString *)path {
124 | return [[self alloc] initWithContentsOfFile:path];
125 | }
126 |
127 | + (YYImage *)imageWithData:(NSData *)data {
128 | return [[self alloc] initWithData:data];
129 | }
130 |
131 | + (YYImage *)imageWithData:(NSData *)data scale:(CGFloat)scale {
132 | return [[self alloc] initWithData:data scale:scale];
133 | }
134 |
135 | - (instancetype)initWithContentsOfFile:(NSString *)path {
136 | NSData *data = [NSData dataWithContentsOfFile:path];
137 | return [self initWithData:data scale:_NSStringPathScale(path)];
138 | }
139 |
140 | - (instancetype)initWithData:(NSData *)data {
141 | return [self initWithData:data scale:1];
142 | }
143 |
144 | - (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale {
145 | if (data.length == 0) return nil;
146 | if (scale <= 0) scale = [UIScreen mainScreen].scale;
147 | _preloadedLock = dispatch_semaphore_create(1);
148 | @autoreleasepool {
149 | YYImageDecoder *decoder = [YYImageDecoder decoderWithData:data scale:scale];
150 | YYImageFrame *frame = [decoder frameAtIndex:0 decodeForDisplay:YES];
151 | UIImage *image = frame.image;
152 | if (!image) return nil;
153 | self = [self initWithCGImage:image.CGImage scale:decoder.scale orientation:image.imageOrientation];
154 | if (!self) return nil;
155 | _animatedImageType = decoder.type;
156 | if (decoder.frameCount > 1) {
157 | _decoder = decoder;
158 | _bytesPerFrame = CGImageGetBytesPerRow(image.CGImage) * CGImageGetHeight(image.CGImage);
159 | _animatedImageMemorySize = _bytesPerFrame * decoder.frameCount;
160 | }
161 | self.yy_isDecodedForDisplay = YES;
162 | }
163 | return self;
164 | }
165 |
166 | - (NSData *)animatedImageData {
167 | return _decoder.data;
168 | }
169 |
170 | - (void)setPreloadAllAnimatedImageFrames:(BOOL)preloadAllAnimatedImageFrames {
171 | if (_preloadAllAnimatedImageFrames != preloadAllAnimatedImageFrames) {
172 | if (preloadAllAnimatedImageFrames && _decoder.frameCount > 0) {
173 | NSMutableArray *frames = [NSMutableArray new];
174 | for (NSUInteger i = 0, max = _decoder.frameCount; i < max; i++) {
175 | UIImage *img = [self animatedImageFrameAtIndex:i];
176 | if (img) {
177 | [frames addObject:img];
178 | } else {
179 | [frames addObject:[NSNull null]];
180 | }
181 | }
182 | dispatch_semaphore_wait(_preloadedLock, DISPATCH_TIME_FOREVER);
183 | _preloadedFrames = frames;
184 | dispatch_semaphore_signal(_preloadedLock);
185 | } else {
186 | dispatch_semaphore_wait(_preloadedLock, DISPATCH_TIME_FOREVER);
187 | _preloadedFrames = nil;
188 | dispatch_semaphore_signal(_preloadedLock);
189 | }
190 | }
191 | }
192 |
193 | #pragma mark - protocol NSCoding
194 |
195 | - (instancetype)initWithCoder:(NSCoder *)aDecoder {
196 | NSNumber *scale = [aDecoder decodeObjectForKey:@"YYImageScale"];
197 | NSData *data = [aDecoder decodeObjectForKey:@"YYImageData"];
198 | if (data.length) {
199 | self = [self initWithData:data scale:scale.doubleValue];
200 | } else {
201 | self = [super initWithCoder:aDecoder];
202 | }
203 | return self;
204 | }
205 |
206 | - (void)encodeWithCoder:(NSCoder *)aCoder {
207 | if (_decoder.data.length) {
208 | [aCoder encodeObject:@(self.scale) forKey:@"YYImageScale"];
209 | [aCoder encodeObject:_decoder.data forKey:@"YYImageData"];
210 | } else {
211 | [super encodeWithCoder:aCoder]; // Apple use UIImagePNGRepresentation() to encode UIImage.
212 | }
213 | }
214 |
215 | #pragma mark - protocol YYAnimatedImage
216 |
217 | - (NSUInteger)animatedImageFrameCount {
218 | return _decoder.frameCount;
219 | }
220 |
221 | - (NSUInteger)animatedImageLoopCount {
222 | return _decoder.loopCount;
223 | }
224 |
225 | - (NSUInteger)animatedImageBytesPerFrame {
226 | return _bytesPerFrame;
227 | }
228 |
229 | - (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {
230 | if (index >= _decoder.frameCount) return nil;
231 | dispatch_semaphore_wait(_preloadedLock, DISPATCH_TIME_FOREVER);
232 | UIImage *image = _preloadedFrames[index];
233 | dispatch_semaphore_signal(_preloadedLock);
234 | if (image) return image == (id)[NSNull null] ? nil : image;
235 | return [_decoder frameAtIndex:index decodeForDisplay:YES].image;
236 | }
237 |
238 | - (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {
239 | NSTimeInterval duration = [_decoder frameDurationAtIndex:index];
240 |
241 | /*
242 | http://opensource.apple.com/source/WebCore/WebCore-7600.1.25/platform/graphics/cg/ImageSourceCG.cpp
243 | Many annoying ads specify a 0 duration to make an image flash as quickly as
244 | possible. We follow Safari and Firefox's behavior and use a duration of 100 ms
245 | for any frames that specify a duration of <= 10 ms.
246 | See and for more information.
247 |
248 | See also: http://nullsleep.tumblr.com/post/16524517190/animated-gif-minimum-frame-delay-browser.
249 | */
250 | if (duration < 0.011f) return 0.100f;
251 | return duration;
252 | }
253 |
254 | @end
255 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Image/YYSpriteSheetImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYSpriteImage.h
3 | // YYImage
4 | //
5 | // Created by ibireme on 15/4/21.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | #if __has_include()
15 | #import
16 | #elif __has_include()
17 | #import
18 | #else
19 | #import "YYAnimatedImageView.h"
20 | #endif
21 |
22 | NS_ASSUME_NONNULL_BEGIN
23 |
24 | /**
25 | An image to display sprite sheet animation.
26 |
27 | @discussion It is a fully compatible `UIImage` subclass.
28 | The animation can be played by YYAnimatedImageView.
29 |
30 | Sample Code:
31 |
32 | // 8 * 12 sprites in a single sheet image
33 | UIImage *spriteSheet = [UIImage imageNamed:@"sprite-sheet"];
34 | NSMutableArray *contentRects = [NSMutableArray new];
35 | NSMutableArray *durations = [NSMutableArray new];
36 | for (int j = 0; j < 12; j++) {
37 | for (int i = 0; i < 8; i++) {
38 | CGRect rect;
39 | rect.size = CGSizeMake(img.size.width / 8, img.size.height / 12);
40 | rect.origin.x = img.size.width / 8 * i;
41 | rect.origin.y = img.size.height / 12 * j;
42 | [contentRects addObject:[NSValue valueWithCGRect:rect]];
43 | [durations addObject:@(1 / 60.0)];
44 | }
45 | }
46 | YYSpriteSheetImage *sprite;
47 | sprite = [[YYSpriteSheetImage alloc] initWithSpriteSheetImage:img
48 | contentRects:contentRects
49 | frameDurations:durations
50 | loopCount:0];
51 | YYAnimatedImageView *imgView = [YYAnimatedImageView new];
52 | imgView.size = CGSizeMake(img.size.width / 8, img.size.height / 12);
53 | imgView.image = sprite;
54 |
55 |
56 |
57 | @discussion It can also be used to display single frame in sprite sheet image.
58 | Sample Code:
59 |
60 | YYSpriteSheetImage *sheet = ...;
61 | UIImageView *imageView = ...;
62 | imageView.image = sheet;
63 | imageView.layer.contentsRect = [sheet contentsRectForCALayerAtIndex:6];
64 |
65 | */
66 | @interface YYSpriteSheetImage : UIImage
67 |
68 | /**
69 | Creates and returns an image object.
70 |
71 | @param image The sprite sheet image (contains all frames).
72 |
73 | @param contentRects The sprite sheet image frame rects in the image coordinates.
74 | The rectangle should not outside the image's bounds. The objects in this array
75 | should be created with [NSValue valueWithCGRect:].
76 |
77 | @param frameDurations The sprite sheet image frame's durations in seconds.
78 | The objects in this array should be NSNumber.
79 |
80 | @param loopCount Animation loop count, 0 means infinite looping.
81 |
82 | @return An image object, or nil if an error occurs.
83 | */
84 | - (nullable instancetype)initWithSpriteSheetImage:(UIImage *)image
85 | contentRects:(NSArray *)contentRects
86 | frameDurations:(NSArray *)frameDurations
87 | loopCount:(NSUInteger)loopCount;
88 |
89 | @property (nonatomic, readonly) NSArray *contentRects;
90 | @property (nonatomic, readonly) NSArray *frameDurations;
91 | @property (nonatomic, readonly) NSUInteger loopCount;
92 |
93 | /**
94 | Get the contents rect for CALayer.
95 | See "contentsRect" property in CALayer for more information.
96 |
97 | @param index Index of frame.
98 | @return Contents Rect.
99 | */
100 | - (CGRect)contentsRectForCALayerAtIndex:(NSUInteger)index;
101 |
102 | @end
103 |
104 | NS_ASSUME_NONNULL_END
105 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/Image/YYSpriteSheetImage.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYSpriteImage.m
3 | // YYImage
4 | //
5 | // Created by ibireme on 15/4/21.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import "YYSpriteSheetImage.h"
13 |
14 | @implementation YYSpriteSheetImage
15 |
16 | - (instancetype)initWithSpriteSheetImage:(UIImage *)image
17 | contentRects:(NSArray *)contentRects
18 | frameDurations:(NSArray *)frameDurations
19 | loopCount:(NSUInteger)loopCount {
20 | if (!image.CGImage) return nil;
21 | if (contentRects.count < 1 || frameDurations.count < 1) return nil;
22 | if (contentRects.count != frameDurations.count) return nil;
23 |
24 | self = [super initWithCGImage:image.CGImage scale:image.scale orientation:image.imageOrientation];
25 | if (!self) return nil;
26 |
27 | _contentRects = contentRects.copy;
28 | _frameDurations = frameDurations.copy;
29 | _loopCount = loopCount;
30 | return self;
31 | }
32 |
33 | - (CGRect)contentsRectForCALayerAtIndex:(NSUInteger)index {
34 | CGRect layerRect = CGRectMake(0, 0, 1, 1);
35 | if (index >= _contentRects.count) return layerRect;
36 |
37 | CGSize imageSize = self.size;
38 | CGRect rect = [self animatedImageContentsRectAtIndex:index];
39 | if (imageSize.width > 0.01 && imageSize.height > 0.01) {
40 | layerRect.origin.x = rect.origin.x / imageSize.width;
41 | layerRect.origin.y = rect.origin.y / imageSize.height;
42 | layerRect.size.width = rect.size.width / imageSize.width;
43 | layerRect.size.height = rect.size.height / imageSize.height;
44 | layerRect = CGRectIntersection(layerRect, CGRectMake(0, 0, 1, 1));
45 | if (CGRectIsNull(layerRect) || CGRectIsEmpty(layerRect)) {
46 | layerRect = CGRectMake(0, 0, 1, 1);
47 | }
48 | }
49 | return layerRect;
50 | }
51 |
52 | #pragma mark @protocol YYAnimatedImage
53 |
54 | - (NSUInteger)animatedImageFrameCount {
55 | return _contentRects.count;
56 | }
57 |
58 | - (NSUInteger)animatedImageLoopCount {
59 | return _loopCount;
60 | }
61 |
62 | - (NSUInteger)animatedImageBytesPerFrame {
63 | return 0;
64 | }
65 |
66 | - (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {
67 | return self;
68 | }
69 |
70 | - (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {
71 | if (index >= _frameDurations.count) return 0;
72 | return ((NSNumber *)_frameDurations[index]).doubleValue;
73 | }
74 |
75 | - (CGRect)animatedImageContentsRectAtIndex:(NSUInteger)index {
76 | if (index >= _contentRects.count) return CGRectZero;
77 | return ((NSValue *)_contentRects[index]).CGRectValue;
78 | }
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/YYImageCache.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYImageCache.h
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/15.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | @class YYMemoryCache, YYDiskCache;
15 |
16 | NS_ASSUME_NONNULL_BEGIN
17 |
18 | /// Image cache type
19 | typedef NS_OPTIONS(NSUInteger, YYImageCacheType) {
20 | /// No value.
21 | YYImageCacheTypeNone = 0,
22 |
23 | /// Get/store image with memory cache.
24 | YYImageCacheTypeMemory = 1 << 0,
25 |
26 | /// Get/store image with disk cache.
27 | YYImageCacheTypeDisk = 1 << 1,
28 |
29 | /// Get/store image with both memory cache and disk cache.
30 | YYImageCacheTypeAll = YYImageCacheTypeMemory | YYImageCacheTypeDisk,
31 | };
32 |
33 |
34 | /**
35 | YYImageCache is a cache that stores UIImage and image data based on memory cache and disk cache.
36 |
37 | @discussion The disk cache will try to protect the original image data:
38 |
39 | * If the original image is still image, it will be saved as png/jpeg file based on alpha information.
40 | * If the original image is animated gif, apng or webp, it will be saved as original format.
41 | * If the original image's scale is not 1, the scale value will be saved as extended data.
42 |
43 | Although UIImage can be serialized with NSCoding protocol, but it's not a good idea:
44 | Apple actually use UIImagePNGRepresentation() to encode all kind of image, it may
45 | lose the original multi-frame data. The result is packed to plist file and cannot
46 | view with photo viewer directly. If the image has no alpha channel, using JPEG
47 | instead of PNG can save more disk size and encoding/decoding time.
48 | */
49 | @interface YYImageCache : NSObject
50 |
51 | #pragma mark - Attribute
52 | ///=============================================================================
53 | /// @name Attribute
54 | ///=============================================================================
55 |
56 | /** The name of the cache. Default is nil. */
57 | @property (nullable, copy) NSString *name;
58 |
59 | /** The underlying memory cache. see `YYMemoryCache` for more information.*/
60 | @property (strong, readonly) YYMemoryCache *memoryCache;
61 |
62 | /** The underlying disk cache. see `YYDiskCache` for more information.*/
63 | @property (strong, readonly) YYDiskCache *diskCache;
64 |
65 | /**
66 | Whether decode animated image when fetch image from disk cache. Default is YES.
67 |
68 | @discussion When fetch image from disk cache, it will use 'YYImage' to decode
69 | animated image such as WebP/APNG/GIF. Set to 'NO' to ignore animated image.
70 | */
71 | @property BOOL allowAnimatedImage;
72 |
73 | /**
74 | Whether decode the image to memory bitmap. Default is YES.
75 |
76 | @discussion If the value is YES, then the image will be decoded to memory bitmap
77 | for better display performance, but may cost more memory.
78 | */
79 | @property BOOL decodeForDisplay;
80 |
81 |
82 | #pragma mark - Initializer
83 | ///=============================================================================
84 | /// @name Initializer
85 | ///=============================================================================
86 | - (instancetype)init UNAVAILABLE_ATTRIBUTE;
87 | + (instancetype)new UNAVAILABLE_ATTRIBUTE;
88 |
89 | /**
90 | Returns global shared image cache instance.
91 | @return The singleton YYImageCache instance.
92 | */
93 | + (instancetype)sharedCache;
94 |
95 | /**
96 | The designated initializer. Multiple instances with the same path will make the
97 | cache unstable.
98 |
99 | @param path Full path of a directory in which the cache will write data.
100 | Once initialized you should not read and write to this directory.
101 | @result A new cache object, or nil if an error occurs.
102 | */
103 | - (nullable instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;
104 |
105 |
106 | #pragma mark - Access Methods
107 | ///=============================================================================
108 | /// @name Access Methods
109 | ///=============================================================================
110 |
111 | /**
112 | Sets the image with the specified key in the cache (both memory and disk).
113 | This method returns immediately and executes the store operation in background.
114 |
115 | @param image The image to be stored in the cache. If nil, this method has no effect.
116 | @param key The key with which to associate the image. If nil, this method has no effect.
117 | */
118 | - (void)setImage:(UIImage *)image forKey:(NSString *)key;
119 |
120 | /**
121 | Sets the image with the specified key in the cache.
122 | This method returns immediately and executes the store operation in background.
123 |
124 | @discussion If the `type` contain `YYImageCacheTypeMemory`, then the `image` will
125 | be stored in the memory cache; `imageData` will be used instead if `image` is nil.
126 | If the `type` contain `YYImageCacheTypeDisk`, then the `imageData` will
127 | be stored in the disk cache; `image` will be used instead if `imageData` is nil.
128 |
129 | @param image The image to be stored in the cache.
130 | @param imageData The image data to be stored in the cache.
131 | @param key The key with which to associate the image. If nil, this method has no effect.
132 | @param type The cache type to store image.
133 | */
134 | - (void)setImage:(nullable UIImage *)image
135 | imageData:(nullable NSData *)imageData
136 | forKey:(NSString *)key
137 | withType:(YYImageCacheType)type;
138 |
139 | /**
140 | Removes the image of the specified key in the cache (both memory and disk).
141 | This method returns immediately and executes the remove operation in background.
142 |
143 | @param key The key identifying the image to be removed. If nil, this method has no effect.
144 | */
145 | - (void)removeImageForKey:(NSString *)key;
146 |
147 | /**
148 | Removes the image of the specified key in the cache.
149 | This method returns immediately and executes the remove operation in background.
150 |
151 | @param key The key identifying the image to be removed. If nil, this method has no effect.
152 | @param type The cache type to remove image.
153 | */
154 | - (void)removeImageForKey:(NSString *)key withType:(YYImageCacheType)type;
155 |
156 | /**
157 | Returns a Boolean value that indicates whether a given key is in cache.
158 | If the image is not in memory, this method may blocks the calling thread until
159 | file read finished.
160 |
161 | @param key A string identifying the image. If nil, just return NO.
162 | @return Whether the image is in cache.
163 | */
164 | - (BOOL)containsImageForKey:(NSString *)key;
165 |
166 | /**
167 | Returns a Boolean value that indicates whether a given key is in cache.
168 | If the image is not in memory and the `type` contains `YYImageCacheTypeDisk`,
169 | this method may blocks the calling thread until file read finished.
170 |
171 | @param key A string identifying the image. If nil, just return NO.
172 | @param type The cache type.
173 | @return Whether the image is in cache.
174 | */
175 | - (BOOL)containsImageForKey:(NSString *)key withType:(YYImageCacheType)type;
176 |
177 | /**
178 | Returns the image associated with a given key.
179 | If the image is not in memory, this method may blocks the calling thread until
180 | file read finished.
181 |
182 | @param key A string identifying the image. If nil, just return nil.
183 | @return The image associated with key, or nil if no image is associated with key.
184 | */
185 | - (nullable UIImage *)getImageForKey:(NSString *)key;
186 |
187 | /**
188 | Returns the image associated with a given key.
189 | If the image is not in memory and the `type` contains `YYImageCacheTypeDisk`,
190 | this method may blocks the calling thread until file read finished.
191 |
192 | @param key A string identifying the image. If nil, just return nil.
193 | @return The image associated with key, or nil if no image is associated with key.
194 | */
195 | - (nullable UIImage *)getImageForKey:(NSString *)key withType:(YYImageCacheType)type;
196 |
197 | /**
198 | Asynchronously get the image associated with a given key.
199 |
200 | @param key A string identifying the image. If nil, just return nil.
201 | @param type The cache type.
202 | @param block A completion block which will be called on main thread.
203 | */
204 | - (void)getImageForKey:(NSString *)key
205 | withType:(YYImageCacheType)type
206 | withBlock:(void(^)(UIImage * _Nullable image, YYImageCacheType type))block;
207 |
208 | /**
209 | Returns the image data associated with a given key.
210 | This method may blocks the calling thread until file read finished.
211 |
212 | @param key A string identifying the image. If nil, just return nil.
213 | @return The image data associated with key, or nil if no image is associated with key.
214 | */
215 | - (nullable NSData *)getImageDataForKey:(NSString *)key;
216 |
217 | /**
218 | Asynchronously get the image data associated with a given key.
219 |
220 | @param key A string identifying the image. If nil, just return nil.
221 | @param block A completion block which will be called on main thread.
222 | */
223 | - (void)getImageDataForKey:(NSString *)key
224 | withBlock:(void(^)(NSData * _Nullable imageData))block;
225 |
226 | @end
227 |
228 | NS_ASSUME_NONNULL_END
229 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/YYImageCache.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYImageCache.m
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/15.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import "YYImageCache.h"
13 | #import "YYImage.h"
14 | #import "UIImage+YYWebImage.h"
15 |
16 | #if __has_include()
17 | #import
18 | #else
19 | #import "YYImage.h"
20 | #endif
21 |
22 | #if __has_include()
23 | #import
24 | #else
25 | #import "YYCache.h"
26 | #endif
27 |
28 |
29 |
30 | static inline dispatch_queue_t YYImageCacheIOQueue() {
31 | return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
32 | }
33 |
34 | static inline dispatch_queue_t YYImageCacheDecodeQueue() {
35 | return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
36 | }
37 |
38 |
39 | @interface YYImageCache ()
40 | - (NSUInteger)imageCost:(UIImage *)image;
41 | - (UIImage *)imageFromData:(NSData *)data;
42 | @end
43 |
44 |
45 | @implementation YYImageCache
46 |
47 | - (NSUInteger)imageCost:(UIImage *)image {
48 | CGImageRef cgImage = image.CGImage;
49 | if (!cgImage) return 1;
50 | CGFloat height = CGImageGetHeight(cgImage);
51 | size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);
52 | NSUInteger cost = bytesPerRow * height;
53 | if (cost == 0) cost = 1;
54 | return cost;
55 | }
56 |
57 | - (UIImage *)imageFromData:(NSData *)data {
58 | NSData *scaleData = [YYDiskCache getExtendedDataFromObject:data];
59 | CGFloat scale = 0;
60 | if (scaleData) {
61 | scale = ((NSNumber *)[NSKeyedUnarchiver unarchiveObjectWithData:scaleData]).doubleValue;
62 | }
63 | if (scale <= 0) scale = [UIScreen mainScreen].scale;
64 | UIImage *image;
65 | if (_allowAnimatedImage) {
66 | image = [[YYImage alloc] initWithData:data scale:scale];
67 | if (_decodeForDisplay) image = [image yy_imageByDecoded];
68 | } else {
69 | YYImageDecoder *decoder = [YYImageDecoder decoderWithData:data scale:scale];
70 | image = [decoder frameAtIndex:0 decodeForDisplay:_decodeForDisplay].image;
71 | }
72 | return image;
73 | }
74 |
75 | #pragma mark Public
76 |
77 | + (instancetype)sharedCache {
78 | static YYImageCache *cache = nil;
79 | static dispatch_once_t onceToken;
80 | dispatch_once(&onceToken, ^{
81 | NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
82 | NSUserDomainMask, YES) firstObject];
83 | cachePath = [cachePath stringByAppendingPathComponent:@"com.ibireme.yykit"];
84 | cachePath = [cachePath stringByAppendingPathComponent:@"images"];
85 | cache = [[self alloc] initWithPath:cachePath];
86 | });
87 | return cache;
88 | }
89 |
90 | - (instancetype)init {
91 | @throw [NSException exceptionWithName:@"YYImageCache init error" reason:@"YYImageCache must be initialized with a path. Use 'initWithPath:' instead." userInfo:nil];
92 | return [self initWithPath:@""];
93 | }
94 |
95 | - (instancetype)initWithPath:(NSString *)path {
96 | YYMemoryCache *memoryCache = [YYMemoryCache new];
97 | memoryCache.shouldRemoveAllObjectsOnMemoryWarning = YES;
98 | memoryCache.shouldRemoveAllObjectsWhenEnteringBackground = YES;
99 | memoryCache.countLimit = NSUIntegerMax;
100 | memoryCache.costLimit = NSUIntegerMax;
101 | memoryCache.ageLimit = 12 * 60 * 60;
102 |
103 | YYDiskCache *diskCache = [[YYDiskCache alloc] initWithPath:path];
104 | diskCache.customArchiveBlock = ^(id object) { return (NSData *)object; };
105 | diskCache.customUnarchiveBlock = ^(NSData *data) { return (id)data; };
106 | if (!memoryCache || !diskCache) return nil;
107 |
108 | self = [super init];
109 | _memoryCache = memoryCache;
110 | _diskCache = diskCache;
111 | _allowAnimatedImage = YES;
112 | _decodeForDisplay = YES;
113 | return self;
114 | }
115 |
116 | - (void)setImage:(UIImage *)image forKey:(NSString *)key {
117 | [self setImage:image imageData:nil forKey:key withType:YYImageCacheTypeAll];
118 | }
119 |
120 | - (void)setImage:(UIImage *)image imageData:(NSData *)imageData forKey:(NSString *)key withType:(YYImageCacheType)type {
121 | if (!key || (image == nil && imageData.length == 0)) return;
122 |
123 | __weak typeof(self) _self = self;
124 | if (type & YYImageCacheTypeMemory) { // add to memory cache
125 | if (image) {
126 | if (image.yy_isDecodedForDisplay) {
127 | [_memoryCache setObject:image forKey:key withCost:[_self imageCost:image]];
128 | } else {
129 | dispatch_async(YYImageCacheDecodeQueue(), ^{
130 | __strong typeof(_self) self = _self;
131 | if (!self) return;
132 | [self.memoryCache setObject:[image yy_imageByDecoded] forKey:key withCost:[self imageCost:image]];
133 | });
134 | }
135 | } else if (imageData) {
136 | dispatch_async(YYImageCacheDecodeQueue(), ^{
137 | __strong typeof(_self) self = _self;
138 | if (!self) return;
139 | UIImage *newImage = [self imageFromData:imageData];
140 | [self.memoryCache setObject:newImage forKey:key withCost:[self imageCost:newImage]];
141 | });
142 | }
143 | }
144 | if (type & YYImageCacheTypeDisk) { // add to disk cache
145 | if (imageData) {
146 | if (image) {
147 | [YYDiskCache setExtendedData:[NSKeyedArchiver archivedDataWithRootObject:@(image.scale)] toObject:imageData];
148 | }
149 | [_diskCache setObject:imageData forKey:key];
150 | } else if (image) {
151 | dispatch_async(YYImageCacheIOQueue(), ^{
152 | __strong typeof(_self) self = _self;
153 | if (!self) return;
154 | NSData *data = [image yy_imageDataRepresentation];
155 | [YYDiskCache setExtendedData:[NSKeyedArchiver archivedDataWithRootObject:@(image.scale)] toObject:data];
156 | [self.diskCache setObject:data forKey:key];
157 | });
158 | }
159 | }
160 | }
161 |
162 | - (void)removeImageForKey:(NSString *)key {
163 | [self removeImageForKey:key withType:YYImageCacheTypeAll];
164 | }
165 |
166 | - (void)removeImageForKey:(NSString *)key withType:(YYImageCacheType)type {
167 | if (type & YYImageCacheTypeMemory) [_memoryCache removeObjectForKey:key];
168 | if (type & YYImageCacheTypeDisk) [_diskCache removeObjectForKey:key];
169 | }
170 |
171 | - (BOOL)containsImageForKey:(NSString *)key {
172 | return [self containsImageForKey:key withType:YYImageCacheTypeAll];
173 | }
174 |
175 | - (BOOL)containsImageForKey:(NSString *)key withType:(YYImageCacheType)type {
176 | if (type & YYImageCacheTypeMemory) {
177 | if ([_memoryCache containsObjectForKey:key]) return YES;
178 | }
179 | if (type & YYImageCacheTypeDisk) {
180 | if ([_diskCache containsObjectForKey:key]) return YES;
181 | }
182 | return NO;
183 | }
184 |
185 | - (UIImage *)getImageForKey:(NSString *)key {
186 | return [self getImageForKey:key withType:YYImageCacheTypeAll];
187 | }
188 |
189 | - (UIImage *)getImageForKey:(NSString *)key withType:(YYImageCacheType)type {
190 | if (!key) return nil;
191 | if (type & YYImageCacheTypeMemory) {
192 | UIImage *image = [_memoryCache objectForKey:key];
193 | if (image) return image;
194 | }
195 | if (type & YYImageCacheTypeDisk) {
196 | NSData *data = (id)[_diskCache objectForKey:key];
197 | UIImage *image = [self imageFromData:data];
198 | if (image && (type & YYImageCacheTypeMemory)) {
199 | [_memoryCache setObject:image forKey:key withCost:[self imageCost:image]];
200 | }
201 | return image;
202 | }
203 | return nil;
204 | }
205 |
206 | - (void)getImageForKey:(NSString *)key withType:(YYImageCacheType)type withBlock:(void (^)(UIImage *image, YYImageCacheType type))block {
207 | if (!block) return;
208 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
209 | UIImage *image = nil;
210 |
211 | if (type & YYImageCacheTypeMemory) {
212 | image = [_memoryCache objectForKey:key];
213 | if (image) {
214 | dispatch_async(dispatch_get_main_queue(), ^{
215 | block(image, YYImageCacheTypeMemory);
216 | });
217 | return;
218 | }
219 | }
220 |
221 | if (type & YYImageCacheTypeDisk) {
222 | NSData *data = (id)[_diskCache objectForKey:key];
223 | image = [self imageFromData:data];
224 | if (image) {
225 | [_memoryCache setObject:image forKey:key];
226 | dispatch_async(dispatch_get_main_queue(), ^{
227 | block(image, YYImageCacheTypeDisk);
228 | });
229 | return;
230 | }
231 | }
232 |
233 | dispatch_async(dispatch_get_main_queue(), ^{
234 | block(nil, YYImageCacheTypeNone);
235 | });
236 | });
237 | }
238 |
239 | - (NSData *)getImageDataForKey:(NSString *)key {
240 | return (id)[_diskCache objectForKey:key];
241 | }
242 |
243 | - (void)getImageDataForKey:(NSString *)key withBlock:(void (^)(NSData *imageData))block {
244 | if (!block) return;
245 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
246 | NSData *data = (id)[_diskCache objectForKey:key];
247 | dispatch_async(dispatch_get_main_queue(), ^{
248 | block(data);
249 | });
250 | });
251 | }
252 |
253 | @end
254 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/YYWebImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYWebImage.h
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/23.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | #if __has_include()
15 | FOUNDATION_EXPORT double YYWebImageVersionNumber;
16 | FOUNDATION_EXPORT const unsigned char YYWebImageVersionString[];
17 | #import
18 | #import
19 | #import
20 | #import
21 | #import
22 | #import
23 | #import
24 | #import
25 | #else
26 | #import "YYImageCache.h"
27 | #import "YYWebImageOperation.h"
28 | #import "YYWebImageManager.h"
29 | #import "UIImage+YYWebImage.h"
30 | #import "UIImageView+YYWebImage.h"
31 | #import "UIButton+YYWebImage.h"
32 | #import "CALayer+YYWebImage.h"
33 | #import "MKAnnotationView+YYWebImage.h"
34 | #endif
35 |
36 | #if __has_include()
37 | #import
38 | #elif __has_include()
39 | #import
40 | #import
41 | #import
42 | #import
43 | #import
44 | #else
45 | #import "YYImage.h"
46 | #import "YYFrameImage.h"
47 | #import "YYSpriteSheetImage.h"
48 | #import "YYImageCoder.h"
49 | #import "YYAnimatedImageView.h"
50 | #endif
51 |
52 | #if __has_include()
53 | #import
54 | #elif __has_include()
55 | #import
56 | #import
57 | #import
58 | #import
59 | #else
60 | #import "YYCache.h"
61 | #import "YYMemoryCache.h"
62 | #import "YYDiskCache.h"
63 | #import "YYKVStorage.h"
64 | #endif
65 |
66 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/YYWebImageManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYWebImageManager.h
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/19.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | #if __has_include()
15 | #import
16 | #else
17 | #import "YYImageCache.h"
18 | #endif
19 |
20 | @class YYWebImageOperation;
21 |
22 | NS_ASSUME_NONNULL_BEGIN
23 |
24 | /// The options to control image operation.
25 | typedef NS_OPTIONS(NSUInteger, YYWebImageOptions) {
26 |
27 | /// Show network activity on status bar when download image.
28 | YYWebImageOptionShowNetworkActivity = 1 << 0,
29 |
30 | /// Display progressive/interlaced/baseline image during download (same as web browser).
31 | YYWebImageOptionProgressive = 1 << 1,
32 |
33 | /// Display blurred progressive JPEG or interlaced PNG image during download.
34 | /// This will ignore baseline image for better user experience.
35 | YYWebImageOptionProgressiveBlur = 1 << 2,
36 |
37 | /// Use NSURLCache instead of YYImageCache.
38 | YYWebImageOptionUseNSURLCache = 1 << 3,
39 |
40 | /// Allows untrusted SSL ceriticates.
41 | YYWebImageOptionAllowInvalidSSLCertificates = 1 << 4,
42 |
43 | /// Allows background task to download image when app is in background.
44 | YYWebImageOptionAllowBackgroundTask = 1 << 5,
45 |
46 | /// Handles cookies stored in NSHTTPCookieStore.
47 | YYWebImageOptionHandleCookies = 1 << 6,
48 |
49 | /// Load the image from remote and refresh the image cache.
50 | YYWebImageOptionRefreshImageCache = 1 << 7,
51 |
52 | /// Do not load image from/to disk cache.
53 | YYWebImageOptionIgnoreDiskCache = 1 << 8,
54 |
55 | /// Do not change the view's image before set a new URL to it.
56 | YYWebImageOptionIgnorePlaceHolder = 1 << 9,
57 |
58 | /// Ignore image decoding.
59 | /// This may used for image downloading without display.
60 | YYWebImageOptionIgnoreImageDecoding = 1 << 10,
61 |
62 | /// Ignore multi-frame image decoding.
63 | /// This will handle the GIF/APNG/WebP/ICO image as single frame image.
64 | YYWebImageOptionIgnoreAnimatedImage = 1 << 11,
65 |
66 | /// Set the image to view with a fade animation.
67 | /// This will add a "fade" animation on image view's layer for better user experience.
68 | YYWebImageOptionSetImageWithFadeAnimation = 1 << 12,
69 |
70 | /// Do not set the image to the view when image fetch complete.
71 | /// You may set the image manually.
72 | YYWebImageOptionAvoidSetImage = 1 << 13,
73 |
74 | /// This flag will add the URL to a blacklist (in memory) when the URL fail to be downloaded,
75 | /// so the library won't keep trying.
76 | YYWebImageOptionIgnoreFailedURL = 1 << 14,
77 | };
78 |
79 | /// Indicated where the image came from.
80 | typedef NS_ENUM(NSUInteger, YYWebImageFromType) {
81 |
82 | /// No value.
83 | YYWebImageFromNone = 0,
84 |
85 | /// Fetched from memory cache immediately.
86 | /// If you called "setImageWithURL:..." and the image is already in memory,
87 | /// then you will get this value at the same call.
88 | YYWebImageFromMemoryCacheFast,
89 |
90 | /// Fetched from memory cache.
91 | YYWebImageFromMemoryCache,
92 |
93 | /// Fetched from disk cache.
94 | YYWebImageFromDiskCache,
95 |
96 | /// Fetched from remote (web or file path).
97 | YYWebImageFromRemote,
98 | };
99 |
100 | /// Indicated image fetch complete stage.
101 | typedef NS_ENUM(NSInteger, YYWebImageStage) {
102 |
103 | /// Incomplete, progressive image.
104 | YYWebImageStageProgress = -1,
105 |
106 | /// Cancelled.
107 | YYWebImageStageCancelled = 0,
108 |
109 | /// Finished (succeed or failed).
110 | YYWebImageStageFinished = 1,
111 | };
112 |
113 |
114 | /**
115 | The block invoked in remote image fetch progress.
116 |
117 | @param receivedSize Current received size in bytes.
118 | @param expectedSize Expected total size in bytes (-1 means unknown).
119 | */
120 | typedef void(^YYWebImageProgressBlock)(NSInteger receivedSize, NSInteger expectedSize);
121 |
122 | /**
123 | The block invoked before remote image fetch finished to do additional image process.
124 |
125 | @discussion This block will be invoked before `YYWebImageCompletionBlock` to give
126 | you a chance to do additional image process (such as resize or crop). If there's
127 | no need to transform the image, just return the `image` parameter.
128 |
129 | @example You can clip the image, blur it and add rounded corners with these code:
130 | ^(UIImage *image, NSURL *url) {
131 | // Maybe you need to create an @autoreleasepool to limit memory cost.
132 | image = [image yy_imageByResizeToSize:CGSizeMake(100, 100) contentMode:UIViewContentModeScaleAspectFill];
133 | image = [image yy_imageByBlurRadius:20 tintColor:nil tintMode:kCGBlendModeNormal saturation:1.2 maskImage:nil];
134 | image = [image yy_imageByRoundCornerRadius:5];
135 | return image;
136 | }
137 |
138 | @param image The image fetched from url.
139 | @param url The image url (remote or local file path).
140 | @return The transformed image.
141 | */
142 | typedef UIImage * _Nullable (^YYWebImageTransformBlock)(UIImage *image, NSURL *url);
143 |
144 | /**
145 | The block invoked when image fetch finished or cancelled.
146 |
147 | @param image The image.
148 | @param url The image url (remote or local file path).
149 | @param from Where the image came from.
150 | @param error Error during image fetching.
151 | @param finished If the operation is cancelled, this value is NO, otherwise YES.
152 | */
153 | typedef void (^YYWebImageCompletionBlock)(UIImage * _Nullable image,
154 | NSURL *url,
155 | YYWebImageFromType from,
156 | YYWebImageStage stage,
157 | NSError * _Nullable error);
158 |
159 |
160 |
161 |
162 | /**
163 | A manager to create and manage web image operation.
164 | */
165 | @interface YYWebImageManager : NSObject
166 |
167 | /**
168 | Returns global YYWebImageManager instance.
169 |
170 | @return YYWebImageManager shared instance.
171 | */
172 | + (instancetype)sharedManager;
173 |
174 | /**
175 | Creates a manager with an image cache and operation queue.
176 |
177 | @param cache Image cache used by manager (pass nil to avoid image cache).
178 | @param queue The operation queue on which image operations are scheduled and run
179 | (pass nil to make the new operation start immediately without queue).
180 | @return A new manager.
181 | */
182 | - (instancetype)initWithCache:(nullable YYImageCache *)cache
183 | queue:(nullable NSOperationQueue *)queue NS_DESIGNATED_INITIALIZER;
184 |
185 | - (instancetype)init UNAVAILABLE_ATTRIBUTE;
186 | + (instancetype)new UNAVAILABLE_ATTRIBUTE;
187 |
188 | /**
189 | Creates and returns a new image operation, the operation will start immediately.
190 |
191 | @param url The image url (remote or local file path).
192 | @param options The options to control image operation.
193 | @param progress Progress block which will be invoked on background thread (pass nil to avoid).
194 | @param transform Transform block which will be invoked on background thread (pass nil to avoid).
195 | @param completion Completion block which will be invoked on background thread (pass nil to avoid).
196 | @return A new image operation.
197 | */
198 | - (nullable YYWebImageOperation *)requestImageWithURL:(NSURL *)url
199 | options:(YYWebImageOptions)options
200 | progress:(nullable YYWebImageProgressBlock)progress
201 | transform:(nullable YYWebImageTransformBlock)transform
202 | completion:(nullable YYWebImageCompletionBlock)completion;
203 |
204 | /**
205 | The image cache used by image operation.
206 | You can set it to nil to avoid image cache.
207 | */
208 | @property (nullable, nonatomic, strong) YYImageCache *cache;
209 |
210 | /**
211 | The operation queue on which image operations are scheduled and run.
212 | You can set it to nil to make the new operation start immediately without queue.
213 |
214 | You can use this queue to control maximum number of concurrent operations, to obtain
215 | the status of the current operations, or to cancel all operations in this manager.
216 | */
217 | @property (nullable, nonatomic, strong) NSOperationQueue *queue;
218 |
219 | /**
220 | The shared transform block to process image. Default is nil.
221 |
222 | When called `requestImageWithURL:options:progress:transform:completion` and
223 | the `transform` is nil, this block will be used.
224 | */
225 | @property (nullable, nonatomic, copy) YYWebImageTransformBlock sharedTransformBlock;
226 |
227 | /**
228 | The image request timeout interval in seconds. Default is 15.
229 | */
230 | @property (nonatomic) NSTimeInterval timeout;
231 |
232 | /**
233 | The username used by NSURLCredential, default is nil.
234 | */
235 | @property (nullable, nonatomic, copy) NSString *username;
236 |
237 | /**
238 | The password used by NSURLCredential, default is nil.
239 | */
240 | @property (nullable, nonatomic, copy) NSString *password;
241 |
242 | /**
243 | The image HTTP request header. Default is "Accept:image/webp,image/\*;q=0.8".
244 | */
245 | @property (nullable, nonatomic, copy) NSDictionary *headers;
246 |
247 | /**
248 | A block which will be invoked for each image HTTP request to do additional
249 | HTTP header process. Default is nil.
250 |
251 | Use this block to add or remove HTTP header field for a specified URL.
252 | */
253 | @property (nullable, nonatomic, copy) NSDictionary *(^headersFilter)(NSURL *url, NSDictionary * _Nullable header);
254 |
255 | /**
256 | A block which will be invoked for each image operation. Default is nil.
257 |
258 | Use this block to provide a custom image cache key for a specified URL.
259 | */
260 | @property (nullable, nonatomic, copy) NSString *(^cacheKeyFilter)(NSURL *url);
261 |
262 | /**
263 | Returns the HTTP headers for a specified URL.
264 |
265 | @param url A specified URL.
266 | @return HTTP headers.
267 | */
268 | - (nullable NSDictionary *)headersForURL:(NSURL *)url;
269 |
270 | /**
271 | Returns the cache key for a specified URL.
272 |
273 | @param url A specified URL
274 | @return Cache key used in YYImageCache.
275 | */
276 | - (NSString *)cacheKeyForURL:(NSURL *)url;
277 |
278 |
279 | /**
280 | Increments the number of active network requests.
281 | If this number was zero before incrementing, this will start animating the
282 | status bar network activity indicator.
283 |
284 | This method is thread safe.
285 |
286 | This method has no effect in App Extension.
287 | */
288 | + (void)incrementNetworkActivityCount;
289 |
290 | /**
291 | Decrements the number of active network requests.
292 | If this number becomes zero after decrementing, this will stop animating the
293 | status bar network activity indicator.
294 |
295 | This method is thread safe.
296 |
297 | This method has no effect in App Extension.
298 | */
299 | + (void)decrementNetworkActivityCount;
300 |
301 | /**
302 | Get current number of active network requests.
303 |
304 | This method is thread safe.
305 |
306 | This method has no effect in App Extension.
307 | */
308 | + (NSInteger)currentNetworkActivityCount;
309 |
310 | @end
311 |
312 | NS_ASSUME_NONNULL_END
313 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/YYWebImageManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYWebImageManager.m
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/19.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import "YYWebImageManager.h"
13 | #import "YYImageCache.h"
14 | #import "YYWebImageOperation.h"
15 | #import "YYImageCoder.h"
16 | #import
17 |
18 | #define kNetworkIndicatorDelay (1/30.0)
19 |
20 |
21 | /// Returns nil in App Extension.
22 | static UIApplication *_YYSharedApplication() {
23 | static BOOL isAppExtension = NO;
24 | static dispatch_once_t onceToken;
25 | dispatch_once(&onceToken, ^{
26 | Class cls = NSClassFromString(@"UIApplication");
27 | if(!cls || ![cls respondsToSelector:@selector(sharedApplication)]) isAppExtension = YES;
28 | if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) isAppExtension = YES;
29 | });
30 | #pragma clang diagnostic push
31 | #pragma clang diagnostic ignored "-Wundeclared-selector"
32 | return isAppExtension ? nil : [UIApplication performSelector:@selector(sharedApplication)];
33 | #pragma clang diagnostic pop
34 | }
35 |
36 |
37 | @interface _YYWebImageApplicationNetworkIndicatorInfo : NSObject
38 | @property (nonatomic, assign) NSInteger count;
39 | @property (nonatomic, strong) NSTimer *timer;
40 | @end
41 | @implementation _YYWebImageApplicationNetworkIndicatorInfo
42 | @end
43 |
44 | @implementation YYWebImageManager
45 |
46 | + (instancetype)sharedManager {
47 | static YYWebImageManager *manager;
48 | static dispatch_once_t onceToken;
49 | dispatch_once(&onceToken, ^{
50 | YYImageCache *cache = [YYImageCache sharedCache];
51 | NSOperationQueue *queue = [NSOperationQueue new];
52 | if ([queue respondsToSelector:@selector(setQualityOfService:)]) {
53 | queue.qualityOfService = NSQualityOfServiceBackground;
54 | }
55 | manager = [[self alloc] initWithCache:cache queue:queue];
56 | });
57 | return manager;
58 | }
59 |
60 | - (instancetype)init {
61 | @throw [NSException exceptionWithName:@"YYWebImageManager init error" reason:@"Use the designated initializer to init." userInfo:nil];
62 | return [self initWithCache:nil queue:nil];
63 | }
64 |
65 | - (instancetype)initWithCache:(YYImageCache *)cache queue:(NSOperationQueue *)queue{
66 | self = [super init];
67 | if (!self) return nil;
68 | _cache = cache;
69 | _queue = queue;
70 | _timeout = 15.0;
71 | if (YYImageWebPAvailable()) {
72 | _headers = @{ @"Accept" : @"image/webp,image/*;q=0.8" };
73 | } else {
74 | _headers = @{ @"Accept" : @"image/*;q=0.8" };
75 | }
76 | return self;
77 | }
78 |
79 | - (YYWebImageOperation *)requestImageWithURL:(NSURL *)url
80 | options:(YYWebImageOptions)options
81 | progress:(YYWebImageProgressBlock)progress
82 | transform:(YYWebImageTransformBlock)transform
83 | completion:(YYWebImageCompletionBlock)completion {
84 |
85 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
86 | request.timeoutInterval = _timeout;
87 | request.HTTPShouldHandleCookies = (options & YYWebImageOptionHandleCookies) != 0;
88 | request.allHTTPHeaderFields = [self headersForURL:url];
89 | request.HTTPShouldUsePipelining = YES;
90 | request.cachePolicy = (options & YYWebImageOptionUseNSURLCache) ?
91 | NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData;
92 |
93 | YYWebImageOperation *operation = [[YYWebImageOperation alloc] initWithRequest:request
94 | options:options
95 | cache:_cache
96 | cacheKey:[self cacheKeyForURL:url]
97 | progress:progress
98 | transform:transform ? transform : _sharedTransformBlock
99 | completion:completion];
100 |
101 | if (_username && _password) {
102 | operation.credential = [NSURLCredential credentialWithUser:_username password:_password persistence:NSURLCredentialPersistenceForSession];
103 | }
104 | if (operation) {
105 | NSOperationQueue *queue = _queue;
106 | if (queue) {
107 | [queue addOperation:operation];
108 | } else {
109 | [operation start];
110 | }
111 | }
112 | return operation;
113 | }
114 |
115 | - (NSDictionary *)headersForURL:(NSURL *)url {
116 | if (!url) return nil;
117 | return _headersFilter ? _headersFilter(url, _headers) : _headers;
118 | }
119 |
120 | - (NSString *)cacheKeyForURL:(NSURL *)url {
121 | if (!url) return nil;
122 | return _cacheKeyFilter ? _cacheKeyFilter(url) : url.absoluteString;
123 | }
124 |
125 |
126 |
127 | #pragma mark Network Indicator
128 |
129 | + (_YYWebImageApplicationNetworkIndicatorInfo *)_networkIndicatorInfo {
130 | return objc_getAssociatedObject(self, @selector(_networkIndicatorInfo));
131 | }
132 |
133 | + (void)_setNetworkIndicatorInfo:(_YYWebImageApplicationNetworkIndicatorInfo *)info {
134 | objc_setAssociatedObject(self, @selector(_networkIndicatorInfo), info, OBJC_ASSOCIATION_RETAIN);
135 | }
136 |
137 | + (void)_delaySetActivity:(NSTimer *)timer {
138 | UIApplication *app = _YYSharedApplication();
139 | if (!app) return;
140 |
141 | NSNumber *visiable = timer.userInfo;
142 | if (app.networkActivityIndicatorVisible != visiable.boolValue) {
143 | [app setNetworkActivityIndicatorVisible:visiable.boolValue];
144 | }
145 | [timer invalidate];
146 | }
147 |
148 | + (void)_changeNetworkActivityCount:(NSInteger)delta {
149 | if (!_YYSharedApplication()) return;
150 |
151 | void (^block)() = ^{
152 | _YYWebImageApplicationNetworkIndicatorInfo *info = [self _networkIndicatorInfo];
153 | if (!info) {
154 | info = [_YYWebImageApplicationNetworkIndicatorInfo new];
155 | [self _setNetworkIndicatorInfo:info];
156 | }
157 | NSInteger count = info.count;
158 | count += delta;
159 | info.count = count;
160 | [info.timer invalidate];
161 | info.timer = [NSTimer timerWithTimeInterval:kNetworkIndicatorDelay target:self selector:@selector(_delaySetActivity:) userInfo:@(info.count > 0) repeats:NO];
162 | [[NSRunLoop mainRunLoop] addTimer:info.timer forMode:NSRunLoopCommonModes];
163 | };
164 | if ([NSThread isMainThread]) {
165 | block();
166 | } else {
167 | dispatch_async(dispatch_get_main_queue(), block);
168 | }
169 | }
170 |
171 | + (void)incrementNetworkActivityCount {
172 | [self _changeNetworkActivityCount:1];
173 | }
174 |
175 | + (void)decrementNetworkActivityCount {
176 | [self _changeNetworkActivityCount:-1];
177 | }
178 |
179 | + (NSInteger)currentNetworkActivityCount {
180 | _YYWebImageApplicationNetworkIndicatorInfo *info = [self _networkIndicatorInfo];
181 | return info.count;
182 | }
183 |
184 | @end
185 |
--------------------------------------------------------------------------------
/HYNavigation/Vendors/YYWebImage/YYWebImageOperation.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYWebImageOperation.h
3 | // YYWebImage
4 | //
5 | // Created by ibireme on 15/2/15.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | #if __has_include()
15 | #import
16 | #import
17 | #else
18 | #import "YYImageCache.h"
19 | #import "YYWebImageManager.h"
20 | #endif
21 |
22 | NS_ASSUME_NONNULL_BEGIN
23 |
24 | /**
25 | The YYWebImageOperation class is an NSOperation subclass used to fetch image
26 | from URL request.
27 |
28 | @discussion It's an asynchronous operation. You typically execute it by adding
29 | it to an operation queue, or calls 'start' to execute it manually. When the
30 | operation is started, it will:
31 |
32 | 1. Get the image from the cache, if exist, return it with `completion` block.
33 | 2. Start an URL connection to fetch image from the request, invoke the `progress`
34 | to notify request progress (and invoke `completion` block to return the
35 | progressive image if enabled by progressive option).
36 | 3. Process the image by invoke the `transform` block.
37 | 4. Put the image to cache and return it with `completion` block.
38 |
39 | */
40 | @interface YYWebImageOperation : NSOperation
41 |
42 | @property (nonatomic, strong, readonly) NSURLRequest *request; ///< The image URL request.
43 | @property (nullable, nonatomic, strong, readonly) NSURLResponse *response; ///< The response for request.
44 | @property (nullable, nonatomic, strong, readonly) YYImageCache *cache; ///< The image cache.
45 | @property (nonatomic, strong, readonly) NSString *cacheKey; ///< The image cache key.
46 | @property (nonatomic, readonly) YYWebImageOptions options; ///< The operation's option.
47 |
48 | /**
49 | Whether the URL connection should consult the credential storage for authenticating
50 | the connection. Default is YES.
51 |
52 | @discussion This is the value that is returned in the `NSURLConnectionDelegate`
53 | method `-connectionShouldUseCredentialStorage:`.
54 | */
55 | @property (nonatomic) BOOL shouldUseCredentialStorage;
56 |
57 | /**
58 | The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`.
59 |
60 | @discussion This will be overridden by any shared credentials that exist for the
61 | username or password of the request URL, if present.
62 | */
63 | @property (nullable, nonatomic, strong) NSURLCredential *credential;
64 |
65 | /**
66 | Creates and returns a new operation.
67 |
68 | You should call `start` to execute this operation, or you can add the operation
69 | to an operation queue.
70 |
71 | @param request The Image request. This value should not be nil.
72 | @param options A mask to specify options to use for this operation.
73 | @param cache An image cache. Pass nil to avoid image cache.
74 | @param cacheKey An image cache key. Pass nil to avoid image cache.
75 | @param progress A block invoked in image fetch progress.
76 | The block will be invoked in background thread. Pass nil to avoid it.
77 | @param transform A block invoked before image fetch finished to do additional image process.
78 | The block will be invoked in background thread. Pass nil to avoid it.
79 | @param completion A block invoked when image fetch finished or cancelled.
80 | The block will be invoked in background thread. Pass nil to avoid it.
81 |
82 | @return The image request opeartion, or nil if an error occurs.
83 | */
84 | - (instancetype)initWithRequest:(NSURLRequest *)request
85 | options:(YYWebImageOptions)options
86 | cache:(nullable YYImageCache *)cache
87 | cacheKey:(nullable NSString *)cacheKey
88 | progress:(nullable YYWebImageProgressBlock)progress
89 | transform:(nullable YYWebImageTransformBlock)transform
90 | completion:(nullable YYWebImageCompletionBlock)completion NS_DESIGNATED_INITIALIZER;
91 |
92 | - (instancetype)init UNAVAILABLE_ATTRIBUTE;
93 | + (instancetype)new UNAVAILABLE_ATTRIBUTE;
94 |
95 | @end
96 |
97 | NS_ASSUME_NONNULL_END
98 |
--------------------------------------------------------------------------------
/HYNavigation/ViewControllers/FirstViewViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // FirstViewViewController.h
3 | // HYNavigation
4 | //
5 | // Created by runlhy on 16/9/27.
6 | // Copyright © 2016年 Pengcent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface FirstViewViewController : UIViewController
12 |
13 | @property (nonatomic, strong) id parameter;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/HYNavigation/ViewControllers/FirstViewViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // FirstViewViewController.m
3 | // HYNavigation
4 | //
5 | // Created by runlhy on 16/9/27.
6 | // Copyright © 2016年 Pengcent. All rights reserved.
7 | //
8 | #define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
9 |
10 | #define SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
11 |
12 | #import "FirstViewViewController.h"
13 |
14 | @interface FirstViewViewController ()
15 |
16 | @end
17 |
18 | @implementation FirstViewViewController
19 |
20 | - (UIViewController *)getPresentedViewController
21 | {
22 | UIViewController *appRootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
23 | UIViewController *topVC = appRootVC;
24 | if (topVC.presentedViewController) {
25 | topVC = topVC.presentedViewController;
26 | }
27 | return topVC;
28 | }
29 |
30 | - (void)viewDidLoad {
31 | UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
32 | button.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.width);
33 | [button addTarget:self action:@selector(dismisVC:) forControlEvents:UIControlEventTouchUpInside];
34 | button.backgroundColor = [UIColor cyanColor];
35 | [button setTitle:@"disappear😛" forState:UIControlStateNormal];
36 | [self.view addSubview:button];
37 |
38 | [super viewDidLoad];
39 | }
40 | - (void)dismisVC:(UIButton *)button{
41 | [[self getPresentedViewController] dismissViewControllerAnimated:YES completion:nil];
42 |
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/HYNavigation/ViewControllers/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // HYNavigation
4 | //
5 | // Created by runlhy on 16/9/26.
6 | // Copyright © 2016年 Pengcent. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/HYNavigation/ViewControllers/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // HYNavigation
4 | //
5 | // Created by runlhy on 16/9/26.
6 | // Copyright © 2016年 Pengcent. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "HYPageView.h"
11 | #import "WaterFlowCollectionViewController.h"
12 |
13 | #define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
14 |
15 | #define SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
16 |
17 | @interface ViewController (){
18 | NSArray *_titles;
19 | }
20 |
21 | @property (nonatomic, strong) UITableView *tableView;
22 |
23 | @end
24 |
25 | @implementation ViewController
26 |
27 | - (void)createTableView{
28 | _tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
29 | _tableView.delegate = self;
30 | _tableView.dataSource = self;
31 | [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"];
32 | _tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);
33 | [self.view addSubview:_tableView];
34 |
35 | _tableView.tableFooterView = [UIView new];
36 | }
37 |
38 | - (void)viewDidLoad {
39 | [super viewDidLoad];
40 | [self createTableView];
41 | _titles = @[@"样例1.仿照优酷首页",@"样例2.仿照优酷Vip会员页面",@"样例3.仿照网易云音乐首页",@"样例4.瞎写",@"每页最后一页是返回"];
42 | }
43 |
44 |
45 | - (HYPageView *)test0 {
46 | HYPageView *pageView = [[HYPageView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) withTitles:@[@"头条",@"精选",@"新好声音"] withViewControllers:@[@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"FirstViewViewController"] withParameters:@[@"123",@"这是一片很寂寞的天"]];
47 |
48 | UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeSystem];
49 | [leftButton setImage:[UIImage imageNamed:@"search_"] forState:UIControlStateNormal];
50 | leftButton.frame = CGRectMake(0, 0, 50, 40);
51 | [leftButton setTintColor:[UIColor blackColor]];
52 | leftButton.transform = CGAffineTransformMakeScale(.7, .7);
53 | pageView.leftButton = leftButton;
54 |
55 | UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeSystem];
56 | [rightButton setImage:[UIImage imageNamed:@"more_"] forState:UIControlStateNormal];
57 | rightButton.frame = CGRectMake(0, 0, 50, 40);
58 | [rightButton setTintColor:[UIColor blackColor]];
59 | rightButton.transform = CGAffineTransformMakeScale(.5, .5);
60 | pageView.rightButton = rightButton;
61 | pageView.defaultSubscript = 0;
62 | return pageView;
63 | }
64 |
65 | - (HYPageView *)test1 {
66 |
67 | WaterFlowCollectionViewController *vc = [WaterFlowCollectionViewController new];
68 |
69 | HYPageView *pageView = [[HYPageView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) withTitles:@[@"精选",@"片库",@"电影",@"韩剧",@"德云社",@"动漫",@"电视剧",@"纪录片"] withViewControllers:@[@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",vc,@"FirstViewViewController"] withParameters:nil];
70 | pageView.pageViewStyle = HYPageViewStyleB;
71 |
72 | pageView.isTranslucent = NO;
73 | pageView.topTabViewColor = [UIColor colorWithRed:211/255. green:111/255. blue:39/255. alpha:.5];
74 | pageView.selectedColor = [UIColor yellowColor];
75 |
76 | UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeSystem];
77 | [leftButton setImage:[UIImage imageNamed:@"search_"] forState:UIControlStateNormal];
78 | pageView.isAdapteNavigationBar = NO;
79 | leftButton.frame = CGRectMake(0, 0, 50, 40);
80 | [leftButton setTintColor:[UIColor blackColor]];
81 | leftButton.transform = CGAffineTransformMakeScale(.7, .7);
82 | pageView.leftButton = leftButton;
83 | pageView.defaultSubscript = 1;
84 | return pageView;
85 | }
86 |
87 | - (HYPageView *)test2 {
88 | HYPageView *pageView = [[HYPageView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) withTitles:@[@"个性推介",@"歌单",@"主播电台",@"排行榜"] withViewControllers:@[@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"FirstViewViewController"] withParameters:nil];
89 | pageView.pageViewStyle = HYPageViewStyleB;
90 | pageView.selectedColor = [UIColor redColor];
91 | pageView.unselectedColor = [UIColor blackColor];
92 | pageView.defaultSubscript = 2;
93 |
94 | return pageView;
95 | }
96 |
97 | - (HYPageView *)test3 {
98 | HYPageView *pageView = [[HYPageView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) withTitles:@[@"One",@"Two",@"Three",@"Four",@"Five",@"Six"] withViewControllers:@[@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"FirstViewViewController"] withParameters:nil];
99 | pageView.pageViewStyle = HYPageViewStyleB;
100 | pageView.selectedColor = [UIColor redColor];
101 | pageView.unselectedColor = [UIColor blackColor];
102 | pageView.font = [UIFont fontWithName:@"Zapfino" size:16];
103 | pageView.defaultSubscript = 2;
104 | return pageView;
105 | }
106 |
107 | - (HYPageView *)test4 {
108 |
109 | HYPageView *pageView = [[HYPageView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) withTitles:@[@"我实在",@"也",@"想不出",@"头上",@"写",@"点啥了"] withViewControllers:@[@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"WaterFlowCollectionViewController",@"FirstViewViewController"] withParameters:nil];
110 | pageView.pageViewStyle = HYPageViewStyleB;
111 |
112 | pageView.isAnimated = YES;
113 | pageView.selectedColor = [UIColor blueColor];
114 | pageView.unselectedColor = [UIColor blackColor];
115 | pageView.font = [UIFont fontWithName:@"HoeflerText-Black" size:18];
116 | pageView.defaultSubscript = 4;
117 | return pageView;
118 | }
119 |
120 | - (void)viewWillAppear:(BOOL)animated{
121 | [super viewWillAppear:animated];
122 | [self.navigationController setNavigationBarHidden:NO animated:NO];
123 | }
124 |
125 | #pragma mark - DataSource & Delegate
126 |
127 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
128 | {
129 | return 1;
130 | }
131 |
132 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
133 | {
134 | return 5;
135 | }
136 |
137 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
138 | {
139 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell" forIndexPath:indexPath];
140 |
141 | cell.textLabel.text = _titles[indexPath.row];
142 |
143 | return cell;
144 | }
145 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
146 | return 80;
147 | }
148 |
149 |
150 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
151 | {
152 | switch (indexPath.row) {
153 | case 0:
154 | {
155 | UIViewController *v = [UIViewController new];
156 | [self.navigationController setNavigationBarHidden:YES animated:NO];
157 | [v.view addSubview:[self test0]];
158 | [self showViewController:v sender:nil];
159 |
160 | }
161 | break;
162 | case 1:
163 | {
164 | UIViewController *v = [UIViewController new];
165 | [v.view addSubview:[self test1]];
166 | [self showViewController:v sender:nil];
167 |
168 | }
169 | break;
170 | case 2:
171 | {
172 | UIViewController *v = [UIViewController new];
173 | UINavigationController *nv = [[UINavigationController alloc]initWithRootViewController:v];
174 | [v.view addSubview:[self test2]];
175 | [self showViewController:nv sender:nil];
176 | }
177 | break;
178 |
179 | case 3:
180 | {
181 | UIViewController *v = [UIViewController new];
182 | [v.view addSubview:[self test3]];
183 | [self showViewController:v sender:nil];
184 | }
185 | break;
186 |
187 | default:
188 | {
189 | UIViewController *v = [UIViewController new];
190 | [v.view addSubview:[self test4]];
191 | [self showViewController:v sender:nil];
192 | }
193 | break;
194 | }
195 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
196 | }
197 |
198 | @end
199 |
--------------------------------------------------------------------------------
/HYNavigation/ViewControllers/WoterFlow/WaterFlowCollectionViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // WaterFlowCollectionViewController.h
3 | // CollectionPictures
4 | //
5 | // Created by runlhy on 16/7/2.
6 | // Copyright © 2016年 runlhy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface WaterFlowCollectionViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/HYNavigation/ViewControllers/WoterFlow/WaterFlowCollectionViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // WaterFlowCollectionViewController.m
3 | // CollectionPictures
4 | //
5 | // Created by runlhy on 16/7/2.
6 | // Copyright © 2016年 runlhy. All rights reserved.
7 | //
8 |
9 | #import "WaterFlowCollectionViewController.h"
10 | #import "WaterFlowLayout.h"
11 | #import "YYWebImage.h"
12 | #import "WaterFlowCollectionViewCell.h"
13 |
14 | @interface WaterFlowCollectionViewController ()
15 | {
16 | UICollectionView *_collectionView;
17 | }
18 |
19 | @property (nonatomic, strong) NSMutableArray *allDataArray;
20 | @property (nonatomic, strong) NSMutableArray *randomDataArray;
21 |
22 | @end
23 |
24 | @implementation WaterFlowCollectionViewController
25 |
26 | - (void)dealloc{
27 | //NSLog(@"%@",self.class);
28 | }
29 |
30 | - (NSMutableArray *)randomDataArray
31 | {
32 | if (!_randomDataArray){
33 | _randomDataArray = [NSMutableArray array];
34 | }
35 | return _randomDataArray;
36 | }
37 |
38 | - (NSMutableArray *)allDataArray
39 | {
40 | if (!_allDataArray){
41 | _allDataArray = [NSMutableArray array];
42 | }
43 | return _allDataArray;
44 | }
45 |
46 | - (void)viewDidLoad {
47 | [super viewDidLoad];
48 |
49 | WaterFlowLayout *waterFlowLayout = [WaterFlowLayout new];
50 |
51 | _collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:waterFlowLayout];
52 |
53 | _collectionView.backgroundColor = [UIColor whiteColor];
54 | _collectionView.delegate = self;
55 | _collectionView.dataSource = self;
56 |
57 | [_collectionView registerNib:[UINib nibWithNibName:@"WaterFlowCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"WaterFlowCollectionViewCell"];
58 | self.view = _collectionView;
59 | // [self.view addSubview:_collectionView];
60 | [self requestData];
61 |
62 | }
63 |
64 | - (void)requestData{
65 | NSString *path = [[NSBundle mainBundle] pathForResource:@"x" ofType:@"txt"];
66 | NSString *string = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
67 | NSArray *array = [string componentsSeparatedByString:@"\n"];
68 | for (NSString *obj in array) {
69 | if ([obj containsString:@"http"] && [obj containsString:@"_240x426"] && ![obj containsString:@"_480x852"]) {
70 | [self.allDataArray addObject:obj];
71 | }
72 | }
73 |
74 | for (NSInteger i=0; i<27; i++) {
75 | [self.randomDataArray addObject:self.allDataArray[arc4random() % self.allDataArray.count]];
76 | }
77 | [_collectionView reloadData];
78 |
79 | }
80 |
81 | #pragma mark - UICollectionView DataSource
82 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
83 | return 1;
84 | }
85 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
86 | return self.randomDataArray.count;
87 | }
88 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
89 | WaterFlowCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"WaterFlowCollectionViewCell" forIndexPath:indexPath];
90 | NSURL *url = [NSURL URLWithString:self.randomDataArray[indexPath.row]];
91 | [cell.imgView yy_setImageWithURL:url options:YYWebImageOptionProgressive];
92 | return cell;
93 | }
94 |
95 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
96 | if (self.navigationController) {
97 | [self.navigationController pushViewController:[WaterFlowCollectionViewController new] animated:YES];
98 | }
99 |
100 | }
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/HYNavigation/ViewControllers/WoterFlow/WaterFlowLayout.h:
--------------------------------------------------------------------------------
1 | //
2 | // WaterFlowLayout.h
3 | // UICollectionDemo_01
4 | //
5 | // Created by runlhy on 16/6/16.
6 | // Copyright © 2016年 runlhy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface WaterFlowLayout : UICollectionViewLayout
12 |
13 | @end
--------------------------------------------------------------------------------
/HYNavigation/ViewControllers/WoterFlow/WaterFlowLayout.m:
--------------------------------------------------------------------------------
1 | //
2 | // WaterFlowLayout.m
3 | // UICollectionDemo_01
4 | //
5 | // Created by runlhy on 16/6/16.
6 | // Copyright © 2016年 runlhy. All rights reserved.
7 | //
8 |
9 | #import "WaterFlowLayout.h"
10 |
11 | static const CGFloat defaultColumnMargin = 3;
12 | static const CGFloat defaultRowMargin = 3;
13 | static const UIEdgeInsets defaultEdgeInsets = {3, 3, 3, 3};
14 | static const NSInteger defaultColumnCount = 3;
15 | static const NSInteger defaultHeight = 100;
16 |
17 | @interface WaterFlowLayout ()
18 |
19 | /** 存放所有cell的布局属性 */
20 | @property (nonatomic, strong) NSMutableArray *attrsArray;
21 |
22 | /** collection滚动高度 */
23 | @property (nonatomic, assign) CGFloat maxHeight;
24 |
25 | /** 当前高度 */
26 | @property (nonatomic, assign) CGFloat sectionHeight;
27 |
28 | /** 当前最大y */
29 | @property (nonatomic, assign) CGFloat maxSectionHeight;
30 |
31 | @end
32 |
33 | @implementation WaterFlowLayout
34 |
35 | #pragma mark - lazy
36 | - (NSMutableArray *)attrsArray
37 | {
38 | if (!_attrsArray){
39 | _attrsArray = [NSMutableArray array];
40 | }
41 | return _attrsArray;
42 | }
43 |
44 | /**
45 | * 初始化
46 | */
47 | - (void)prepareLayout{
48 | [super prepareLayout];
49 |
50 | // 清除之前所有的布局属性
51 | [self.attrsArray removeAllObjects];
52 | self.attrsArray = nil;
53 |
54 | //创建cell对应的布局属性
55 | for (int j=0; j<[self.collectionView numberOfSections]; j++) {
56 | NSInteger count = [self.collectionView numberOfItemsInSection:j];
57 | for (NSInteger i = 0; i < count; i++) {
58 | //创建位置
59 | NSIndexPath *indexpath = [NSIndexPath indexPathForItem:i inSection:j];
60 | //获取indexPath对应的布局属性
61 | UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexpath];
62 |
63 | [self.attrsArray addObject:attrs];
64 | }
65 | }
66 | }
67 | /**
68 | * 决定cell的排布
69 | */
70 | - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
71 | //NSLog(@"%s",__func__);
72 | return self.attrsArray;
73 | }
74 | /**
75 | * 返回indexpath对应cell的 布局的属性
76 | */
77 | - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
78 |
79 | //创建布局属性
80 | UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
81 |
82 | // collectionView的宽度
83 | CGFloat collectionViewW = self.collectionView.frame.size.width;
84 | CGFloat w = (collectionViewW - defaultEdgeInsets.left - defaultEdgeInsets.right - (defaultColumnCount - 1)*defaultColumnMargin)/defaultColumnCount;
85 | CGFloat h = w / ((sqrt(5.0)-1)/2.0);
86 | CGFloat x = defaultEdgeInsets.left;
87 | CGFloat y = defaultEdgeInsets.top;
88 |
89 | //12个为一个周期 根据周期计算位置
90 | NSInteger section = indexPath.row / 6;
91 | NSInteger row = indexPath.row % 6;
92 | switch (row) {
93 | case 0:
94 | case 1:
95 | case 2:{
96 | y = section * (3 * (h + defaultRowMargin)) + defaultEdgeInsets.top;
97 | x = defaultEdgeInsets.left + row * (w + defaultColumnMargin);
98 | }
99 | break;
100 | case 3:{
101 | if (section % 2 == 0){
102 | y = (3 * section + 1) * (h + defaultRowMargin) + defaultEdgeInsets.top;
103 | }else{
104 | y = (3 * section + 1) * (h + defaultRowMargin) + defaultEdgeInsets.top;
105 | w = w * 2 + defaultColumnMargin;
106 | h = h * 2 + defaultRowMargin;
107 | }
108 | }
109 | break;
110 | case 4:{
111 | if (section % 2 == 0){
112 | y = (3 * section + 2) * (h + defaultRowMargin) + defaultEdgeInsets.top;
113 | }else{
114 | x = defaultEdgeInsets.left + 2 * (w + defaultColumnMargin);
115 | y = (3 * section + 1) * (h + defaultRowMargin) + defaultEdgeInsets.top;
116 | }
117 | }
118 | break;
119 | default:{
120 | if (section % 2 == 0){
121 | x = defaultEdgeInsets.left + w + defaultColumnMargin;
122 | y = (3 * section + 1) * (h + defaultRowMargin) + defaultEdgeInsets.top;
123 | w = w * 2 + defaultColumnMargin;
124 | h = h * 2 + defaultRowMargin;
125 | }else{
126 | x = defaultEdgeInsets.left + 2 * (w + defaultColumnMargin);
127 | y = (3 * section + 2) * (h + defaultRowMargin) + defaultEdgeInsets.top;
128 | }
129 | }
130 | break;
131 | }
132 |
133 | //设置布局属性的frame
134 | y += _sectionHeight;
135 | attributes.frame = CGRectMake(x, y, w, h);
136 |
137 | //解决最后一块小于前一块的问题
138 | if (_maxSectionHeight < y + h) {
139 | _maxSectionHeight = y + h;
140 | }
141 | //下一组时 更新高度
142 | if (indexPath.row == [self.collectionView numberOfItemsInSection:indexPath.section]-1) {
143 | _sectionHeight = _maxSectionHeight + defaultEdgeInsets.bottom;
144 | }
145 | //获得最底部位置
146 | _maxHeight = _maxSectionHeight + defaultEdgeInsets.bottom;
147 | return attributes;
148 | }
149 |
150 | /**
151 | * 滚动范围
152 | */
153 | - (CGSize)collectionViewContentSize{
154 | return CGSizeMake(0,_maxHeight);
155 | }
156 |
157 | @end
158 |
--------------------------------------------------------------------------------
/HYNavigation/Views/WaterFlowCollectionViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // WaterFlowCollectionViewCell.h
3 | // CollectionPictures
4 | //
5 | // Created by runlhy on 16/7/2.
6 | // Copyright © 2016年 runlhy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface WaterFlowCollectionViewCell : UICollectionViewCell
12 | @property (weak, nonatomic) IBOutlet UIImageView *imgView;
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/HYNavigation/Views/WaterFlowCollectionViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // WaterFlowCollectionViewCell.m
3 | // CollectionPictures
4 | //
5 | // Created by runlhy on 16/7/2.
6 | // Copyright © 2016年 runlhy. All rights reserved.
7 | //
8 |
9 | #import "WaterFlowCollectionViewCell.h"
10 |
11 | @implementation WaterFlowCollectionViewCell
12 |
13 | - (void)awakeFromNib {
14 | // Initialization code
15 | }
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/HYNavigation/Views/WaterFlowCollectionViewCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/HYNavigation/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // HYNavigation
4 | //
5 | // Created by runlhy on 16/9/26.
6 | // Copyright © 2016年 Pengcent. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HYPageView
2 | ## 类似优酷,网易云音乐导航条,代码足够简单,使用足够简单。
3 |
4 |
5 | 
6 |
7 |
8 |
9 | 
10 |
11 |
12 |
13 | 
14 |
15 |
16 |
17 | 
18 |
19 |
20 |
--------------------------------------------------------------------------------