├── .gitignore ├── LICENSE ├── OCTool.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── OCTool.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── WorkspaceSettings.xcsettings ├── OCTool ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── Test.swift ├── ViewController.h ├── ViewController.m └── main.m ├── Podfile ├── Podfile.lock ├── README.md ├── Sources └── Core │ ├── AddressBook │ ├── YHAddressBook.h │ ├── YHAddressBook.m │ ├── YHAdressBookModel.h │ └── YHAdressBookModel.m │ ├── Alert │ ├── YHAlertViewController.h │ └── YHAlertViewController.m │ ├── AsyncDisplayKit │ ├── ASCollectionNode+YHASReload.h │ ├── ASCollectionNode+YHASReload.m │ ├── ASControlNode+YHAddTap.h │ ├── ASControlNode+YHAddTap.m │ ├── ASDisplayNode+YHAddTap.h │ ├── ASDisplayNode+YHAddTap.m │ ├── ASTableNode+YHASReload.h │ ├── ASTableNode+YHASReload.m │ ├── ASTextNode+YHHighlight.h │ ├── ASTextNode+YHHighlight.m │ ├── YHASCollectionLayoutDelegate.h │ ├── YHASCollectionLayoutDelegate.m │ ├── YHASEnlargeEdgeControlNode.h │ ├── YHASEnlargeEdgeControlNode.m │ ├── YHASNetworkImageNode.h │ └── YHASNetworkImageNode.m │ ├── Authorizetion │ ├── YHAuthorizetion.h │ ├── YHAuthorizetion.m │ ├── YHAuthorizetionCalendar.h │ ├── YHAuthorizetionCalendar.m │ ├── YHAuthorizetionCamera.h │ ├── YHAuthorizetionCamera.m │ ├── YHAuthorizetionContacts.h │ ├── YHAuthorizetionContacts.m │ ├── YHAuthorizetionMicrophone.h │ ├── YHAuthorizetionMicrophone.m │ ├── YHAuthorizetionPhotos.h │ ├── YHAuthorizetionPhotos.m │ ├── YHAuthorizetionReminder.h │ └── YHAuthorizetionReminder.m │ ├── ChineseSort │ ├── YHChineseSort.h │ ├── YHChineseSort.m │ ├── YHChineseSortModel.h │ ├── YHChineseSortModel.m │ ├── yh_chinese_letters.c │ └── yh_chinese_letters.h │ ├── Foundation │ ├── NSArray+YHExtension.h │ ├── NSArray+YHExtension.m │ ├── NSAttributedString+YHExtension.h │ ├── NSAttributedString+YHExtension.m │ ├── NSDate+YHExtension.h │ ├── NSDate+YHExtension.m │ ├── NSDictionary+YHExtension.h │ ├── NSDictionary+YHExtension.m │ ├── NSMutableAttributedString+YHExtension.h │ ├── NSMutableAttributedString+YHExtension.m │ ├── NSObject+YHExtension.h │ ├── NSObject+YHExtension.m │ ├── NSParagraphStyle+YHExtension.h │ ├── NSParagraphStyle+YHExtension.m │ ├── NSString+YHExtension.h │ └── NSString+YHExtension.m │ ├── ImageBrowser │ ├── AuxiliaryView │ │ ├── UIView+YHImageBrowserProgressView.h │ │ ├── UIView+YHImageBrowserProgressView.m │ │ ├── YHImageBrowserSheetView.h │ │ ├── YHImageBrowserSheetView.m │ │ ├── YHImageBrowserToolBar.h │ │ └── YHImageBrowserToolBar.m │ ├── Base │ │ ├── YHImageBrowserCollectionViewFlowLayout.h │ │ ├── YHImageBrowserCollectionViewFlowLayout.m │ │ ├── YHImageBrowserView.h │ │ └── YHImageBrowserView.m │ ├── Helper │ │ ├── YHImageBrowserDefine.h │ │ ├── YHImageBrowserLayoutDirectionManager.h │ │ ├── YHImageBrowserLayoutDirectionManager.m │ │ ├── YHImageBrowserWebImageManager.h │ │ └── YHImageBrowserWebImageManager.m │ ├── ImageBrowser │ │ ├── YHImage+Private.h │ │ ├── YHImage.h │ │ ├── YHImage.m │ │ ├── YHImageBrowserCell.h │ │ ├── YHImageBrowserCell.m │ │ ├── YHImageBrowserCellData+Private.h │ │ ├── YHImageBrowserCellData.h │ │ └── YHImageBrowserCellData.m │ ├── Protocol │ │ ├── YHImageBrowserCellDataProtocol.h │ │ ├── YHImageBrowserCellProtocol.h │ │ ├── YHImageBrowserDataSource.h │ │ ├── YHImageBrowserDelegate.h │ │ ├── YHImageBrowserViewDataSource.h │ │ └── YHImageBrowserViewDelegate.h │ ├── YHImageBrowser.h │ └── YHImageBrowser.m │ ├── Location │ ├── YHLocation.h │ └── YHLocation.m │ ├── MB_HUD │ ├── YHMBHud.h │ └── YHMBHud.m │ ├── Net │ ├── YHDownloadManager.h │ ├── YHDownloadManager.m │ ├── YHNet.h │ └── YHNet.m │ ├── PhotoManager │ ├── YHGIFManager.swift │ ├── YHPhotoManager.h │ └── YHPhotoManager.m │ ├── SendSMS │ ├── YHSendSMS.h │ └── YHSendSMS.m │ ├── SystemImagePicker │ ├── YHSystemImagePicker.h │ └── YHSystemImagePicker.m │ ├── TimeCountDown │ ├── YHTimeCountDownManager.h │ └── YHTimeCountDownManager.m │ ├── UIKit │ ├── AppDelegate+YHNotiExtension.h │ ├── AppDelegate+YHNotiExtension.m │ ├── UIButton+YHExtension.h │ ├── UIButton+YHExtension.m │ ├── UIDevice+YHExtension.h │ ├── UIDevice+YHExtension.m │ ├── UIImage+YHExtension.h │ ├── UIImage+YHExtension.m │ ├── UINavigationController+YHRotationExtension.h │ ├── UINavigationController+YHRotationExtension.m │ ├── UIView+YHFrame.h │ ├── UIView+YHFrame.m │ ├── UIViewController+YHExtension.h │ ├── UIViewController+YHExtension.m │ ├── YHTextView.h │ └── YHTextView.m │ ├── ViewChain │ ├── YHBaseViewChainModel.h │ ├── YHBaseViewChainModel.m │ ├── YHButtonChainModel.h │ ├── YHButtonChainModel.m │ ├── YHImageViewChainModel.h │ ├── YHImageViewChainModel.m │ ├── YHLabelChainModel.h │ ├── YHLabelChainModel.m │ ├── YHScrollViewChainModel.h │ ├── YHScrollViewChainModel.m │ ├── YHTextFieldChainModel.h │ ├── YHTextFieldChainModel.m │ ├── YHTextViewChainModel.h │ ├── YHTextViewChainModel.m │ ├── YHViewChainModel.h │ └── YHViewChainModel.m │ ├── YHKit.h │ ├── YHMacro.h │ └── YYText Bug Fix │ ├── YYLabel+YHBugFix.h │ └── YYLabel+YHBugFix.m └── YHOCTool.podspec /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | # Mac OS X Finder and whatnot 6 | .DS_Store 7 | 8 | ## Build generated 9 | build/ 10 | DerivedData/ 11 | 12 | ## Various settings 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata/ 22 | 23 | ## Other 24 | *.moved-aside 25 | *.xcuserstate 26 | *.xccheckout 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | *.dSYM.zip 32 | *.dSYM 33 | 34 | #CocoaPods 35 | Pods/ 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 liujun 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /OCTool.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OCTool.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /OCTool.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /OCTool.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /OCTool.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | PreviewsEnabled 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /OCTool/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // OCTool 4 | // 5 | // Created by apple on 2020/4/15. 6 | // Copyright © 2020 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | @property (strong, nonatomic) UIWindow *window; 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /OCTool/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // OCTool 4 | // 5 | // Created by apple on 2020/4/15. 6 | // Copyright © 2020 yinhe. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /OCTool/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /OCTool/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /OCTool/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 | -------------------------------------------------------------------------------- /OCTool/Base.lproj/Main.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 | -------------------------------------------------------------------------------- /OCTool/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /OCTool/Test.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Test.swift 3 | // OCTool 4 | // 5 | // Created by apple on 2020/4/15. 6 | // Copyright © 2020 yinhe. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /OCTool/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // OCTool 4 | // 5 | // Created by apple on 2020/4/15. 6 | // Copyright © 2020 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /OCTool/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // OCTool 4 | // 5 | // Created by apple on 2020/4/15. 6 | // Copyright © 2020 yinhe. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "YHKit.h" 11 | 12 | @interface ViewController () 13 | 14 | @end 15 | 16 | @implementation ViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | // Do any additional setup after loading the view. 21 | } 22 | 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /OCTool/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // OCTool 4 | // 5 | // Created by apple on 2020/4/15. 6 | // Copyright © 2020 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | NSString * appDelegateClassName; 14 | @autoreleasepool { 15 | // Setup code that might create autoreleased objects goes here. 16 | appDelegateClassName = NSStringFromClass([AppDelegate class]); 17 | } 18 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 19 | } 20 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | platform :ios, '9.0' 3 | target 'OCTool' do 4 | use_frameworks! 5 | 6 | pod 'AFNetworking' 7 | pod 'Texture' 8 | pod 'SDWebImage' 9 | pod 'SDWebImageWebPCoder' 10 | pod 'YYText' 11 | pod 'MBProgressHUD' 12 | pod 'Masonry' 13 | pod 'FLAnimatedImage' 14 | 15 | # pod 'BMKLocationKit' 16 | end 17 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (4.0.0): 3 | - AFNetworking/NSURLSession (= 4.0.0) 4 | - AFNetworking/Reachability (= 4.0.0) 5 | - AFNetworking/Security (= 4.0.0) 6 | - AFNetworking/Serialization (= 4.0.0) 7 | - AFNetworking/UIKit (= 4.0.0) 8 | - AFNetworking/NSURLSession (4.0.0): 9 | - AFNetworking/Reachability 10 | - AFNetworking/Security 11 | - AFNetworking/Serialization 12 | - AFNetworking/Reachability (4.0.0) 13 | - AFNetworking/Security (4.0.0) 14 | - AFNetworking/Serialization (4.0.0) 15 | - AFNetworking/UIKit (4.0.0): 16 | - AFNetworking/NSURLSession 17 | - FLAnimatedImage (1.0.12) 18 | - libwebp (1.1.0): 19 | - libwebp/demux (= 1.1.0) 20 | - libwebp/mux (= 1.1.0) 21 | - libwebp/webp (= 1.1.0) 22 | - libwebp/demux (1.1.0): 23 | - libwebp/webp 24 | - libwebp/mux (1.1.0): 25 | - libwebp/demux 26 | - libwebp/webp (1.1.0) 27 | - Masonry (1.1.0) 28 | - MBProgressHUD (1.2.0) 29 | - PINCache (3.0.1-beta.6): 30 | - PINCache/Arc-exception-safe (= 3.0.1-beta.6) 31 | - PINCache/Core (= 3.0.1-beta.6) 32 | - PINCache/Arc-exception-safe (3.0.1-beta.6): 33 | - PINCache/Core 34 | - PINCache/Core (3.0.1-beta.6): 35 | - PINOperation (~> 1.1.0) 36 | - PINOperation (1.1.2) 37 | - PINRemoteImage/Core (3.0.0-beta.13): 38 | - PINOperation 39 | - PINRemoteImage/iOS (3.0.0-beta.13): 40 | - PINRemoteImage/Core 41 | - PINRemoteImage/PINCache (3.0.0-beta.13): 42 | - PINCache (= 3.0.1-beta.6) 43 | - PINRemoteImage/Core 44 | - SDWebImage (5.6.1): 45 | - SDWebImage/Core (= 5.6.1) 46 | - SDWebImage/Core (5.6.1) 47 | - SDWebImageWebPCoder (0.5.0): 48 | - libwebp (~> 1.0) 49 | - SDWebImage/Core (~> 5.5) 50 | - Texture (2.8.1): 51 | - Texture/AssetsLibrary (= 2.8.1) 52 | - Texture/Core (= 2.8.1) 53 | - Texture/MapKit (= 2.8.1) 54 | - Texture/Photos (= 2.8.1) 55 | - Texture/PINRemoteImage (= 2.8.1) 56 | - Texture/Video (= 2.8.1) 57 | - Texture/AssetsLibrary (2.8.1): 58 | - Texture/Core 59 | - Texture/Core (2.8.1) 60 | - Texture/MapKit (2.8.1): 61 | - Texture/Core 62 | - Texture/Photos (2.8.1): 63 | - Texture/Core 64 | - Texture/PINRemoteImage (2.8.1): 65 | - PINRemoteImage/iOS (= 3.0.0-beta.13) 66 | - PINRemoteImage/PINCache 67 | - Texture/Core 68 | - Texture/Video (2.8.1): 69 | - Texture/Core 70 | - YYText (1.0.7) 71 | 72 | DEPENDENCIES: 73 | - AFNetworking 74 | - FLAnimatedImage 75 | - Masonry 76 | - MBProgressHUD 77 | - SDWebImage 78 | - SDWebImageWebPCoder 79 | - Texture 80 | - YYText 81 | 82 | SPEC REPOS: 83 | trunk: 84 | - AFNetworking 85 | - FLAnimatedImage 86 | - libwebp 87 | - Masonry 88 | - MBProgressHUD 89 | - PINCache 90 | - PINOperation 91 | - PINRemoteImage 92 | - SDWebImage 93 | - SDWebImageWebPCoder 94 | - Texture 95 | - YYText 96 | 97 | SPEC CHECKSUMS: 98 | AFNetworking: d9fdf484a3c723ec3c558a41cc5754c7e845ee77 99 | FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 100 | libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3 101 | Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 102 | MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406 103 | PINCache: d195fdba255283f7e9900a55e3cced377f431f9b 104 | PINOperation: 24b774353ca248fcf87d67b2d61eef42087c125a 105 | PINRemoteImage: d6d51c5d2adda55f1ce30c96e850b6c4ebd2856a 106 | SDWebImage: 7edb9c3ea661e77a66661f7f044de8c1b55d1120 107 | SDWebImageWebPCoder: e7ae855f058e3dcae99696920b6a5d134e9dcddf 108 | Texture: 8ecf6984065a1e54f06bf97b349ecca28582acd7 109 | YYText: 5c461d709e24d55a182d1441c41dc639a18a4849 110 | 111 | PODFILE CHECKSUM: f48f28fe4e8a68a7101d45292a8df8f533882e3b 112 | 113 | COCOAPODS: 1.9.1 114 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > 个人开发工具,逐步迁移到[Swift](https://github.com/liujunliuhong/SwiftTool) 2 | 3 | # 导入方式 4 | 5 | `pod 'YHOCTool/Core', :git => "https://github.com/liujunliuhong/Kit.git"` 6 | -------------------------------------------------------------------------------- /Sources/Core/AddressBook/YHAddressBook.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHAddressBook.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/16. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "YHAdressBookModel.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | NS_CLASS_AVAILABLE_IOS(8_0) @interface YHAddressBook : NSObject 15 | 16 | // If not add 'NSContactsUsageDescription' key into info.plst, app will crash. 17 | // If access to contact data is already restricted or denied, the error is not nil. 18 | + (void)getOriginAdressBookWithCompletionBlock:(void(^_Nullable)(NSArray *_Nullable originModels, NSError *_Nullable error))completionBlock; 19 | 20 | // If not add 'NSContactsUsageDescription' key into info.plst, app will crash. 21 | // If access to contact data is already restricted or denied, the error is not nil. 22 | + (void)getOrderAdressBookWithCompletionBlock:(void(^_Nullable)(NSArray *> *_Nullable orderModels, NSArray *_Nullable sectionTitles, NSError *_Nullable error))completionBlock; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /Sources/Core/AddressBook/YHAdressBookModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHAdressBookModel.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/16. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | @interface YHAdressBookModel : NSObject 14 | 15 | // name. 16 | @property (nonatomic, copy) NSString *name; 17 | // phone. 18 | @property (nonatomic, copy) NSString *phone; 19 | // avatar. 20 | @property (nonatomic, strong, nullable) UIImage *headImage; 21 | 22 | @end 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Sources/Core/AddressBook/YHAdressBookModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHAdressBookModel.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/16. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import "YHAdressBookModel.h" 10 | 11 | @implementation YHAdressBookModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Sources/Core/Alert/YHAlertViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHAlertViewController.h 3 | // FrameDating 4 | // 5 | // Created by 银河 on 2019/6/2. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @class YHAlertViewController; 13 | typedef void (^YHAlertActionBlock)(int buttonIndex, UIAlertAction *action, YHAlertViewController *alertController); 14 | NS_CLASS_AVAILABLE_IOS(8_0) @interface YHAlertViewController : UIAlertController 15 | @property (nonatomic, copy, nullable) void(^didShowBlock)(void); 16 | @property (nonatomic, copy, nullable) void(^didDismissBlock)(void); 17 | @property (nonatomic, copy, readonly) YHAlertViewController *(^addDefaultActionTitle)(NSString *title); 18 | @property (nonatomic, copy, readonly) YHAlertViewController *(^addCancelActionTitle)(NSString *title); 19 | @property (nonatomic, copy, readonly) YHAlertViewController *(^addDestructiveActionTitle)(NSString *title); 20 | @end 21 | 22 | 23 | 24 | /** 25 | * 系统UIAlertController的简单封装,参考了JXTAlertController,相比JXTAlertController,去掉了很多个人觉得没有用的东西。 26 | */ 27 | @interface UIViewController (YHAlertViewController) 28 | 29 | 30 | /** 31 | 弹出alert的方法 32 | 当style为UIAlertControllerStyleActionSheet时,控制台会显示约束错误信息,即使用原生方法写,也是这样,暂时不知道什么原因 33 | 34 | @param title title 35 | @param message message 36 | @param style style 37 | @param actionProcessBlock 事件加工链 38 | @param didShowBlock 显示回调 39 | @param didDismissBlock 消失回调 40 | @param actionBlock 事件回调 41 | */ 42 | - (void)yh_showAlertWithTitle:(nullable NSString *)title 43 | message:(nullable NSString *)message 44 | style:(UIAlertControllerStyle)style 45 | actionProcessBlock:(void(^_Nullable)(YHAlertViewController *alertController))actionProcessBlock 46 | didShowBlock:(void(^_Nullable)(void))didShowBlock 47 | didDismissBlock:(void(^_Nullable)(void))didDismissBlock 48 | actionBlock:(nullable YHAlertActionBlock)actionBlock NS_AVAILABLE_IOS(8_0); 49 | 50 | @end 51 | 52 | NS_ASSUME_NONNULL_END 53 | -------------------------------------------------------------------------------- /Sources/Core/Alert/YHAlertViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHAlertViewController.m 3 | // FrameDating 4 | // 5 | // Created by 银河 on 2019/6/2. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHAlertViewController.h" 10 | 11 | @interface YHAlertModel : NSObject 12 | @property (nonatomic, copy) NSString *title; 13 | @property (nonatomic, assign) UIAlertActionStyle style; 14 | @end 15 | 16 | @implementation YHAlertModel 17 | - (instancetype)init 18 | { 19 | self = [super init]; 20 | if (self) { 21 | self.title = @""; 22 | self.style = UIAlertActionStyleDefault; 23 | } 24 | return self; 25 | } 26 | @end 27 | 28 | 29 | @interface YHAlertViewController () 30 | @property (nonatomic, strong) NSMutableArray *alertActions; 31 | @property (nonatomic, copy, readonly) void (^alertActionBlock)(YHAlertActionBlock actionBlock); 32 | @end 33 | 34 | @implementation YHAlertViewController 35 | 36 | + (instancetype)alertControllerWithTitle:(NSString *)title message:(NSString *)message preferredStyle:(UIAlertControllerStyle)preferredStyle{ 37 | YHAlertViewController *alertController = [super alertControllerWithTitle:title message:message preferredStyle:preferredStyle]; 38 | if (alertController) { 39 | alertController.view.translatesAutoresizingMaskIntoConstraints = NO; 40 | alertController.alertActions = [NSMutableArray array]; 41 | } 42 | return alertController; 43 | } 44 | 45 | - (void)viewDidDisappear:(BOOL)animated{ 46 | [super viewDidDisappear:animated]; 47 | if (self.didDismissBlock) { 48 | self.didDismissBlock(); 49 | } 50 | } 51 | 52 | - (void)viewDidAppear:(BOOL)animated{ 53 | [super viewDidAppear:animated]; 54 | if (self.didShowBlock) { 55 | self.didShowBlock(); 56 | } 57 | } 58 | 59 | - (YHAlertViewController * _Nonnull (^)(NSString * _Nonnull))addDefaultActionTitle{ 60 | __weak typeof(self) weakSelf = self; 61 | return ^YHAlertViewController *(NSString *title) { 62 | YHAlertModel *model = [[YHAlertModel alloc] init]; 63 | model.title = title; 64 | model.style = UIAlertActionStyleDefault; 65 | [weakSelf.alertActions addObject:model]; 66 | return weakSelf; 67 | }; 68 | } 69 | 70 | - (YHAlertViewController * _Nonnull (^)(NSString * _Nonnull))addCancelActionTitle{ 71 | __weak typeof(self) weakSelf = self; 72 | return ^YHAlertViewController *(NSString *title) { 73 | YHAlertModel *model = [[YHAlertModel alloc] init]; 74 | model.title = title; 75 | model.style = UIAlertActionStyleCancel; 76 | [weakSelf.alertActions addObject:model]; 77 | return weakSelf; 78 | }; 79 | } 80 | 81 | - (YHAlertViewController * _Nonnull (^)(NSString * _Nonnull))addDestructiveActionTitle{ 82 | __weak typeof(self) weakSelf = self; 83 | return ^YHAlertViewController *(NSString *title) { 84 | YHAlertModel *model = [[YHAlertModel alloc] init]; 85 | model.title = title; 86 | model.style = UIAlertActionStyleDestructive; 87 | [weakSelf.alertActions addObject:model]; 88 | return weakSelf; 89 | }; 90 | } 91 | 92 | - (void (^)(YHAlertActionBlock))alertActionBlock{ 93 | __weak typeof(self) weakSelf = self; 94 | return ^(YHAlertActionBlock actionBlock) { 95 | [weakSelf.alertActions enumerateObjectsUsingBlock:^(YHAlertModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 96 | UIAlertAction *action = [UIAlertAction actionWithTitle:obj.title style:obj.style handler:^(UIAlertAction * _Nonnull action) { 97 | __strong typeof(weakSelf) strongSelf = weakSelf; 98 | if (actionBlock) { 99 | actionBlock((int)idx, action, strongSelf); 100 | } 101 | }]; 102 | [weakSelf addAction:action]; 103 | }]; 104 | }; 105 | } 106 | 107 | @end 108 | 109 | @implementation UIViewController (YHAlertViewController) 110 | - (void)yh_showAlertWithTitle:(NSString *)title 111 | message:(NSString *)message 112 | style:(UIAlertControllerStyle)style 113 | actionProcessBlock:(void (^)(YHAlertViewController * _Nonnull))actionProcessBlock 114 | didShowBlock:(void (^)(void))didShowBlock 115 | didDismissBlock:(void (^)(void))didDismissBlock actionBlock:(YHAlertActionBlock)actionBlock{ 116 | YHAlertViewController *alertController = [YHAlertViewController alertControllerWithTitle:title message:message preferredStyle:style]; 117 | if (!alertController) { 118 | return; 119 | } 120 | if (!actionProcessBlock) { 121 | return; 122 | } 123 | 124 | actionProcessBlock(alertController); 125 | alertController.alertActionBlock(actionBlock); 126 | 127 | alertController.didShowBlock = didShowBlock; 128 | alertController.didDismissBlock = didDismissBlock; 129 | 130 | alertController.popoverPresentationController.sourceView = self.view; 131 | alertController.popoverPresentationController.sourceRect = CGRectMake(0,0,1.0,1.0); 132 | 133 | [self presentViewController:alertController animated:YES completion:nil]; 134 | } 135 | @end 136 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/ASCollectionNode+YHASReload.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASCollectionNode+YHASReload.h 3 | // FrameDating 4 | // 5 | // Created by 银河 on 2019/6/1. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | /** 14 | * ASCollectionNode刷新闪烁的解决办法 15 | */ 16 | @interface ASCollectionNode (YHASReload) 17 | 18 | - (void)yh_reloadData; 19 | 20 | - (void)yh_nodeBlockForRowWithCellNode:(ASCellNode *)cellNode indexPath:(NSIndexPath *)indexPath; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/ASCollectionNode+YHASReload.m: -------------------------------------------------------------------------------- 1 | // 2 | // ASCollectionNode+YHASReload.m 3 | // FrameDating 4 | // 5 | // Created by 银河 on 2019/6/1. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "ASCollectionNode+YHASReload.h" 10 | #import 11 | 12 | const char _yh_reload_path_key__; 13 | 14 | @interface ASCollectionNode () 15 | @property (nonatomic, strong) NSArray *yh_reloadPaths; 16 | @end 17 | 18 | 19 | @implementation ASCollectionNode (YHASReload) 20 | - (void)setYh_reloadPaths:(NSArray *)yh_reloadPaths{ 21 | objc_setAssociatedObject(self, &_yh_reload_path_key__, yh_reloadPaths, OBJC_ASSOCIATION_COPY_NONATOMIC); 22 | } 23 | 24 | - (NSArray *)yh_reloadPaths{ 25 | return objc_getAssociatedObject(self, &_yh_reload_path_key__); 26 | } 27 | 28 | - (void)yh_reloadData{ 29 | self.yh_reloadPaths = self.self.indexPathsForVisibleItems; 30 | [self reloadData]; 31 | } 32 | 33 | - (void)yh_nodeBlockForRowWithCellNode:(ASCellNode *)cellNode indexPath:(NSIndexPath *)indexPath{ 34 | if ([self.yh_reloadPaths containsObject:indexPath]) { 35 | cellNode.neverShowPlaceholders = YES; 36 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 37 | cellNode.neverShowPlaceholders = NO; 38 | }); 39 | } 40 | else { 41 | cellNode.neverShowPlaceholders = NO; 42 | } 43 | } 44 | @end 45 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/ASControlNode+YHAddTap.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASControlNode+YHAddTap.h 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/12. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ASControlNode (YHAddTap) 14 | 15 | // ASControlNode点击事件封装 16 | - (void)yh_addControllActionWithBlock:(void(^_Nullable)( __kindof ASControlNode * sender))actionBlock; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/ASControlNode+YHAddTap.m: -------------------------------------------------------------------------------- 1 | // 2 | // ASControlNode+YHAddTap.m 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/12. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "ASControlNode+YHAddTap.h" 10 | #import 11 | 12 | static char actionKey; 13 | typedef void(^__actionBlock)(__kindof ASControlNode *sender); 14 | 15 | @implementation ASControlNode (YHAddTap) 16 | - (void)yh_addControllActionWithBlock:(void (^)(__kindof ASControlNode * _Nonnull))actionBlock{ 17 | objc_setAssociatedObject(self, &actionKey, actionBlock, OBJC_ASSOCIATION_COPY); 18 | [self addTarget:self action:@selector(action) forControlEvents:ASControlNodeEventTouchUpInside]; 19 | } 20 | 21 | - (void)action{ 22 | __actionBlock block = objc_getAssociatedObject(self, &actionKey); 23 | if (block) { 24 | block(self); 25 | } 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/ASDisplayNode+YHAddTap.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASDisplayNode+YHAddTap.h 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/12. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ASDisplayNode (YHAddTap) 14 | 15 | // ASDisplayNode触摸事件 16 | - (void)yh_addTapWithActionBlock:(void(^_Nullable)(void))actionBlock; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/ASDisplayNode+YHAddTap.m: -------------------------------------------------------------------------------- 1 | // 2 | // ASDisplayNode+YHAddTap.m 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/12. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "ASDisplayNode+YHAddTap.h" 10 | #import 11 | 12 | static char actionKey; 13 | typedef void(^__actionBlock)(void); 14 | 15 | @implementation ASDisplayNode (YHAddTap) 16 | 17 | - (void)yh_addTapWithActionBlock:(void (^)(void))actionBlock{ 18 | objc_setAssociatedObject(self, &actionKey, actionBlock, OBJC_ASSOCIATION_COPY); 19 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(action)]; 20 | [self.view addGestureRecognizer:tap]; 21 | } 22 | 23 | - (void)action{ 24 | __actionBlock block = objc_getAssociatedObject(self, &actionKey); 25 | if (block) { 26 | block(); 27 | } 28 | //objc_setAssociatedObject(self, &actionKey, nil, OBJC_ASSOCIATION_COPY); 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/ASTableNode+YHASReload.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASTableNode+YHASReload.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/3/27. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | /** 14 | * ASTableNode刷新闪烁的解决办法 15 | */ 16 | @interface ASTableNode (YHASReload) 17 | 18 | - (void)yh_reloadData; 19 | 20 | - (void)yh_nodeBlockForRowWithCellNode:(ASCellNode *)cellNode indexPath:(NSIndexPath *)indexPath; 21 | 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/ASTableNode+YHASReload.m: -------------------------------------------------------------------------------- 1 | // 2 | // ASTableNode+YHASReload.m 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/3/27. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "ASTableNode+YHASReload.h" 10 | #import 11 | 12 | const char _yh_reload_path_key; 13 | 14 | @interface ASTableNode() 15 | @property (nonatomic, strong) NSArray *yh_reloadPaths; 16 | @end 17 | 18 | @implementation ASTableNode (YHASReload) 19 | 20 | - (void)setYh_reloadPaths:(NSArray *)yh_reloadPaths{ 21 | objc_setAssociatedObject(self, &_yh_reload_path_key, yh_reloadPaths, OBJC_ASSOCIATION_COPY_NONATOMIC); 22 | } 23 | 24 | - (NSArray *)yh_reloadPaths{ 25 | return objc_getAssociatedObject(self, &_yh_reload_path_key); 26 | } 27 | 28 | - (void)yh_reloadData{ 29 | self.yh_reloadPaths = self.indexPathsForVisibleRows; 30 | [self reloadData]; 31 | } 32 | 33 | - (void)yh_nodeBlockForRowWithCellNode:(ASCellNode *)cellNode indexPath:(NSIndexPath *)indexPath{ 34 | __weak typeof(cellNode) weakCellNode = cellNode; 35 | if ([self.yh_reloadPaths containsObject:indexPath]) { 36 | cellNode.neverShowPlaceholders = YES; 37 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 38 | weakCellNode.neverShowPlaceholders = NO; 39 | }); 40 | } 41 | else { 42 | cellNode.neverShowPlaceholders = NO; 43 | } 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/ASTextNode+YHHighlight.h: -------------------------------------------------------------------------------- 1 | // 2 | // ASTextNode+YHHighlight.h 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/14. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ASTextNode (YHHighlight) 14 | 15 | - (void)yh_as_setHighlightColor:(UIColor *)highlightColor range:(NSRange)range attributeName:(NSString *)attributeName; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/ASTextNode+YHHighlight.m: -------------------------------------------------------------------------------- 1 | // 2 | // ASTextNode+YHHighlight.m 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/14. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "ASTextNode+YHHighlight.h" 10 | #import 11 | 12 | const char _highlight_properties_key; 13 | 14 | @implementation ASTextNode (YHHighlight) 15 | + (void)load{ 16 | Method originMethod = class_getInstanceMethod(self, NSSelectorFromString(@"_setHighlightRange:forAttributeName:value:animated:")); 17 | 18 | Method myMethod = class_getInstanceMethod(self, NSSelectorFromString(@"_yh_setHighlightRange:forAttributeName:value:animated:")); 19 | method_exchangeImplementations(originMethod, myMethod); 20 | } 21 | - (void)yh_as_setHighlightColor:(UIColor *)highlightColor range:(NSRange)range attributeName:(nonnull NSString *)attributeName{ 22 | 23 | NSMutableDictionary *properties = objc_getAssociatedObject(self, &_highlight_properties_key); 24 | if (!properties) { 25 | properties = [NSMutableDictionary dictionary]; 26 | } 27 | [properties setObject:@[[NSValue valueWithRange:range], highlightColor] forKey:attributeName]; 28 | objc_setAssociatedObject(self, &_highlight_properties_key, properties, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 29 | } 30 | 31 | - (void)_yh_setHighlightRange:(NSRange)highlightRange forAttributeName:(NSString *)highlightedAttributeName value:(id)highlightedAttributeValue animated:(BOOL)animated{ 32 | [self _yh_setHighlightRange:highlightRange forAttributeName:highlightedAttributeName value:highlightedAttributeValue animated:animated]; 33 | 34 | NSMutableDictionary *properties = objc_getAssociatedObject(self, &_highlight_properties_key); 35 | if (properties) { 36 | if ([properties.allKeys containsObject:highlightedAttributeName]) { 37 | NSArray *values = properties[highlightedAttributeName]; 38 | NSRange range = [values[0] rangeValue]; 39 | UIColor *color = values[1]; 40 | if (NSEqualRanges(range, highlightRange)) { 41 | ASHighlightOverlayLayer *highlightOverlayLayer = [self valueForKeyPath:@"_activeHighlightLayer"]; 42 | if (highlightOverlayLayer) { 43 | highlightOverlayLayer.highlightColor = color.CGColor; 44 | highlightOverlayLayer.opacity = 1; 45 | } 46 | } 47 | } 48 | } 49 | } 50 | 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/YHASCollectionLayoutDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHASCollectionLayoutDelegate.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/4/24. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | /** 14 | * ASCollectionNode瀑布流配置 15 | * 目前这儿有个bug,只支持垂直方向的滚动,水平方向的滚动暂时不支持 16 | */ 17 | @interface YHASCollectionLayoutDelegate : NSObject 18 | 19 | /** 20 | * 无Header和Footer的配置方法 21 | */ 22 | - (instancetype)initWithNumberOfColumns:(NSInteger)numberOfColumns 23 | columnSpacing:(CGFloat)columnSpacing 24 | interItemSpacing:(CGFloat)interItemSpacing 25 | sectionInsets:(UIEdgeInsets)sectionInsets 26 | scrollDirection:(ASScrollDirection)scrollDirection; 27 | 28 | /** 29 | * 有Header或者Footer的配置方法 30 | * isHeaderWidthBaseSectionInsets:Header的宽度是否根据SctionInsets来动态调整,默认NO 31 | * isFooterWidthBaseSectionInsets:Footer的宽度是否根据SctionInsets来动态调整,默认NO 32 | * bottomOffset:CollectionNode底部偏移量,默认大于0,如果小于0,框架内部自动设置为0 33 | */ 34 | - (instancetype)initWithNumberOfColumns:(NSInteger)numberOfColumns 35 | columnSpacing:(CGFloat)columnSpacing 36 | interItemSpacing:(CGFloat)interItemSpacing 37 | sectionInsets:(UIEdgeInsets)sectionInsets 38 | isHeaderWidthBaseSectionInsets:(BOOL)isHeaderWidthBaseSectionInsets 39 | isFooterWidthBaseSectionInsets:(BOOL)isFooterWidthBaseSectionInsets 40 | bottomOffset:(CGFloat)bottomOffset 41 | scrollDirection:(ASScrollDirection)scrollDirection; 42 | 43 | - (instancetype)init NS_UNAVAILABLE; 44 | 45 | @end 46 | 47 | NS_ASSUME_NONNULL_END 48 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/YHASEnlargeEdgeControlNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHASEnlargeEdgeControlNode.h 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/12. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface YHASEnlargeEdgeControlNode : ASButtonNode 14 | 15 | 16 | /** 17 | 扩大点击区域(注意:实在父Node的基础上的,如果父node比较小,比如和YHASEnlargeEdgeControlNode相等,那么设置这个是没有效果的) 18 | 19 | @param top 向上的偏移量 20 | @param right 向右的偏移量 21 | @param bottom 向下的偏移量 22 | @param left 向左的偏移量 23 | */ 24 | - (void)yh_setEnlargeEdgeWithTop:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom left:(CGFloat)left; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/YHASEnlargeEdgeControlNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHASEnlargeEdgeControlNode.m 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/12. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHASEnlargeEdgeControlNode.h" 10 | #import 11 | 12 | static char topNameKey; 13 | static char rightNameKey; 14 | static char bottomNameKey; 15 | static char leftNameKey; 16 | 17 | @implementation YHASEnlargeEdgeControlNode 18 | 19 | - (void)yh_setEnlargeEdgeWithTop:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom left:(CGFloat)left{ 20 | objc_setAssociatedObject(self, &topNameKey, [NSNumber numberWithFloat:top], OBJC_ASSOCIATION_COPY_NONATOMIC); 21 | objc_setAssociatedObject(self, &rightNameKey, [NSNumber numberWithFloat:right], OBJC_ASSOCIATION_COPY_NONATOMIC); 22 | objc_setAssociatedObject(self, &bottomNameKey, [NSNumber numberWithFloat:bottom], OBJC_ASSOCIATION_COPY_NONATOMIC); 23 | objc_setAssociatedObject(self, &leftNameKey, [NSNumber numberWithFloat:left], OBJC_ASSOCIATION_COPY_NONATOMIC); 24 | } 25 | 26 | - (CGRect)enlargedRect { 27 | NSNumber *topEdge = objc_getAssociatedObject(self, &topNameKey); 28 | NSNumber *rightEdge = objc_getAssociatedObject(self, &rightNameKey); 29 | NSNumber *bottomEdge = objc_getAssociatedObject(self, &bottomNameKey); 30 | NSNumber *leftEdge = objc_getAssociatedObject(self, &leftNameKey); 31 | if (topEdge && rightEdge && bottomEdge && leftEdge) { 32 | return CGRectMake(self.bounds.origin.x - leftEdge.floatValue, 33 | self.bounds.origin.y - topEdge.floatValue, 34 | self.bounds.size.width + leftEdge.floatValue + rightEdge.floatValue, 35 | self.bounds.size.height + topEdge.floatValue + bottomEdge.floatValue); 36 | } else { 37 | return self.bounds; 38 | } 39 | } 40 | 41 | 42 | - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{ 43 | CGRect rect = [self enlargedRect]; 44 | return CGRectContainsPoint(rect, point); 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Sources/Core/AsyncDisplayKit/YHASNetworkImageNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHASNetworkImageNode.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/3/27. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | /** 15 | * 解决ASNetworkImageNode闪烁的问题 16 | */ 17 | @interface YHASNetworkImageNode : ASControlNode 18 | @property (nonatomic, strong, readonly) SDAnimatedImageView *animatedImageView; 19 | 20 | @property (nonatomic, strong, nullable) UIImage *placeholdeImage; // 请在设置URL之前设置placeholdeImage 21 | @property (nonatomic, copy) NSString *URL; 22 | @property (nonatomic, assign) UIViewContentMode contentMode; 23 | - (void)setURL:(NSString *)URL placeholdeImage:(nullable UIImage *)placeholdeImage contentMode:(UIViewContentMode)contentMode; 24 | - (void)setImage:(nullable UIImage *)image contentMode:(UIViewContentMode)contentMode; 25 | 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetion.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetion.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "YHAuthorizetionCamera.h" 11 | #import "YHAuthorizetionPhotos.h" 12 | #import "YHAuthorizetionContacts.h" 13 | #import "YHAuthorizetionMicrophone.h" 14 | #import "YHAuthorizetionCalendar.h" 15 | #import "YHAuthorizetionReminder.h" 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | typedef NS_ENUM(NSUInteger, YHAuthorizetionType) { 20 | YHAuthorizetionType_Camera, // Camera NSCameraUsageDescription 21 | YHAuthorizetionType_Photos, // Photos NSPhotoLibraryUsageDescription NSPhotoLibraryAddUsageDescription 22 | YHAuthorizetionType_Contacts, // Contacts NSContactsUsageDescription 23 | YHAuthorizetionType_Microphone, // Microphone NSMicrophoneUsageDescription 24 | YHAuthorizetionType_Calendar, // Calendar NSCalendarsUsageDescription 25 | YHAuthorizetionType_Reminder, // Reminder NSRemindersUsageDescription 26 | }; 27 | 28 | 29 | typedef NS_ENUM(NSUInteger, YHNotificationAuthorizationType) { 30 | YHNotificationAuthorizationType_Authorization, // 允许通知 31 | YHNotificationAuthorizationType_Denied, // 拒绝通知 32 | YHNotificationAuthorizationType_NotDetermined, // 还没有做决定(iOS 10之后才有) 33 | }; 34 | 35 | 36 | NS_CLASS_AVAILABLE_IOS(8_0) @interface YHAuthorizetion : NSObject 37 | 38 | // Determine whether authorization is currently available. 39 | + (BOOL)isAuthorizedWithType:(YHAuthorizetionType)type; 40 | 41 | // Request authorization. 42 | + (void)requestAuthorizetionWithType:(YHAuthorizetionType)type completion:(void(^_Nullable)(BOOL granted, BOOL isFirst))completion; 43 | 44 | 45 | /** 46 | // Check whether turned on push permission. 47 | 有些app对于没有打开通知,会有一个弹出框提示,提示去打开通知。调用此方法,就会获取当前应用的通知打开状态。不过,这儿有一点需要注意,一般第一次安装app时,都会弹出是否允许通知的弹出框,这是一个延迟事件,而这个方法是一个即时事件,因此,就会有个现象,调用此方法会返回denied或者NotDetermined状态,然而此时却正好是用户选择的时候。因此有种做法就是,可以在沙盒里面设置一个key,用于记录用户打开app(完全杀死进程,再打开)的次数,当打开次数为1的时候,不调用此方法;当大于1的时候,再调用此方法 48 | 兼容iOS 10之下以及iOS 10之后 49 | */ 50 | + (void)checkNotificationAuthorizationWithResultBlock:(void(^_Nullable)(YHNotificationAuthorizationType authorizationType))resultBlock NS_CLASS_AVAILABLE_IOS(8_0); 51 | 52 | @end 53 | NS_ASSUME_NONNULL_END 54 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetion.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetion.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import "YHAuthorizetion.h" 10 | 11 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 12 | #import 13 | #endif 14 | 15 | @implementation YHAuthorizetion 16 | 17 | // Determine whether authorization is currently available. 18 | + (BOOL)isAuthorizedWithType:(YHAuthorizetionType)type{ 19 | switch (type) { 20 | case YHAuthorizetionType_Camera: 21 | { 22 | return [YHAuthorizetionCamera isAuthorized]; 23 | } 24 | break; 25 | case YHAuthorizetionType_Photos: 26 | { 27 | return [YHAuthorizetionPhotos isAuthorized]; 28 | } 29 | break; 30 | case YHAuthorizetionType_Contacts: 31 | { 32 | return [YHAuthorizetionContacts isAuthorized]; 33 | } 34 | break; 35 | case YHAuthorizetionType_Microphone: 36 | { 37 | return [YHAuthorizetionMicrophone isAuthorized]; 38 | } 39 | break; 40 | case YHAuthorizetionType_Calendar: 41 | { 42 | return [YHAuthorizetionCalendar isAuthorized]; 43 | } 44 | break; 45 | case YHAuthorizetionType_Reminder: 46 | { 47 | return [YHAuthorizetionReminder isAuthorized]; 48 | } 49 | break; 50 | default: 51 | { 52 | return NO; 53 | } 54 | break; 55 | } 56 | } 57 | 58 | // Request authorization. 59 | + (void)requestAuthorizetionWithType:(YHAuthorizetionType)type completion:(void (^)(BOOL, BOOL))completion{ 60 | switch (type) { 61 | case YHAuthorizetionType_Camera: 62 | { 63 | [YHAuthorizetionCamera requestAuthorizetionWithCompletion:completion]; 64 | } 65 | break; 66 | case YHAuthorizetionType_Photos: 67 | { 68 | [YHAuthorizetionPhotos requestAuthorizetionWithCompletion:completion]; 69 | } 70 | break; 71 | case YHAuthorizetionType_Contacts: 72 | { 73 | [YHAuthorizetionContacts requestAuthorizetionWithCompletion:completion]; 74 | } 75 | break; 76 | case YHAuthorizetionType_Microphone: 77 | { 78 | [YHAuthorizetionMicrophone requestAuthorizetionWithCompletion:completion]; 79 | } 80 | break; 81 | case YHAuthorizetionType_Calendar: 82 | { 83 | [YHAuthorizetionCalendar requestAuthorizetionWithCompletion:completion]; 84 | } 85 | break; 86 | case YHAuthorizetionType_Reminder: 87 | { 88 | [YHAuthorizetionReminder requestAuthorizetionWithCompletion:completion]; 89 | } 90 | break; 91 | default: 92 | break; 93 | } 94 | } 95 | 96 | // Check whether turned on push permission. 97 | + (void)checkNotificationAuthorizationWithResultBlock:(void (^)(YHNotificationAuthorizationType))resultBlock{ 98 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 99 | if (@available(iOS 10.0, *)) { 100 | UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; 101 | [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { 102 | switch (settings.authorizationStatus) { 103 | case UNAuthorizationStatusAuthorized: 104 | { 105 | resultBlock ? resultBlock(YHNotificationAuthorizationType_Authorization) : nil; 106 | } 107 | break; 108 | case UNAuthorizationStatusDenied: 109 | { 110 | resultBlock ? resultBlock(YHNotificationAuthorizationType_Denied) : nil; 111 | } 112 | break; 113 | case UNAuthorizationStatusNotDetermined: 114 | { 115 | resultBlock ? resultBlock(YHNotificationAuthorizationType_NotDetermined) : nil; 116 | } 117 | break; 118 | default: 119 | break; 120 | } 121 | }]; 122 | } 123 | #else 124 | UIUserNotificationSettings *settings = [UIApplication sharedApplication].currentUserNotificationSettings; 125 | if (settings.types == UIUserNotificationTypeNone) { 126 | resultBlock ? resultBlock(YHNotificationAuthorizationType_Denied) : nil; 127 | } else { 128 | resultBlock ? resultBlock(YHNotificationAuthorizationType_Authorization) : nil; 129 | } 130 | #endif 131 | } 132 | 133 | 134 | @end 135 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionCalendar.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionCalendar.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | /** 14 | * the calendar authorizetion. 15 | */ 16 | @interface YHAuthorizetionCalendar : NSObject 17 | 18 | // Determine whether authorization is currently available. 19 | + (BOOL)isAuthorized; 20 | 21 | // Request calendar authorizetion. 22 | + (void)requestAuthorizetionWithCompletion:(void(^_Nullable)(BOOL granted, BOOL isFirst))completion; 23 | 24 | @end 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionCalendar.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionCalendar.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import "YHAuthorizetionCalendar.h" 10 | 11 | @implementation YHAuthorizetionCalendar 12 | 13 | // Determine whether authorization is currently available. 14 | + (BOOL)isAuthorized{ 15 | EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent]; 16 | return status == EKAuthorizationStatusAuthorized; 17 | } 18 | 19 | // Request calendar authorizetion. 20 | + (void)requestAuthorizetionWithCompletion:(void (^)(BOOL, BOOL))completion{ 21 | EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent]; 22 | switch (status) { 23 | case EKAuthorizationStatusAuthorized: 24 | { 25 | completion ? completion(YES, NO) : nil; 26 | } 27 | break; 28 | case EKAuthorizationStatusDenied: 29 | case EKAuthorizationStatusRestricted: 30 | { 31 | completion ? completion(NO, NO) : nil; 32 | } 33 | break; 34 | case EKAuthorizationStatusNotDetermined: 35 | { 36 | [[[EKEventStore alloc] init] requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError * _Nullable error) { 37 | dispatch_async(dispatch_get_main_queue(), ^{ 38 | completion ? completion(granted, YES) : nil; 39 | }); 40 | }]; 41 | } 42 | break; 43 | default: 44 | break; 45 | } 46 | } 47 | 48 | 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionCamera.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionCamera.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | /** 14 | * the camera authorizetion. 15 | */ 16 | NS_CLASS_AVAILABLE_IOS(8_0) @interface YHAuthorizetionCamera : NSObject 17 | 18 | // Determine whether authorization is currently available. 19 | + (BOOL)isAuthorized; 20 | 21 | // Request camera authorizetion. 22 | + (void)requestAuthorizetionWithCompletion:(void(^_Nullable)(BOOL granted, BOOL isFirst))completion; 23 | 24 | @end 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionCamera.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionCamera.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import "YHAuthorizetionCamera.h" 10 | 11 | @implementation YHAuthorizetionCamera 12 | 13 | // Determine whether authorization is currently available. 14 | + (BOOL)isAuthorized{ 15 | AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; 16 | return status == AVAuthorizationStatusAuthorized; 17 | } 18 | 19 | // Request camera authorizetion. 20 | + (void)requestAuthorizetionWithCompletion:(void (^)(BOOL, BOOL))completion{ 21 | AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; 22 | switch (status) { 23 | case AVAuthorizationStatusAuthorized: 24 | { 25 | completion ? completion(YES, NO) : nil; 26 | } 27 | break; 28 | case AVAuthorizationStatusDenied: 29 | case AVAuthorizationStatusRestricted: 30 | { 31 | completion ? completion(NO, NO) : nil; 32 | } 33 | break; 34 | case AVAuthorizationStatusNotDetermined: 35 | { 36 | [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { 37 | dispatch_async(dispatch_get_main_queue(), ^{ 38 | completion ? completion(granted, YES) : nil; 39 | }); 40 | }]; 41 | } 42 | break; 43 | default: 44 | break; 45 | } 46 | } 47 | 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionContacts.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionContacts.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 11 | #import 12 | #else 13 | #import 14 | #endif 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | /** 18 | * the contacts authorizetion. 19 | */ 20 | NS_CLASS_AVAILABLE_IOS(8_0) @interface YHAuthorizetionContacts : NSObject 21 | 22 | // Determine whether authorization is currently available. 23 | + (BOOL)isAuthorized; 24 | 25 | // Request contacts authorizetion. 26 | + (void)requestAuthorizetionWithCompletion:(void(^_Nullable)(BOOL granted, BOOL isFirst))completion; 27 | 28 | @end 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionContacts.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionContacts.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import "YHAuthorizetionContacts.h" 10 | 11 | @implementation YHAuthorizetionContacts 12 | 13 | // Determine whether authorization is currently available. 14 | + (BOOL)isAuthorized{ 15 | BOOL res = NO; 16 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 17 | if (@available(iOS 9.0, *)) { 18 | CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]; 19 | res = status == CNAuthorizationStatusAuthorized; 20 | } 21 | #else 22 | ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus(); 23 | res = status == kABAuthorizationStatusAuthorized; 24 | #endif 25 | return res; 26 | } 27 | 28 | // Request contacts authorizetion. 29 | + (void)requestAuthorizetionWithCompletion:(void (^)(BOOL, BOOL))completion{ 30 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 31 | if (@available(iOS 9.0, *)) { 32 | CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]; 33 | switch (status) { 34 | case CNAuthorizationStatusAuthorized: 35 | { 36 | completion ? completion(YES, NO) : nil; 37 | } 38 | break; 39 | case CNAuthorizationStatusDenied: 40 | case CNAuthorizationStatusRestricted: 41 | { 42 | completion ? completion(NO, NO) : nil; 43 | } 44 | break; 45 | case CNAuthorizationStatusNotDetermined: 46 | { 47 | [[[CNContactStore alloc] init] requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { 48 | dispatch_async(dispatch_get_main_queue(), ^{ 49 | completion ? completion(granted, YES) : nil; 50 | }); 51 | }]; 52 | } 53 | break; 54 | default: 55 | break; 56 | } 57 | } 58 | #else 59 | ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus(); 60 | switch (status) { 61 | case kABAuthorizationStatusAuthorized: 62 | { 63 | completion ? completion(YES, NO) : nil; 64 | } 65 | break; 66 | case kABAuthorizationStatusDenied: 67 | case kABAuthorizationStatusRestricted: 68 | { 69 | completion ? completion(NO, NO) : nil; 70 | } 71 | break; 72 | case kABAuthorizationStatusNotDetermined: 73 | { 74 | ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); 75 | ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { 76 | dispatch_async(dispatch_get_main_queue(), ^{ 77 | completion ? completion(granted, YES) : nil; 78 | }); 79 | }); 80 | } 81 | break; 82 | default: 83 | break; 84 | } 85 | #endif 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionMicrophone.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionMicrophone.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | /** 14 | * the microphone authorizetion. 15 | */ 16 | NS_CLASS_AVAILABLE_IOS(8_0) @interface YHAuthorizetionMicrophone : NSObject 17 | 18 | // Determine whether authorization is currently available. 19 | + (BOOL)isAuthorized; 20 | 21 | // Request microphone authorizetion. 22 | + (void)requestAuthorizetionWithCompletion:(void(^_Nullable)(BOOL granted, BOOL isFirst))completion; 23 | 24 | @end 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionMicrophone.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionMicrophone.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import "YHAuthorizetionMicrophone.h" 10 | 11 | @implementation YHAuthorizetionMicrophone 12 | 13 | // Determine whether authorization is currently available. 14 | + (BOOL)isAuthorized{ 15 | AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio]; 16 | return status == AVAuthorizationStatusAuthorized; 17 | } 18 | 19 | // Request microphone authorizetion. 20 | + (void)requestAuthorizetionWithCompletion:(void (^)(BOOL, BOOL))completion{ 21 | AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio]; 22 | switch (status) { 23 | case AVAuthorizationStatusAuthorized: 24 | { 25 | completion ? completion(YES, NO) : nil; 26 | } 27 | break; 28 | case AVAuthorizationStatusDenied: 29 | case AVAuthorizationStatusRestricted: 30 | { 31 | completion ? completion(NO, NO) : nil; 32 | } 33 | break; 34 | case AVAuthorizationStatusNotDetermined: 35 | { 36 | [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) { 37 | dispatch_async(dispatch_get_main_queue(), ^{ 38 | completion ? completion(granted, YES) : nil; 39 | }); 40 | }]; 41 | } 42 | break; 43 | default: 44 | break; 45 | } 46 | } 47 | 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionPhotos.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionPhotos.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | /** 14 | * the photo authorizetion. 15 | */ 16 | NS_CLASS_AVAILABLE_IOS(8_0) @interface YHAuthorizetionPhotos : NSObject 17 | 18 | // Determine whether authorization is currently available. 19 | + (BOOL)isAuthorized; 20 | 21 | // Request photo authorizetion. 22 | + (void)requestAuthorizetionWithCompletion:(void(^_Nullable)(BOOL granted, BOOL isFirst))completion; 23 | 24 | @end 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionPhotos.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionPhotos.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import "YHAuthorizetionPhotos.h" 10 | 11 | @implementation YHAuthorizetionPhotos 12 | 13 | // Determine whether authorization is currently available. 14 | + (BOOL)isAuthorized{ 15 | PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus]; 16 | return status == PHAuthorizationStatusAuthorized; 17 | } 18 | 19 | // Request photo authorizetion. 20 | + (void)requestAuthorizetionWithCompletion:(void (^)(BOOL, BOOL))completion{ 21 | PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus]; 22 | switch (status) { 23 | case PHAuthorizationStatusAuthorized: 24 | { 25 | completion ? completion(YES, NO) : nil; 26 | } 27 | break; 28 | case PHAuthorizationStatusRestricted: 29 | case PHAuthorizationStatusDenied: 30 | { 31 | completion ? completion(NO, NO) : nil; 32 | } 33 | break; 34 | case PHAuthorizationStatusNotDetermined: 35 | { 36 | [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { 37 | dispatch_async(dispatch_get_main_queue(), ^{ 38 | completion ? completion(status == PHAuthorizationStatusAuthorized, YES) : nil; 39 | }); 40 | }]; 41 | } 42 | break; 43 | default: 44 | break; 45 | } 46 | } 47 | 48 | 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionReminder.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionReminder.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | /** 14 | * the reminder authorizetion. 15 | */ 16 | @interface YHAuthorizetionReminder : NSObject 17 | 18 | // Determine whether authorization is currently available. 19 | + (BOOL)isAuthorized; 20 | 21 | // Request reminder authorizetion. 22 | + (void)requestAuthorizetionWithCompletion:(void(^_Nullable)(BOOL granted, BOOL isFirst))completion; 23 | 24 | @end 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Sources/Core/Authorizetion/YHAuthorizetionReminder.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHAuthorizetionReminder.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import "YHAuthorizetionReminder.h" 10 | 11 | @implementation YHAuthorizetionReminder 12 | 13 | // Determine whether authorization is currently available. 14 | + (BOOL)isAuthorized{ 15 | EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeReminder]; 16 | return status == EKAuthorizationStatusAuthorized; 17 | } 18 | 19 | // Request reminder authorizetion. 20 | + (void)requestAuthorizetionWithCompletion:(void (^)(BOOL, BOOL))completion{ 21 | EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeReminder]; 22 | switch (status) { 23 | case EKAuthorizationStatusAuthorized: 24 | { 25 | completion ? completion(YES, NO) : nil; 26 | } 27 | break; 28 | case EKAuthorizationStatusDenied: 29 | case EKAuthorizationStatusRestricted: 30 | { 31 | completion ? completion(NO, NO) : nil; 32 | } 33 | break; 34 | case EKAuthorizationStatusNotDetermined: 35 | { 36 | [[[EKEventStore alloc] init] requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError * _Nullable error) { 37 | dispatch_async(dispatch_get_main_queue(), ^{ 38 | completion ? completion(granted, YES) : nil; 39 | }); 40 | }]; 41 | } 42 | break; 43 | default: 44 | break; 45 | } 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Sources/Core/ChineseSort/YHChineseSort.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHChineseSort.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @interface YHChineseSort : NSObject 13 | 14 | 15 | // The name of the group in which the special characters are last grouped separately. 16 | // Default is @"#". 17 | @property (nonatomic, copy) NSString *specialCharTitle; 18 | 19 | // Positions inserted by special character groups 20 | // Default is NO. 21 | // If is NO, insert last. 22 | @property (nonatomic, assign) BOOL isInsertSpecialCharTitleAtFirst; 23 | 24 | // Default Polyphone. 25 | // Such as:@{@"长安":@"CA",@"曾经",@"CJ"}. 26 | @property (nonatomic, strong, readonly) NSMutableDictionary *defaultPolyphoneMaping; 27 | 28 | // Extra Polyphone. 29 | // Such as:@{@"长安":@"CA",@"曾经",@"CJ"}. 30 | @property (nonatomic, strong) NSDictionary *extraPolyphoneMaping; 31 | 32 | // Gets the first uppercase word of each character in pinyin. 33 | // Such as. 34 | // 你好 -> NH 35 | // abc啦啦 -> ABCLL 36 | // ,.呵呵 -> ##HH 37 | - (nullable NSString *)getEachChineseCharacterFirstLettter:(nullable NSString *)chinese; 38 | 39 | /** 40 | sort 1. 41 | models: Array of models to sort. 42 | key: The Model property. 43 | modelClass: The model class. 44 | */ 45 | - (void)sortWithModels:(NSArray *)models key:(NSString *)key modelClass:(Class)modelClass completion:(void(^_Nullable)(NSArray *sortGroups, NSArray *sectionTitles))completion; 46 | 47 | /** 48 | sort 2. 49 | stringArrays: Array of string to sort. 50 | */ 51 | - (void)sortWithStringArrays:(NSArray *)stringArrays completion:(void(^_Nullable)(NSArray *> *sortGroups, NSArray *sectionTitles))completion; 52 | 53 | 54 | 55 | @end 56 | NS_ASSUME_NONNULL_END 57 | -------------------------------------------------------------------------------- /Sources/Core/ChineseSort/YHChineseSortModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHChineseSortModel.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/7. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @interface YHChineseSortModel : NSObject 13 | 14 | // The object. 15 | @property (nonatomic, strong) id obj; 16 | // The first upper letter. 17 | @property (nonatomic, copy, nullable) NSString *firstLetter; 18 | 19 | @end 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Sources/Core/ChineseSort/YHChineseSortModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHChineseSortModel.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/7. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import "YHChineseSortModel.h" 10 | 11 | @implementation YHChineseSortModel 12 | - (instancetype)init 13 | { 14 | self = [super init]; 15 | if (self) { 16 | 17 | } 18 | return self; 19 | } 20 | @end 21 | -------------------------------------------------------------------------------- /Sources/Core/ChineseSort/yh_chinese_letters.h: -------------------------------------------------------------------------------- 1 | // 2 | // yh_chinese_letters.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/5. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #ifndef yh_chinese_letters_h 10 | #define yh_chinese_letters_h 11 | 12 | #include 13 | 14 | char yh_get_chinese_first_letters(unsigned short ch); 15 | 16 | #endif /* yh_chinese_letters_h */ 17 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSArray+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+YHExtension.h 3 | // Kit 4 | // 5 | // Created by 银河 on 2019/1/17. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSArray (YHExtension) 14 | 15 | // NSArray to json string. 16 | @property (nonatomic, strong, readonly, nullable) NSString *yh_jsonStringEncode; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSArray+YHExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+YHExtension.m 3 | // Kit 4 | // 5 | // Created by 银河 on 2019/1/17. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "NSArray+YHExtension.h" 10 | 11 | #ifdef DEBUG 12 | #define YHDebugLog(format, ...) printf("[YHDebugLog] [NSArray (YHExtension)] [%s] [%d] %s\n" ,[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:format, ##__VA_ARGS__] UTF8String]) 13 | #else 14 | #define YHDebugLog(format, ...) 15 | #endif 16 | 17 | @implementation NSArray (YHExtension) 18 | 19 | - (NSString *)yh_jsonStringEncode{ 20 | NSString *result = nil; 21 | if (self && [NSJSONSerialization isValidJSONObject:self]) { 22 | NSError *error = nil; 23 | NSData *data = [NSJSONSerialization dataWithJSONObject:self 24 | options:NSJSONReadingMutableLeaves | NSJSONReadingAllowFragments 25 | error:&error]; 26 | 27 | if (!error && data) { 28 | YHDebugLog(@"NSArray to json successful."); 29 | result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 30 | } else { 31 | YHDebugLog(@"NSArray to json failed, error : %@.", error); 32 | } 33 | } 34 | return result; 35 | } 36 | 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSAttributedString+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+YHExtension.h 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/6. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface NSAttributedString (YHExtension) 15 | 16 | 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSAttributedString+YHExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+YHExtension.m 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/6. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "NSAttributedString+YHExtension.h" 10 | 11 | @implementation NSAttributedString (YHExtension) 12 | 13 | 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSDate+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+YHExtension.h 3 | // Kit 4 | // 5 | // Created by 银河 on 2018/12/27. 6 | // Copyright © 2018 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | // the week day type. 14 | // In Western countries, Sunday comes first. 1-Sun. 2-Mon. 3-Thes. 4-Wed. 5-Thur. 6-Fri. 7-Sat. 15 | // But in China, Monday comes first. 16 | typedef NS_ENUM(NSUInteger, YHDateWeekType) { 17 | YHDateWeekTypeMonday, // Mon. In China 18 | YHDateWeekTypeTuesday, // Thes. In China 19 | YHDateWeekTypeWednesday, // Wed. In China 20 | YHDateWeekTypeThursday, // Thur. In China 21 | YHDateWeekTypeFriday, // Fri. In China 22 | YHDateWeekTypeSaturday, // Sat. In China 23 | YHDateWeekTypeSunday, // Sun. In China 24 | }; 25 | 26 | @interface NSDate (YHExtension) 27 | 28 | // date components. 29 | // year, month, day, hour, minute, second, weekday. 30 | @property (nonatomic, strong, readonly) NSDateComponents *yh_cmps; 31 | 32 | // the year with given date. 33 | @property (nonatomic, assign, readonly) NSInteger yh_year; 34 | 35 | // the month with given date. 36 | @property (nonatomic, assign, readonly) NSInteger yh_month; 37 | 38 | // the day with given date. 39 | @property (nonatomic, assign, readonly) NSInteger yh_day; 40 | 41 | // the hour with given date. 42 | @property (nonatomic, assign, readonly) NSInteger yh_hour; 43 | 44 | // the minute with given date. 45 | @property (nonatomic, assign, readonly) NSInteger yh_minute; 46 | 47 | // the second with given date. 48 | @property (nonatomic, assign, readonly) NSInteger yh_second; 49 | 50 | // the week with given date. 51 | @property (nonatomic, assign, readonly) YHDateWeekType yh_weekType; 52 | 53 | // is leap year with given date. 54 | @property (nonatomic, assign, readonly) BOOL yh_isLeapYear; 55 | 56 | // is today with given date. 57 | @property (nonatomic, assign, readonly) BOOL yh_isToday; 58 | 59 | // is yesterday with given date. 60 | @property (nonatomic, assign, readonly) BOOL yh_isYesterday; 61 | 62 | // is tomorrow with given date. 63 | @property (nonatomic, assign, readonly) BOOL yh_isTomorrow; 64 | 65 | // days of the month. 66 | @property (nonatomic, assign, readonly) NSInteger yh_daysOfMonth; 67 | 68 | // NSDate -> time string 69 | // yyyy-MM-dd HH:mm:ss 70 | - (NSString *)yh_dateStringWithFormat:(NSString *)format; 71 | 72 | // NSDate -> timeStmp 73 | - (NSString *)yh_timeStamp; 74 | 75 | // Returns a date representing the receiver date shifted later by the provided number of seconds. 76 | - (NSDate *)yh_dateByAddSecond:(NSInteger)second; 77 | 78 | // Returns a date representing the receiver date shifted later by the provided number of minutes. 79 | - (NSDate *)yh_dateByAddMinute:(NSInteger)minute; 80 | 81 | // Returns a date representing the receiver date shifted later by the provided number of hours. 82 | - (NSDate *)yh_dateByAddHour:(NSInteger)hour; 83 | 84 | // Returns a date representing the receiver date shifted later by the provided number of days. 85 | - (NSDate *)yh_dateByAddDay:(NSInteger)day; 86 | 87 | 88 | 89 | 90 | 91 | 92 | @end 93 | NS_ASSUME_NONNULL_END 94 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSDate+YHExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+YHExtension.m 3 | // Kit 4 | // 5 | // Created by 银河 on 2018/12/27. 6 | // Copyright © 2018 yinhe. All rights reserved. 7 | // 8 | 9 | #import "NSDate+YHExtension.h" 10 | 11 | #ifdef DEBUG 12 | #define YHDebugLog(format, ...) printf("[YHDebugLog] [NSDate (YHExtension)] [%s] [%d] %s\n" ,[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:format, ##__VA_ARGS__] UTF8String]) 13 | #else 14 | #define YHDebugLog(format, ...) 15 | #endif 16 | @implementation NSDate (YHExtension) 17 | 18 | // date components. 19 | // year, month, day, hour, minute, second, weekday. 20 | - (NSDateComponents *)yh_cmps{ 21 | NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday; 22 | return [[NSCalendar currentCalendar] components:unit fromDate:self]; 23 | } 24 | 25 | // the year with given date. 26 | - (NSInteger)yh_year{ 27 | return self.yh_cmps.year; 28 | } 29 | 30 | // the month with given date. 31 | - (NSInteger)yh_month{ 32 | return self.yh_cmps.month; 33 | } 34 | 35 | // the day with given date. 36 | - (NSInteger)yh_day{ 37 | return self.yh_cmps.day; 38 | } 39 | 40 | // the hour with given date. 41 | - (NSInteger)yh_hour{ 42 | return self.yh_cmps.hour; 43 | } 44 | 45 | // the minute with given date. 46 | - (NSInteger)yh_minute{ 47 | return self.yh_cmps.minute; 48 | } 49 | 50 | // the second with given date. 51 | - (NSInteger)yh_second{ 52 | return self.yh_cmps.second; 53 | } 54 | 55 | // the week with given date. 56 | - (YHDateWeekType)yh_weekType{ 57 | NSInteger weekday = self.yh_cmps.weekday; 58 | YHDateWeekType type = YHDateWeekTypeSunday; 59 | if (weekday == 1) { 60 | type = YHDateWeekTypeSunday; 61 | } else if (weekday == 2) { 62 | type = YHDateWeekTypeMonday; 63 | } else if (weekday == 3) { 64 | type = YHDateWeekTypeTuesday; 65 | } else if (weekday == 4) { 66 | type = YHDateWeekTypeWednesday; 67 | } else if (weekday == 5) { 68 | type = YHDateWeekTypeThursday; 69 | } else if (weekday == 6) { 70 | type = YHDateWeekTypeFriday; 71 | } else if (weekday == 7) { 72 | type = YHDateWeekTypeSaturday; 73 | } 74 | return type; 75 | } 76 | 77 | // is leap year with given date. 78 | - (BOOL)yh_isLeapYear{ 79 | NSInteger year = self.yh_year; 80 | return ((year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0))); 81 | } 82 | 83 | // is today with given date. 84 | - (BOOL)yh_isToday{ 85 | return [[NSCalendar currentCalendar] isDateInToday:self]; 86 | } 87 | 88 | // is yesterday with given date. 89 | - (BOOL)yh_isYesterday{ 90 | return [[NSCalendar currentCalendar] isDateInYesterday:self]; 91 | } 92 | 93 | // is tomorrow with given date. 94 | - (BOOL)yh_isTomorrow{ 95 | return [[NSCalendar currentCalendar] isDateInTomorrow:self]; 96 | } 97 | 98 | // days of the month. 99 | - (NSInteger)yh_daysOfMonth{ 100 | NSRange range = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:self]; 101 | return range.length; 102 | } 103 | 104 | // NSDate -> time string 105 | // yyyy-MM-dd HH:mm:ss 106 | - (NSString *)yh_dateStringWithFormat:(NSString *)format{ 107 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 108 | formatter.dateFormat = format; 109 | return [formatter stringFromDate:self]; 110 | } 111 | 112 | // NSDate -> timeStmp 113 | - (NSString *)yh_timeStamp{ 114 | NSInteger stmp = (NSInteger)[self timeIntervalSince1970]; 115 | return [NSString stringWithFormat:@"%ld",(long)stmp]; 116 | } 117 | 118 | // Returns a date representing the receiver date shifted later by the provided number of seconds. 119 | - (NSDate *)yh_dateByAddSecond:(NSInteger)second{ 120 | NSTimeInterval s = [self timeIntervalSince1970] + second; 121 | return [NSDate dateWithTimeIntervalSince1970:s]; 122 | } 123 | 124 | // Returns a date representing the receiver date shifted later by the provided number of minutes. 125 | - (NSDate *)yh_dateByAddMinute:(NSInteger)minute{ 126 | return [self yh_dateByAddSecond:(minute * 60)]; 127 | } 128 | 129 | // Returns a date representing the receiver date shifted later by the provided number of hours. 130 | - (NSDate *)yh_dateByAddHour:(NSInteger)hour{ 131 | return [self yh_dateByAddMinute:(hour * 60)]; 132 | } 133 | 134 | // Returns a date representing the receiver date shifted later by the provided number of days. 135 | - (NSDate *)yh_dateByAddDay:(NSInteger)day{ 136 | return [self yh_dateByAddHour:(day * 24)]; 137 | } 138 | 139 | 140 | 141 | 142 | @end 143 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSDictionary+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+YHExtension.h 3 | // Kit 4 | // 5 | // Created by apple on 2019/1/17. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @interface NSDictionary (YHExtension) 13 | 14 | 15 | #pragma mark - 字典解析 16 | //************************************************************************************* 17 | //************************************************************************************* 18 | //************************************************************************************* 19 | 20 | // 用于后台返回的json解析,一般情况下后台返回的数据包含NSDictionary、NSArray、NSNumber、NSString、NSNull. 21 | // 个人不喜欢使用MJExtension或者YYModel,更喜欢手动解析数据,因此写了下面三个方法. 22 | // yh_decodeToStringWithKey:defaultStringValue 强制把字典里面的某个key关联的数据解析为字符串 23 | // yh_decodeToArrayWithKey:defaultArrayValue 把字典里面的某个key关联的数据解析成为数组,内部做了判断,如果解析出来的数据不是NSArray类型,则使用defaultArrayValue,保证返回的数据一定是NSArray类型的数据 24 | // yh_decodeToDictionaryWithKey:defaultDictionaryValue 把字典里面的某个key关联的数据解析成为字典,内部做了判断,如果解析出来的数据不是NSDictionary类型,则使用defaultDictionaryValue,保证返回的数据一定是NSDictionary类型的数据 25 | - (NSString *)yh_decodeToStringWithKey:(NSString *)key defaultStringValue:(NSString *)defaultStringValue; 26 | - (NSArray *)yh_decodeToArrayWithKey:(NSString *)key defaultArrayValue:(NSArray *)defaultArrayValue; 27 | - (NSDictionary *)yh_decodeToDictionaryWithKey:(NSString *)key defaultDictionaryValue:(NSDictionary *)defaultDictionaryValue; 28 | 29 | 30 | //************************************************************************************* 31 | //************************************************************************************* 32 | //************************************************************************************* 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | // NSDictionary to json string. 42 | @property (nonatomic, strong, readonly, nullable) NSString *yh_jsonStringEncode; 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | @end 55 | NS_ASSUME_NONNULL_END 56 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSDictionary+YHExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+YHExtension.m 3 | // Kit 4 | // 5 | // Created by apple on 2019/1/17. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "NSDictionary+YHExtension.h" 10 | 11 | #ifdef DEBUG 12 | #define YHDebugLog(format, ...) printf("[YHDebugLog] [NSDictionary (YHExtension)] [%s] [%d] %s\n" ,[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:format, ##__VA_ARGS__] UTF8String]) 13 | #else 14 | #define YHDebugLog(format, ...) 15 | #endif 16 | 17 | @implementation NSDictionary (YHExtension) 18 | 19 | #pragma mark - 字典解析 20 | //************************************************************************************* 21 | //************************************************************************************* 22 | //************************************************************************************* 23 | 24 | - (NSString *)yh_decodeToStringWithKey:(NSString *)key defaultStringValue:(NSString *)defaultStringValue{ 25 | NSString *result = defaultStringValue; 26 | if (self && [self.allKeys containsObject:key]) { 27 | id object = self[key]; 28 | result = [NSString stringWithFormat:@"%@",object]; 29 | } 30 | return result; 31 | } 32 | 33 | - (NSArray *)yh_decodeToArrayWithKey:(NSString *)key defaultArrayValue:(NSArray *)defaultArrayValue{ 34 | NSArray *result = defaultArrayValue; 35 | if (self &&[self.allKeys containsObject:key]) { 36 | id object = self[key]; 37 | if ([object isKindOfClass:[NSArray class]]) { 38 | result = object; 39 | } 40 | } 41 | return result; 42 | } 43 | 44 | - (NSDictionary *)yh_decodeToDictionaryWithKey:(NSString *)key defaultDictionaryValue:(NSDictionary *)defaultDictionaryValue{ 45 | NSDictionary *result = defaultDictionaryValue; 46 | if (self && [self.allKeys containsObject:key]) { 47 | id object = self[key]; 48 | if ([object isKindOfClass:[NSDictionary class]]) { 49 | result = object; 50 | } 51 | } 52 | return result; 53 | } 54 | 55 | //************************************************************************************* 56 | //************************************************************************************* 57 | //************************************************************************************* 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | - (NSString *)yh_jsonStringEncode{ 74 | NSString *result = nil; 75 | if (self && [NSJSONSerialization isValidJSONObject:self]) { 76 | NSError *error = nil; 77 | NSData *data = [NSJSONSerialization dataWithJSONObject:self 78 | options:NSJSONReadingMutableLeaves | NSJSONReadingAllowFragments 79 | error:&error]; 80 | if (!error && data) { 81 | YHDebugLog(@"NSDictionary to json successful."); 82 | result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 83 | } else { 84 | YHDebugLog(@"NSDictionary to json failed, error : %@.", error); 85 | } 86 | } 87 | return result; 88 | } 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSMutableAttributedString+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableAttributedString+YHExtension.h 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/12. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface NSMutableAttributedString (YHExtension) 15 | 16 | 17 | /** 18 | 快速设置一个属性字符串 19 | 20 | @param text 文本 21 | @param color 文本颜色 22 | @param font 字体 23 | @param kern 文字间距(0代表默认间距) 24 | @param lineSpacing 行间距(0代表默认间距) 25 | @param alignment 文本对其方式 26 | @return 属性字符串 27 | */ 28 | + (NSMutableAttributedString *)yh_attributedStringWithText:(NSString *)text 29 | color:(UIColor *)color 30 | font:(UIFont *)font 31 | kern:(CGFloat)kern 32 | lineSpacing:(CGFloat)lineSpacing 33 | alignment:(NSTextAlignment)alignment; 34 | 35 | @end 36 | 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSMutableAttributedString+YHExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableAttributedString+YHExtension.m 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/12. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "NSMutableAttributedString+YHExtension.h" 10 | 11 | 12 | @implementation NSMutableAttributedString (YHExtension) 13 | 14 | + (NSMutableAttributedString *)yh_attributedStringWithText:(NSString *)text color:(UIColor *)color font:(UIFont *)font kern:(CGFloat)kern lineSpacing:(CGFloat)lineSpacing alignment:(NSTextAlignment)alignment{ 15 | if (!text) { 16 | return [[NSMutableAttributedString alloc] initWithString:@""]; 17 | } 18 | NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:text]; 19 | 20 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 21 | paragraphStyle.lineSpacing = lineSpacing; 22 | paragraphStyle.alignment = alignment; 23 | paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping; 24 | 25 | [attr addAttributes:@{NSForegroundColorAttributeName : color, 26 | NSFontAttributeName : font, 27 | NSKernAttributeName : @(kern), 28 | NSParagraphStyleAttributeName : paragraphStyle 29 | } range:NSMakeRange(0, text.length)]; 30 | return attr; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSObject+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+YHExtension.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/16. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface NSObject (YHExtension) 16 | 17 | // Determine whether an object is Foundation class. 18 | @property (nonatomic, assign, readonly) BOOL yh_isFoundationClass; 19 | 20 | // The description with object. 21 | // Always use in debug. 22 | @property (nonatomic, strong, readonly, nullable) id yh_description; 23 | 24 | // Determine whether a object is an empty. 25 | @property (nonatomic, assign, readonly) BOOL yh_isNilOrNull; 26 | 27 | // Determine whether a object is an NSString class. 28 | @property (nonatomic, assign, readonly) BOOL yh_is_NSString; 29 | 30 | // Determine whether a object is an NSArray class. 31 | @property (nonatomic, assign, readonly) BOOL yh_is_NSArray; 32 | 33 | // Determine whether a object is an NSDictionary class. 34 | @property (nonatomic, assign, readonly) BOOL yh_is_NSDictionary; 35 | 36 | // Determine whether a object is an NSNumber class. 37 | @property (nonatomic, assign, readonly) BOOL yh_is_NSNumber; 38 | 39 | // Get topViewController. 40 | @property (nonatomic, strong, readonly) UIViewController *yh_topViewController; 41 | 42 | // make call. 43 | + (void)yh_makeCallWithPhone:(NSString *)phone; 44 | 45 | // open app settings. 46 | + (void)yh_openAppSettings; 47 | 48 | // Open App Store. 49 | + (void)yh_openAppStoreWithAppID:(NSString *)appID; 50 | 51 | // Open App Store Review. 52 | + (void)yh_openAppStoreReviewWithAppID:(NSString *)appID; 53 | 54 | // Open Safari. 55 | + (void)yh_openSafariWithURL:(NSString *)url; 56 | 57 | // Send SMS without SMS content. 58 | // If you want to send SMS with content, please use 'YHSendSMS'. 59 | + (void)yh_sendSmsWithoutContentWithPhone:(NSString *)phone; 60 | 61 | // Get local json file. 62 | + (nullable id)yh_getLocalJsonFileWithFileName:(NSString *)fileName; 63 | 64 | // Get local plist file. 65 | + (nullable id)yh_getLocalPlistFileWithFileName:(NSString *)fileName; 66 | 67 | @end 68 | 69 | NS_ASSUME_NONNULL_END 70 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSParagraphStyle+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSParagraphStyle+YHExtension.h 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/12. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSParagraphStyle (YHExtension) 14 | 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSParagraphStyle+YHExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSParagraphStyle+YHExtension.m 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/12. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "NSParagraphStyle+YHExtension.h" 10 | #import 11 | 12 | @implementation NSParagraphStyle (YHExtension) 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Sources/Core/Foundation/NSString+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+YHExtension.h 3 | // Kit 4 | // 5 | // Created by 银河 on 2018/12/28. 6 | // Copyright © 2018 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | static NSString *const k_YH_Email_Regex = @"^[a-zA-Z0-9]+@[a-zA-Z0-9.]+\\.[a-zA-Z0-9]+$"; 14 | static NSString *const k_YH_URL_Regex = @"((http[s]{0,1}|ftp)://[a-zA-Z0-9\\-.]+(?::(\\d+))?(?:(?:/[a-zA-Z0-9\\-._?,'+\\&%$=~*!():@\\\\]*)+)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)"; 15 | static NSString *const k_YH_Chinese_Regex = @"[\\u4e00-\\u9fa5\\w\\-]+"; 16 | 17 | @interface NSString (YHExtension) 18 | 19 | // Determine whether a string is an integer. 20 | @property (nonatomic, assign, readonly) BOOL yh_isInt; 21 | 22 | // Determine whether a string is an float. 23 | @property (nonatomic, assign, readonly) BOOL yh_isFloat; 24 | 25 | // Determine whether a string is an number. 26 | @property (nonatomic, assign, readonly) BOOL yh_isNumber; 27 | 28 | // Determine whether a string is empty. 29 | // 注意:空对象不会调用 比如 NSString *str = nil; str.yh_isEmpty 此时返回NO 30 | @property (nonatomic, assign, readonly) BOOL yh_isEmpty; 31 | 32 | // Determine whether a string contain chinese. 33 | @property (nonatomic, assign, readonly) BOOL yh_isContainChinese; 34 | 35 | // Determine whether a string contain emoji. 36 | @property (nonatomic, assign, readonly) BOOL yh_isContainEmoji; 37 | 38 | // Get pinyin. 39 | @property (nonatomic, copy, readonly) NSString *yh_pinYin; 40 | 41 | // JSON string decode. 42 | @property (nonatomic, strong, readonly, nullable) id yh_jsonStringDecode; 43 | 44 | // Determine whether a string is an email. 45 | @property (nonatomic, assign, readonly) BOOL yh_isEmail; 46 | 47 | // Determine whether a string is an URL. 48 | @property (nonatomic, assign, readonly) BOOL yh_isURL; 49 | 50 | // URL transcoding if contain chinese. 51 | @property (nonatomic, copy, readonly) NSString *yh_urlTranscoding; 52 | 53 | // timeStamp -> timeString. 54 | // yyyy-MM-dd HH:mm:ss 55 | - (nullable NSString *)yh_timeStampToTimeStringWithFormat:(NSString *)format; 56 | 57 | // timeString -> timeStmp. 58 | // yyyy-MM-dd HH:mm:ss 59 | - (nullable NSString *)yh_timeStringToTimeStampWithFormat:(NSString *)format; 60 | 61 | // timeString -> NSDate. 62 | // yyyy-MM-dd HH:mm:ss 63 | - (nullable NSDate *)yh_timeStringToDateWithWithFormat:(NSString *)format; 64 | 65 | // timeStamp -> NSDate. 66 | // 时间戳可以是13位. 67 | // yyyy-MM-dd HH:mm:ss 68 | - (nullable NSDate *)yh_timeStampToDateWithFormat:(NSString *)format; 69 | 70 | // Determine whether a string is legal. 71 | - (BOOL)yh_validateWithRegex:(NSString *)regex; 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | @end 82 | NS_ASSUME_NONNULL_END 83 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/AuxiliaryView/UIView+YHImageBrowserProgressView.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+YHImageBrowserProgressView.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/17. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface UIView (YHImageBrowserProgressView) 14 | /** 15 | * 显示进度 16 | */ 17 | - (void)yh_showProgressViewWithValue:(CGFloat)value; 18 | /** 19 | * 显示菊花旋转 20 | */ 21 | - (void)yh_showLoading; 22 | /** 23 | * 隐藏 24 | */ 25 | - (void)yh_hideProgressView; 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/AuxiliaryView/YHImageBrowserSheetView.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserSheetView.h 3 | // HiFanSmooth 4 | // 5 | // Created by 银河 on 2019/5/17. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class YHImageBrowserSheetView; 14 | @class YHImageBrowser; 15 | @protocol YHImageBrowserSheetViewDataSource 16 | @required; 17 | /** 18 | * 数据源 19 | */ 20 | - (NSArray *)titlesForSheetView:(YHImageBrowserSheetView *)sheetView; 21 | @end 22 | 23 | 24 | 25 | @protocol YHImageBrowserSheetViewDelegate 26 | @optional; 27 | /** 28 | * CanelButton是否隐藏(默认NO) 29 | * 当为YES,titleForCancelWithSheetView和sheetViewDicClickCancel这两个回调无效 30 | */ 31 | - (BOOL)shouldHideCancelForSheetView:(YHImageBrowserSheetView *)sheetView; 32 | 33 | /** 34 | * CanelButton的标题(默认"取消") 35 | */ 36 | - (NSString *)titleForCancelWithSheetView:(YHImageBrowserSheetView *)sheetView; 37 | 38 | /** 39 | * 点击索引回调 40 | */ 41 | - (void)sheetView:(YHImageBrowserSheetView *)sheetView didClickIndex:(int)clickIndex; 42 | 43 | /** 44 | * 点击了CanelButton 45 | * 当实现了此协议,如果需要隐藏sheetView,请自行调用hide方法 46 | */ 47 | - (void)sheetViewDicClickCancel:(YHImageBrowserSheetView *)sheetView; 48 | 49 | /** 50 | * SheetView隐藏回调 51 | */ 52 | - (void)sheetViewDidHide:(YHImageBrowserSheetView *)sheetView; 53 | 54 | @end 55 | 56 | 57 | 58 | /** 59 | * 长按从底部弹出来的SheetView 60 | * 内部已做了横竖屏切换的适配 61 | */ 62 | @interface YHImageBrowserSheetView : UIView 63 | 64 | @property (nonatomic, weak) id dataSource; 65 | 66 | @property (nonatomic, weak) id delegate; 67 | 68 | // sheetView关联的ImageBrowser 69 | @property (nonatomic, weak) YHImageBrowser *associatedBrowser; 70 | 71 | /** 72 | * 显示SheetView 73 | */ 74 | - (void)show; 75 | 76 | /** 77 | * 隐藏SheetView 78 | */ 79 | - (void)hide; 80 | @end 81 | 82 | NS_ASSUME_NONNULL_END 83 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/AuxiliaryView/YHImageBrowserToolBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserToolBar.h 3 | // HiFanSmooth 4 | // 5 | // Created by 银河 on 2019/5/18. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface YHImageBrowserToolBar : UIView 14 | @property (nonatomic, strong, readonly) UILabel *indexLabel; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/AuxiliaryView/YHImageBrowserToolBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserToolBar.m 3 | // HiFanSmooth 4 | // 5 | // Created by 银河 on 2019/5/18. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHImageBrowserToolBar.h" 10 | #import "YHMacro.h" 11 | #import "YHImageBrowserDefine.h" 12 | 13 | @interface YHImageBrowserToolBar () 14 | @property (nonatomic, strong) CAGradientLayer *gradientLayer; 15 | @property (nonatomic, strong) UILabel *indexLabel; 16 | @end 17 | 18 | @implementation YHImageBrowserToolBar 19 | 20 | - (instancetype)init 21 | { 22 | self = [super init]; 23 | if (self) { 24 | [self.layer addSublayer:self.gradientLayer]; 25 | [self addSubview:self.indexLabel]; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)layoutSubviews{ 31 | [super layoutSubviews]; 32 | self.gradientLayer.frame = self.bounds; 33 | 34 | if (YH__DeviceOrientation == UIInterfaceOrientationPortrait || YH__DeviceOrientation == UIInterfaceOrientationPortraitUpsideDown || YH__DeviceOrientation == UIInterfaceOrientationUnknown) { 35 | if (YH__IS_IPHONE_X) { 36 | self.indexLabel.frame = CGRectMake(0, self.frame.size.height - 50, self.frame.size.width, 50); 37 | } else { 38 | self.indexLabel.frame = self.bounds; 39 | } 40 | } else { 41 | self.indexLabel.frame = self.bounds; 42 | } 43 | } 44 | 45 | - (CAGradientLayer *)gradientLayer{ 46 | if (!_gradientLayer) { 47 | _gradientLayer = [CAGradientLayer layer]; 48 | _gradientLayer.startPoint = CGPointMake(0.5, 0); 49 | _gradientLayer.endPoint = CGPointMake(0.5, 1); 50 | _gradientLayer.colors = @[(id)[UIColor colorWithRed:0 green:0 blue:0 alpha:0.3].CGColor, (id)[UIColor colorWithRed:0 green:0 blue:0 alpha:0].CGColor]; 51 | } 52 | return _gradientLayer; 53 | } 54 | 55 | - (UILabel *)indexLabel { 56 | if (!_indexLabel) { 57 | _indexLabel = [[UILabel alloc] init]; 58 | _indexLabel.textColor = [UIColor whiteColor]; 59 | _indexLabel.font = [UIFont boldSystemFontOfSize:15]; 60 | _indexLabel.textAlignment = NSTextAlignmentCenter; 61 | _indexLabel.adjustsFontSizeToFitWidth = YES; 62 | } 63 | return _indexLabel; 64 | } 65 | 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Base/YHImageBrowserCollectionViewFlowLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserCollectionViewFlowLayout.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/16. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface YHImageBrowserCollectionViewFlowLayout : UICollectionViewFlowLayout 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Base/YHImageBrowserCollectionViewFlowLayout.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserCollectionViewFlowLayout.m 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/16. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHImageBrowserCollectionViewFlowLayout.h" 10 | 11 | @interface YHImageBrowserCollectionViewFlowLayout() 12 | @property (nonatomic, assign) CGFloat distanceBetweenPages; 13 | @end 14 | 15 | @implementation YHImageBrowserCollectionViewFlowLayout 16 | 17 | - (instancetype)init { 18 | self = [super init]; 19 | if (self) { 20 | self.distanceBetweenPages = 20; 21 | } 22 | return self; 23 | } 24 | 25 | - (void)prepareLayout { 26 | [super prepareLayout]; 27 | self.scrollDirection = UICollectionViewScrollDirectionHorizontal; 28 | CGSize size = self.collectionView.bounds.size; 29 | self.itemSize = CGSizeMake(size.width, size.height); 30 | self.minimumLineSpacing = 0; 31 | self.minimumInteritemSpacing = 0; 32 | } 33 | 34 | - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { 35 | NSArray *layoutAttsArray = [[NSArray alloc] initWithArray:[super layoutAttributesForElementsInRect:rect] copyItems:YES]; 36 | CGFloat halfWidth = self.collectionView.bounds.size.width / 2.0; 37 | CGFloat centerX = self.collectionView.contentOffset.x + halfWidth; 38 | [layoutAttsArray enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 39 | obj.center = CGPointMake(obj.center.x + (obj.center.x - centerX) / halfWidth * self.distanceBetweenPages / 2, obj.center.y); 40 | }]; 41 | return layoutAttsArray; 42 | } 43 | 44 | - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { 45 | return YES; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Base/YHImageBrowserView.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserView.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/16. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "YHImageBrowserLayoutDirectionManager.h" 11 | #import "YHImageBrowserViewDataSource.h" 12 | #import "YHImageBrowserViewDelegate.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface YHImageBrowserView : UICollectionView 17 | 18 | /** 19 | * 数据源 20 | */ 21 | @property (nonatomic, weak) id yh_dataSource; 22 | 23 | /** 24 | * 代理 25 | */ 26 | @property (nonatomic, weak) id yh_delegate; 27 | 28 | /** 29 | * 当前currentIndex所对应的data(只读) 30 | */ 31 | @property (nonatomic, strong, readonly) id currentData; 32 | 33 | /** 34 | * 当前索引(只读) 35 | */ 36 | @property (nonatomic, assign, readonly) NSUInteger currentIndex; 37 | 38 | /** 39 | * 根据屏幕旋转方向更新布局 40 | */ 41 | - (void)updateLayoutWithDirection:(YHImageBrowserLayoutDirection)direction containerFrame:(CGRect)containerFrame; 42 | 43 | /** 44 | * 滑动到指定索引 45 | */ 46 | - (void)scrollToPageIndex:(NSInteger)index; 47 | 48 | 49 | @end 50 | 51 | NS_ASSUME_NONNULL_END 52 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Helper/YHImageBrowserDefine.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserDefine.h 3 | // HiFanSmooth 4 | // 5 | // Created by 银河 on 2019/5/17. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #ifndef YHImageBrowserDefine_h 10 | #define YHImageBrowserDefine_h 11 | 12 | 13 | static void YHImageBrowserAsync(dispatch_queue_t queue, dispatch_block_t block) { 14 | if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(queue)) == 0) { 15 | block(); 16 | } else { 17 | dispatch_async(queue, block); 18 | } 19 | } 20 | 21 | 22 | 23 | #endif /* YHImageBrowserDefine_h */ 24 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Helper/YHImageBrowserLayoutDirectionManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserLayoutDirectionManager.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/16. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | typedef NS_ENUM(NSUInteger, YHImageBrowserLayoutDirection) { 15 | YHImageBrowserLayoutDirection_Vertical, // 水平 16 | YHImageBrowserLayoutDirection_Horizontal, // 垂直 17 | }; 18 | 19 | @interface YHImageBrowserLayoutDirectionManager : NSObject 20 | 21 | @property (nonatomic, copy) void(^layoutDirectionChangedBlock)(YHImageBrowserLayoutDirection direction); 22 | 23 | - (void)startObserve; 24 | 25 | + (YHImageBrowserLayoutDirection)getCurrntLayoutDirection; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Helper/YHImageBrowserLayoutDirectionManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserLayoutDirectionManager.m 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/16. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHImageBrowserLayoutDirectionManager.h" 10 | 11 | @implementation YHImageBrowserLayoutDirectionManager 12 | 13 | - (void)dealloc{ 14 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; 15 | } 16 | 17 | - (void)startObserve{ 18 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidChangeStatusBarOrientationNotification:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; 19 | } 20 | 21 | + (YHImageBrowserLayoutDirection)getCurrntLayoutDirection{ 22 | UIInterfaceOrientation obr = [UIApplication sharedApplication].statusBarOrientation; 23 | if ((obr == UIInterfaceOrientationPortrait) || (obr == UIInterfaceOrientationPortraitUpsideDown)) { 24 | return YHImageBrowserLayoutDirection_Vertical; 25 | } else if ((obr == UIInterfaceOrientationLandscapeLeft) || (obr == UIInterfaceOrientationLandscapeRight)) { 26 | return YHImageBrowserLayoutDirection_Horizontal; 27 | } else { 28 | return YHImageBrowserLayoutDirection_Vertical; 29 | } 30 | } 31 | 32 | 33 | - (void)applicationDidChangeStatusBarOrientationNotification:(NSNotification *)note { 34 | if (self.layoutDirectionChangedBlock) { 35 | self.layoutDirectionChangedBlock([self.class getCurrntLayoutDirection]); 36 | } 37 | } 38 | @end 39 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Helper/YHImageBrowserWebImageManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserWebImageManager.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/14. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | typedef void(^QueryCacheCompletionBlock)(UIImage *_Nullable image, NSData *_Nullable data); 15 | typedef void(^DownloadProgressBlock)(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL); 16 | typedef void(^DownloadSuccessBlock)(UIImage * _Nullable image, NSData * _Nullable data, BOOL finished); 17 | typedef void(^DownloadErrorBlock)(NSError * _Nullable error, BOOL finished); 18 | 19 | @interface YHImageBrowserWebImageManager : NSObject 20 | 21 | 22 | + (void)queryCacheImageWithKey:(NSURL *)key 23 | completionBlock:(nullable QueryCacheCompletionBlock)completionBlock; 24 | 25 | 26 | + (id)downloadImageWithURL:(NSURL *)URL 27 | progressBlock:(nullable DownloadProgressBlock)progressBlock 28 | successBlock:(nullable DownloadSuccessBlock)successBlock 29 | errorBlock:(nullable DownloadErrorBlock)errorBlock; 30 | 31 | + (void)cancelDownloadWithDownloadToken:(id)token; 32 | 33 | + (void)storeImage:(nullable UIImage *)image 34 | imageData:(nullable NSData *)data 35 | forKey:(NSURL *)key toDisk:(BOOL)toDisk; 36 | 37 | @end 38 | 39 | NS_ASSUME_NONNULL_END 40 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Helper/YHImageBrowserWebImageManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserWebImageManager.m 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/14. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHImageBrowserWebImageManager.h" 10 | 11 | #if __has_include() 12 | #import 13 | #elif __has_include("SDWebImage.h") 14 | #import "SDWebImage.h" 15 | #endif 16 | 17 | #if __has_include() 18 | #import 19 | #elif __has_include("SDWebImageWebPCoder.h") 20 | #import "SDWebImageWebPCoder.h" 21 | #endif 22 | 23 | 24 | @implementation YHImageBrowserWebImageManager 25 | 26 | + (void)initialize{ 27 | 28 | } 29 | 30 | + (void)queryCacheImageWithKey:(NSURL *)key 31 | completionBlock:(QueryCacheCompletionBlock)completionBlock{ 32 | 33 | NSString *cacheKey = [[SDWebImageManager sharedManager] cacheKeyForURL:key]; 34 | 35 | if (!cacheKey) { 36 | if (completionBlock) { 37 | completionBlock(nil, nil); 38 | } 39 | return; 40 | } 41 | 42 | [[SDImageCache sharedImageCache] queryCacheOperationForKey:cacheKey done:^(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType) { 43 | if (completionBlock) { 44 | completionBlock(image, data); 45 | } 46 | }]; 47 | } 48 | 49 | 50 | + (id)downloadImageWithURL:(NSURL *)URL 51 | progressBlock:(DownloadProgressBlock)progressBlock 52 | successBlock:(DownloadSuccessBlock)successBlock 53 | errorBlock:(DownloadErrorBlock)errorBlock{ 54 | // 适配SDImageWeb 5.0版本 55 | #if __has_include() || __has_include("SDWebImageWebPCoder.h") 56 | SDImageWebPCoder *webPCoder = [SDImageWebPCoder sharedCoder]; 57 | if (![[SDImageCodersManager sharedManager].coders containsObject:webPCoder]) { 58 | [[SDImageCodersManager sharedManager] addCoder:webPCoder]; 59 | } 60 | #endif 61 | SDWebImageDownloadToken *token = [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:URL options:SDWebImageDownloaderLowPriority context:nil progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) { 62 | if (progressBlock) { 63 | progressBlock(receivedSize, expectedSize, targetURL); 64 | } 65 | } completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) { 66 | if (error) { 67 | if (errorBlock) { 68 | errorBlock(error, finished); 69 | return ; 70 | } 71 | } 72 | if (successBlock) { 73 | successBlock(image, data, finished); 74 | } 75 | }]; 76 | return token; 77 | } 78 | 79 | 80 | + (void)cancelDownloadWithDownloadToken:(id)token{ 81 | if (token && [token isKindOfClass:[SDWebImageDownloadToken class]]) { 82 | SDWebImageDownloadToken *downloadToken = token; 83 | [downloadToken cancel]; 84 | } 85 | } 86 | 87 | 88 | + (void)storeImage:(UIImage *)image 89 | imageData:(NSData *)data 90 | forKey:(NSURL *)key 91 | toDisk:(BOOL)toDisk{ 92 | if (!key) { 93 | return; 94 | } 95 | NSString *cacheKey = [[SDWebImageManager sharedManager] cacheKeyForURL:key]; 96 | if (!cacheKey) { 97 | return; 98 | } 99 | 100 | [[SDImageCache sharedImageCache] storeImage:image imageData:data forKey:cacheKey toDisk:toDisk completion:nil]; 101 | } 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/ImageBrowser/YHImage+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImage+Private.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/16. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHImage.h" 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface YHImage () 15 | 16 | - (instancetype)initDownloadWithImage:(nullable UIImage *)image imageData:(nullable NSData *)imageData; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/ImageBrowser/YHImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImage.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/15. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #if __has_include() 12 | #import 13 | #elif __has_include("FLAnimatedImage.h") 14 | #import "FLAnimatedImage.h" 15 | #endif 16 | 17 | 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | @interface YHImage : NSObject 22 | 23 | @property (nonatomic, strong, readonly, nullable) UIImage *image; 24 | @property (nonatomic, strong, readonly, nullable) FLAnimatedImage *animatedImage; 25 | 26 | + (YHImage *)imageNamed:(NSString *)name; 27 | + (YHImage *)imageWithImage:(UIImage *)image; 28 | + (YHImage *)imageWithData:(NSData *)data; 29 | + (YHImage *)imageWithContentsOfFile:(NSString *)path; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/ImageBrowser/YHImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHImage.m 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/15. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHImage.h" 10 | 11 | #if __has_include() 12 | #import 13 | #elif __has_include("SDWebImage.h") 14 | #import "SDWebImage.h" 15 | #endif 16 | 17 | #import "YHImage+Private.h" 18 | 19 | @interface YHImage() 20 | @property (nonatomic, strong) UIImage *image; 21 | @property (nonatomic, strong) FLAnimatedImage *animatedImage; 22 | @end 23 | 24 | @implementation YHImage 25 | 26 | static NSArray *_NSBundlePreferredScales() { 27 | static NSArray *scales; 28 | static dispatch_once_t onceToken; 29 | dispatch_once(&onceToken, ^{ 30 | CGFloat screenScale = [UIScreen mainScreen].scale; 31 | if (screenScale <= 1) { 32 | scales = @[@1,@2,@3]; 33 | } else if (screenScale <= 2) { 34 | scales = @[@2,@3,@1]; 35 | } else { 36 | scales = @[@3,@2,@1]; 37 | } 38 | }); 39 | return scales; 40 | } 41 | 42 | static NSString *_NSStringByAppendingNameScale(NSString *string, CGFloat scale) { 43 | if (!string) return nil; 44 | if (fabs(scale - 1) <= __FLT_EPSILON__ || string.length == 0 || [string hasSuffix:@"/"]) return string.copy; 45 | return [string stringByAppendingFormat:@"@%@x", @(scale)]; 46 | } 47 | 48 | 49 | + (YHImage *)imageWithData:(NSData *)data{ 50 | return [[self alloc] initDownloadWithImage:nil imageData:data]; 51 | } 52 | 53 | + (YHImage *)imageWithContentsOfFile:(NSString *)path{ 54 | UIImage *image = [[UIImage alloc] initWithContentsOfFile:path]; 55 | return [[self alloc] initDownloadWithImage:image imageData:nil]; 56 | } 57 | 58 | + (YHImage *)imageWithImage:(UIImage *)image{ 59 | return [[self alloc] initDownloadWithImage:image imageData:nil]; 60 | } 61 | 62 | + (YHImage *)imageNamed:(NSString *)name{ 63 | if (name.length == 0) return nil; 64 | if ([name hasSuffix:@"/"]) return nil; 65 | 66 | NSString *res = name.stringByDeletingPathExtension; 67 | NSString *ext = name.pathExtension; 68 | NSString *path = nil; 69 | CGFloat scale = 1; 70 | 71 | // If no extension, guess by system supported (same as UIImage). 72 | NSArray *exts = ext.length > 0 ? @[ext] : @[@"", @"png", @"jpeg", @"jpg", @"gif", @"webp", @"apng"]; 73 | NSArray *scales = _NSBundlePreferredScales(); 74 | for (int s = 0; s < scales.count; s++) { 75 | scale = ((NSNumber *)scales[s]).floatValue; 76 | NSString *scaledName = _NSStringByAppendingNameScale(res, scale); 77 | for (NSString *e in exts) { 78 | path = [[NSBundle mainBundle] pathForResource:scaledName ofType:e]; 79 | if (path) break; 80 | } 81 | if (path) break; 82 | } 83 | if (path.length == 0) { 84 | // Support Assets.xcassets. 85 | UIImage *image = [UIImage imageNamed:name]; 86 | return [[self alloc] initDownloadWithImage:image imageData:nil]; 87 | } 88 | NSData *data = [NSData dataWithContentsOfFile:path]; 89 | if (data.length == 0) return nil; 90 | return [[self alloc] initDownloadWithImage:nil imageData:data]; 91 | } 92 | 93 | 94 | - (instancetype)initDownloadWithImage:(UIImage *)image imageData:(NSData *)imageData{ 95 | self = [super init]; 96 | if (self) { 97 | BOOL isGIF = [NSData sd_imageFormatForImageData:imageData] == SDImageFormatGIF; 98 | if (isGIF) { 99 | FLAnimatedImage *animatedImage = [[FLAnimatedImage alloc] initWithAnimatedGIFData:imageData]; 100 | if (animatedImage) { 101 | self.image = animatedImage.posterImage; 102 | self.animatedImage = animatedImage; 103 | } else { 104 | UIImage *tmpImage = [UIImage imageWithData:imageData]; 105 | self.image = tmpImage ? tmpImage : image; 106 | self.animatedImage = nil; 107 | } 108 | } else { 109 | UIImage *tmpImage = [UIImage imageWithData:imageData]; 110 | self.image = tmpImage ? tmpImage : image; 111 | self.animatedImage = nil; 112 | } 113 | } 114 | return self; 115 | } 116 | 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/ImageBrowser/YHImageBrowserCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserCell.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/14. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface YHImageBrowserCell : UICollectionViewCell 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/ImageBrowser/YHImageBrowserCellData+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserCellData+Private.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/15. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHImageBrowserCellData.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | 14 | typedef NS_ENUM(NSUInteger, YHImageBrowserCellDataState) { 15 | YHImageBrowserCellDataState_Invalid, // 非法图片 16 | 17 | YHImageBrowserCellDataState_ImageReady, // YHImage准备好了 18 | 19 | YHImageBrowserCellDataState_ThumbImageReady, // 缩略图准备好了,此时可以显示缩略图 20 | 21 | YHImageBrowserCellDataState_CompressImageReady, // 压缩图片准备好了,此时可以显示压缩图片 22 | 23 | YHImageBrowserCellDataState_IsCompressingImage, // 正在压缩图片 24 | YHImageBrowserCellDataState_CompressImageComplete, // 图片压缩完成 25 | 26 | YHImageBrowserCellDataState_IsDecoding, // 正在解码本地图片 27 | YHImageBrowserCellDataState_DecodeComplete, // 本地图片解码完成 28 | 29 | YHImageBrowserCellDataState_IsQueryingCache, // 正在查询本地缓存 30 | YHImageBrowserCellDataState_QueryCacheComplete, // 本地缓存查询完成 31 | 32 | YHImageBrowserCellDataState_DownloadReady, // 准备下载图片 33 | YHImageBrowserCellDataState_IsDownloading, // 图片下载中(此时有下载进度) 34 | YHImageBrowserCellDataState_DownloadSuccess, // 图片下载成功 35 | YHImageBrowserCellDataState_DownloadFailed, // 图片下载失败 36 | }; 37 | 38 | 39 | @interface YHImageBrowserCellData () 40 | 41 | @property (nonatomic, strong) UIImage *compressImage; 42 | @property (nonatomic, assign) CGFloat downloadProgress; 43 | 44 | @property (nonatomic, assign) YHImageBrowserCellDataState dataState; 45 | 46 | 47 | @property (nonatomic, assign) BOOL isLoading; 48 | 49 | - (void)loadData; 50 | 51 | @end 52 | 53 | NS_ASSUME_NONNULL_END 54 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/ImageBrowser/YHImageBrowserCellData.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserCellData.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/14. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "YHImageBrowserCellDataProtocol.h" 12 | #import "YHImage.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface YHImageBrowserCellData : NSObject 17 | /** 18 | * 网络图片链接 19 | */ 20 | @property (nonatomic, strong, nullable) NSURL *imageURL; 21 | 22 | /** 23 | * 缩略图 24 | */ 25 | @property (nonatomic, strong, nullable) UIImage *thumbImage; 26 | 27 | /** 28 | * 缩略图链接(不会去下载缩略图,只是根据缩略图链接去本地缓存查找是否有该图片,有就显示) 29 | */ 30 | @property (nonatomic, strong, nullable) NSURL *thumbURL; 31 | 32 | /** 33 | * 本地图片 34 | */ 35 | @property (nonatomic, copy, nullable) YHImage *(^localImageBlock)(void); 36 | 37 | 38 | /** 39 | * 最终的YHImage对象 40 | */ 41 | @property (nonatomic, strong, readonly) YHImage *image; 42 | 43 | @end 44 | 45 | NS_ASSUME_NONNULL_END 46 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Protocol/YHImageBrowserCellDataProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserCellDataProtocol.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/14. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | /** 14 | * cellData协议 15 | */ 16 | @protocol YHImageBrowserCellDataProtocol 17 | @required; 18 | 19 | - (Class)yh_cellClass; 20 | 21 | @optional; 22 | - (void)yh_saveToPhotoAlblum:(NSString *)photoAlblumName; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Protocol/YHImageBrowserCellProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserCellProtocol.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/14. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "YHImageBrowserCellDataProtocol.h" 11 | #import "YHImageBrowserLayoutDirectionManager.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | /** 16 | * cell协议 17 | */ 18 | @protocol YHImageBrowserCellProtocol 19 | @required; 20 | 21 | // 设置cell初始data 22 | - (void)yh_browserSetInitialCellData:(id)data layoutDirection:(YHImageBrowserLayoutDirection)layoutDirection containerFrame:(CGRect)containerFrame; 23 | 24 | // 屏幕旋转 25 | - (void)yh_browserLayoutDirectionChanged:(YHImageBrowserLayoutDirection)layoutDirection containerFrmae:(CGRect)containerFrame; 26 | 27 | 28 | @optional; 29 | @property (nonatomic, copy) void(^yh_browserStartPanDownBlock)(void); 30 | @property (nonatomic, copy) void(^yh_browserEndPanDownBlock)(void); 31 | @property (nonatomic, copy) void(^yh_browserChangePanDownBlock)(CGFloat alpha); 32 | @property (nonatomic, copy) void(^yh_browserResetPanDownBlock)(NSTimeInterval interval); 33 | @property (nonatomic, copy) void(^yh_browserDismissPanDownBlock)(NSTimeInterval interval); 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Protocol/YHImageBrowserDataSource.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserDataSource.h 3 | // HiFanSmooth 4 | // 5 | // Created by 银河 on 2019/5/18. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @class YHImageBrowser; 13 | @protocol YHImageBrowserDataSource 14 | @required; 15 | // item个数 16 | - (NSUInteger)numberOfCellForImageBrowser:(YHImageBrowser *)imageBrowser; 17 | 18 | // item所属data赋值 19 | - (id)imageBrowser:(YHImageBrowser *)imageBrowser dataForCellAtIndex:(NSUInteger)index; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Protocol/YHImageBrowserDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserDelegate.h 3 | // HiFanSmooth 4 | // 5 | // Created by 银河 on 2019/5/18. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | @class YHImageBrowser; 14 | @protocol YHImageBrowserDelegate 15 | @optional; 16 | 17 | /** 18 | * 索引发生变化的代理. 19 | */ 20 | - (void)imageBrowser:(YHImageBrowser *)imageBrowser pageIndexChanged:(NSUInteger)index; 21 | 22 | /** 23 | * YHImageBrowser长按. 24 | * 如果不实现该协议,长按时,框架内部使用默认的sheetView. 25 | */ 26 | - (void)imageBrowser:(YHImageBrowser *)imageBrowser longGesture:(UILongPressGestureRecognizer *)longGesture; 27 | 28 | /** 29 | * toolBar. 30 | * 如果不实现该协议,框架内部使用默认的toolBar. 31 | */ 32 | - (UIView *)viewForToolBarWithImageBrowser:(YHImageBrowser *)imageBrowser; 33 | 34 | /** 35 | * toolBar的高度. 36 | * 如果不实现该协议,框架内部将根据屏幕旋转方向选择合适的高度. 37 | */ 38 | - (CGFloat)heightForToolBarWithImageBrowser:(YHImageBrowser *)imageBrowser; 39 | 40 | /** 41 | * imageBrowser dismiss. 42 | */ 43 | - (void)imageBrowserDidDismiss:(YHImageBrowser *)imageBrowser; 44 | 45 | /** 46 | * imageBrowser的BottomView(与toolBar对应,在屏幕底部). 47 | */ 48 | - (UIView *)bottomViewForImageBrowser:(YHImageBrowser *)imageBrowser; 49 | 50 | /** 51 | * BottomView的高度. 52 | */ 53 | - (CGFloat)imageBrowser:(YHImageBrowser *)imageBrowser heightForBottomView:(CGFloat)heightForBottomView; 54 | 55 | /** 56 | * 当使用框架内部的SheetView时,点击"保存"的回调. 57 | */ 58 | - (void)imageBrowserSaveAction:(YHImageBrowser *)imageBrowser; 59 | 60 | @end 61 | 62 | NS_ASSUME_NONNULL_END 63 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Protocol/YHImageBrowserViewDataSource.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserViewDataSource.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/16. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "YHImageBrowserCellDataProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | @class YHImageBrowserView; 14 | /** 15 | * YHImageBrowserView数据源 16 | */ 17 | @protocol YHImageBrowserViewDataSource 18 | 19 | @required; 20 | 21 | // item个数 22 | - (NSUInteger)yh_numberOfCellForImageBrowserView:(YHImageBrowserView *)imageBrowserView; 23 | 24 | // item所属data赋值 25 | - (id)yh_imageBrowserView:(YHImageBrowserView *)imageBrowserView dataForCellAtIndex:(NSUInteger)index; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/Protocol/YHImageBrowserViewDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowserViewDelegate.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/16. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | /** 13 | * YHImageBrowserView代理 14 | */ 15 | @class YHImageBrowserView; 16 | @protocol YHImageBrowserViewDelegate 17 | /** 18 | * 索引发生变化的代理 19 | */ 20 | - (void)yh_imageBrowserView:(YHImageBrowserView *)browserView pageIndexChanged:(NSUInteger)index; 21 | 22 | /** 23 | * 开始pan手势的代理 24 | */ 25 | - (void)yh_willStartPanDownWithImageBrowserView:(YHImageBrowserView *)browserView; 26 | 27 | /** 28 | * pan手势导致alpha变化的代理 29 | */ 30 | - (void)yh_imageBrowserView:(YHImageBrowserView *)browserView didChangeAlpha:(CGFloat)alpha; 31 | 32 | /** 33 | * 重置由于pan手势导致的变化 34 | */ 35 | - (void)yh_imageBrowserView:(YHImageBrowserView *)browserView resetWithInterval:(NSTimeInterval)interval; 36 | 37 | /** 38 | * dismiss 39 | */ 40 | - (void)yh_imageBrowserView:(YHImageBrowserView *)browserView dismissWithInterval:(NSTimeInterval)interval; 41 | 42 | @end 43 | 44 | NS_ASSUME_NONNULL_END 45 | -------------------------------------------------------------------------------- /Sources/Core/ImageBrowser/YHImageBrowser.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageBrowser.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/16. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "YHImageBrowserCellDataProtocol.h" 11 | #import "YHImageBrowserCellData.h" 12 | #import "YHImageBrowserDelegate.h" 13 | #import "YHImageBrowserDataSource.h" 14 | #import "YHImageBrowserSheetView.h" 15 | #import "YHImage.h" 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface YHImageBrowser : UIView 20 | 21 | /** 22 | * 数据源设置方式1 23 | */ 24 | @property (nonatomic, strong) NSArray> *dataSourceArray; 25 | 26 | /** 27 | * 数据源设置方式2 28 | */ 29 | @property (nonatomic, weak) id dataSource; 30 | 31 | /** 32 | * 代理 33 | */ 34 | @property (nonatomic, weak) id delegate; 35 | 36 | /** 37 | * 图片保存到指定相册的名字 38 | */ 39 | @property (nonatomic, copy) NSString *saveAlbumName; 40 | 41 | /** 42 | * 当前索引所对应的data 43 | */ 44 | @property (nonatomic, strong, readonly) id currentData; 45 | 46 | /** 47 | * 当前索引 48 | * setter、getter 49 | */ 50 | @property (nonatomic, assign) int currentIndex; 51 | 52 | /** 53 | * sheetView 54 | */ 55 | @property (nonatomic, strong) YHImageBrowserSheetView *sheetView; 56 | 57 | 58 | - (instancetype)init; 59 | - (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; 60 | + (instancetype)new NS_UNAVAILABLE; 61 | 62 | /** 63 | * show 64 | */ 65 | - (void)show; 66 | 67 | /** 68 | * dismiss 69 | */ 70 | - (void)dismiss; 71 | 72 | @end 73 | 74 | NS_ASSUME_NONNULL_END 75 | -------------------------------------------------------------------------------- /Sources/Core/Location/YHLocation.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHLocation.h 3 | // Kit 4 | // 5 | // Created by 银河 on 2019/2/12. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface YHLocation : NSObject 15 | 16 | // System location. 17 | // 单次定位. 18 | // 使用中才定位. 19 | // 使用前请先调用requestLocationAuthorizationStatusWhenInUseWithTarget方法 20 | + (void)startLocationWithTarget:(id)target completionBlock:(void(^_Nullable)(CLPlacemark *_Nullable placemark, NSError *_Nullable error))completionBlock; 21 | 22 | // 获取当前的定位授权状态 23 | + (CLAuthorizationStatus)locationAuthorizationStatus; 24 | 25 | // 获取定位使用中的授权状态 26 | + (void)requestLocationAuthorizationStatusWhenInUseWithTarget:(id)target completionBlock:(void(^_Nullable)(BOOL granted, NSError *_Nullable error))completionBlock; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /Sources/Core/MB_HUD/YHMBHud.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHMBHud.h 3 | // YHKit_OC 4 | // 5 | // Created by 银河 on 2017/11/10. 6 | // Copyright © 2017年 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #if __has_include() 13 | #import 14 | #elif __has_include("MBProgressHUD.h") 15 | #import "MBProgressHUD.h" 16 | #endif 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | 21 | #if __has_include() || __has_include("MBProgressHUD.h") 22 | #define YH_MB_HUD_Tip(__tip__) [YHMBHud hudOnlyMessage:__tip__ inView:nil dismissBlock:nil]; // 黑 23 | #define YH_MB_White_HUD_Tip(__tip__) [YHMBHud hudOnlyMessage:__tip__ hudColor:[UIColor whiteColor] messageColor:[UIColor grayColor] inView:nil dismissBlock:nil]; 24 | #endif 25 | 26 | /** 27 | 此类是对MBProgressHUD的封装,要使用此类,请选择按照方法1或者方法2的方式引入 28 | 29 | 1、需要自行去从GitHub上下载MBProgressHUD,将"MBProgressHUD.h"和"MBProgressHUD.m"文件拖入工程中 30 | 2、pod 'MBProgressHUD' 31 | 32 | */ 33 | @interface YHMBHud : NSObject 34 | 35 | #if __has_include() || __has_include("MBProgressHUD.h") 36 | 37 | /** 38 | * 菊花旋转,提示信息可为空,view可为空 39 | * 请确保在主线程调用 40 | */ 41 | + (MBProgressHUD *)hudWithMessage:(NSString * _Nullable)message inView:(UIView * _Nullable)view; 42 | + (MBProgressHUD *)hudWithMessage:(NSString * _Nullable)message hudColor:(UIColor *)hudColor messageColor:(UIColor *)messageColor inView:(UIView * _Nullable)view; 43 | 44 | 45 | 46 | 47 | /** 48 | * 仅仅只有一段提示信息,一段时间后消失(默认1.5s消失) 49 | */ 50 | + (void)hudOnlyMessage:(NSString *)message inView:(UIView * _Nullable)view dismissBlock:(void(^ _Nullable)(void))dismissBlock; 51 | + (void)hudOnlyMessage:(NSString *)message hudColor:(UIColor *)hudColor messageColor:(UIColor *)messageColor inView:(UIView * _Nullable)view dismissBlock:(void(^ _Nullable)(void))dismissBlock; 52 | 53 | /** 54 | * 仅仅只有一段提示信息,一段时间后消失 55 | */ 56 | + (void)hudOnlyMessage:(NSString *)message inView:(UIView * _Nullable)view dismissTime:(NSTimeInterval)dismissTime dismissBlock:(void(^ _Nullable)(void))dismissBlock; 57 | 58 | 59 | /** 60 | * 在主线程隐藏hud 61 | */ 62 | + (void)hideHud:(MBProgressHUD *)hud; 63 | 64 | #endif 65 | @end 66 | 67 | NS_ASSUME_NONNULL_END 68 | -------------------------------------------------------------------------------- /Sources/Core/MB_HUD/YHMBHud.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHMBHud.m 3 | // YHKit_OC 4 | // 5 | // Created by 银河 on 2017/11/10. 6 | // Copyright © 2017年 银河. All rights reserved. 7 | // 8 | 9 | #import "YHMBHud.h" 10 | 11 | //HUD的背景颜色,默认黑色 12 | #define YHMBHUD_COLOR [UIColor blackColor] 13 | 14 | @implementation YHMBHud 15 | 16 | #if __has_include() || __has_include("MBProgressHUD.h") 17 | 18 | /** 菊花旋转,提示信息可为空,view可为空 */ 19 | + (MBProgressHUD *)hudWithMessage:(NSString *)message inView:(UIView *)view{ 20 | return [YHMBHud hudWithMessage:message hudColor:[YHMBHUD_COLOR colorWithAlphaComponent:1] messageColor:[UIColor whiteColor] inView:view]; 21 | } 22 | 23 | + (MBProgressHUD *)hudWithMessage:(NSString *)message hudColor:(UIColor *)hudColor messageColor:(UIColor *)messageColor inView:(UIView *)view{ 24 | NSAssert([NSThread isMainThread], @"MBProgressHUD must be in main thread."); 25 | UIView *tmpView = view; 26 | if (!view) { 27 | tmpView = [UIApplication sharedApplication].keyWindow; 28 | } 29 | MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:tmpView animated:YES];//必须在主线程,源码规定 30 | 31 | hud.mode = MBProgressHUDModeIndeterminate; 32 | hud.contentColor = messageColor; 33 | hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor; 34 | hud.bezelView.color = hudColor; 35 | hud.removeFromSuperViewOnHide = YES; 36 | if (message.length > 0) { 37 | hud.label.text = message; 38 | hud.label.numberOfLines = 0; 39 | } 40 | return hud; 41 | } 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | /** 仅仅只有一段提示信息,一段时间后消失 */ 63 | + (void)hudOnlyMessage:(NSString *)message inView:(UIView *)view dismissBlock:(void (^)(void))dismissBlock{ 64 | [YHMBHud hudOnlyMessage:message hudColor:[YHMBHUD_COLOR colorWithAlphaComponent:1] messageColor:[UIColor whiteColor] inView:view dismissTime:1.5 dismissBlock:dismissBlock]; 65 | } 66 | + (void)hudOnlyMessage:(NSString *)message inView:(UIView *)view dismissTime:(NSTimeInterval)dismissTime dismissBlock:(void (^)(void))dismissBlock{ 67 | [YHMBHud hudOnlyMessage:message hudColor:[YHMBHUD_COLOR colorWithAlphaComponent:1] messageColor:[UIColor whiteColor] inView:view dismissTime:dismissTime dismissBlock:dismissBlock]; 68 | } 69 | + (void)hudOnlyMessage:(NSString *)message hudColor:(UIColor *)hudColor messageColor:(UIColor *)messageColor inView:(UIView *)view dismissBlock:(void (^)(void))dismissBlock{ 70 | [YHMBHud hudOnlyMessage:message hudColor:hudColor messageColor:messageColor inView:view dismissTime:1.5 dismissBlock:dismissBlock]; 71 | } 72 | + (void)hudOnlyMessage:(NSString *)message hudColor:(UIColor *)hudColor messageColor:(UIColor *)messageColor inView:(UIView *)view dismissTime:(NSTimeInterval)dismissTime dismissBlock:(void (^)(void))dismissBlock{ 73 | dispatch_async(dispatch_get_main_queue(), ^{ 74 | if (!message || message.length == 0) { 75 | return; 76 | } 77 | UIView *tmpView = view; 78 | if (!view) { 79 | tmpView = [UIApplication sharedApplication].keyWindow; 80 | } 81 | 82 | MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:tmpView animated:YES];//必须在主线程,源码规定 83 | 84 | hud.mode = MBProgressHUDModeText; 85 | hud.contentColor = messageColor; 86 | hud.label.text = message; 87 | hud.label.numberOfLines = 0; 88 | hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor; 89 | hud.bezelView.color = hudColor; 90 | hud.removeFromSuperViewOnHide = YES; 91 | [hud hideAnimated:YES afterDelay:dismissTime];//必须在主线程,源码规定 92 | hud.completionBlock = dismissBlock; 93 | }); 94 | } 95 | 96 | // 在主线程隐藏hud 97 | + (void)hideHud:(MBProgressHUD *)hud{ 98 | if (!hud) { 99 | return; 100 | } 101 | dispatch_async(dispatch_get_main_queue(), ^{ 102 | [hud hideAnimated:YES]; 103 | }); 104 | } 105 | 106 | #endif 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /Sources/Core/Net/YHDownloadManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHDownloadManager.h 3 | // Meow 4 | // 5 | // Created by apple on 2019/2/16. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface YHDownloadManager : NSObject 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Sources/Core/Net/YHDownloadManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHDownloadManager.m 3 | // Meow 4 | // 5 | // Created by apple on 2019/2/16. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHDownloadManager.h" 10 | 11 | @implementation YHDownloadManager 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Sources/Core/Net/YHNet.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHNet.h 3 | // LocalDating 4 | // 5 | // Created by apple on 2019/2/15. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | typedef void(^YHHttpRequestProgressBlock)(CGFloat progress); 15 | typedef void(^YHHttpRequestSuccessBlock)(id responseObject); 16 | typedef void(^YHHttpRequestErrorBlock)(NSError *error); 17 | 18 | /** Request method */ 19 | typedef NS_ENUM(NSUInteger, YHHttpMethod) { 20 | YHHttpMethodPOST = 0, // POST 21 | YHHttpMethodGET = 1, // GET 22 | }; 23 | 24 | /** Request serializer type */ 25 | typedef NS_ENUM(NSUInteger, YHHttpRequestSerializerType) { 26 | YHHttpRequestSerializerTypeJSON = 0, // JSON 27 | YHHttpRequestSerializerTypeHTTP = 1, // HTTP 28 | }; 29 | 30 | /** Response serializer type */ 31 | typedef NS_ENUM(NSUInteger, YHHttpResponseSerializerType) { 32 | YHHttpResponseSerializerTypeJSON = 0, // JSON 33 | YHHttpResponseSerializerTypeHTTP = 1, // HTTP 34 | }; 35 | 36 | /** Network status **/ 37 | typedef NS_ENUM(NSUInteger, YHNetworkStatus) { 38 | YHNetworkStatus_Unkonwn, // 未知网络 39 | YHNetworkStatus_NotReachable, // 无网络连接 40 | YHNetworkStatus_ViaWWAN, // 移动网络(2G、3G、4G...) 41 | YHNetworkStatus_ViaWiFi, // WiFi 42 | }; 43 | 44 | @class YHUploadFileModel; 45 | @class AFHTTPRequestSerializer; 46 | @class AFJSONResponseSerializer; 47 | @class AFJSONRequestSerializer; 48 | @class AFHTTPResponseSerializer; 49 | @interface YHNet : NSObject 50 | 51 | + (YHNet *)sharedInstance; 52 | - (instancetype)init NS_UNAVAILABLE; 53 | + (instancetype)new NS_UNAVAILABLE; 54 | 55 | 56 | // 当前网络状态,会根据实际网络状态实时变化 57 | @property (nonatomic, assign, readonly) YHNetworkStatus networkStatus; 58 | @property (nonatomic, assign, readonly) BOOL isReachable; 59 | 60 | 61 | /// 开启网络监控 62 | - (void)startMonitoringNetwork; 63 | 64 | /// 关闭网络监控 65 | - (void)stopMonitoringNetwork; 66 | 67 | // HTTP请求 68 | - (nullable NSURLSessionDataTask *)httpRequestWithMethod:(YHHttpMethod)httpMethod 69 | url:(NSString *)url 70 | param:(nullable id)param 71 | headers:(nullable NSDictionary *)headers 72 | isUseHttps:(BOOL)isUseHttps 73 | requestSerializerType:(YHHttpRequestSerializerType)requestSerializerType 74 | responseSerializerType:(YHHttpResponseSerializerType)responseSerializerType 75 | progressBlock:(nullable YHHttpRequestProgressBlock)progressBlock 76 | successBlock:(nullable YHHttpRequestSuccessBlock)successBlock 77 | errorBlock:(nullable YHHttpRequestErrorBlock)errorBlock; 78 | 79 | 80 | // HTTP for json request and json response. 81 | - (nullable NSURLSessionDataTask *)httpCommonRequestWithMethod:(YHHttpMethod)httpMethod 82 | url:(NSString *)url 83 | param:(nullable id)param 84 | headers:(nullable NSDictionary *)headers 85 | isUseHttps:(BOOL)isUseHttps 86 | progressBlock:(nullable YHHttpRequestProgressBlock)progressBlock 87 | successBlock:(nullable YHHttpRequestSuccessBlock)successBlock 88 | errorBlock:(nullable YHHttpRequestErrorBlock)errorBlock; 89 | 90 | 91 | // POST上传方法 92 | - (nullable NSURLSessionDataTask *)uploadWithURL:(NSString *)url 93 | files:(NSArray *)files 94 | param:(nullable id)param 95 | headers:(nullable NSDictionary *)headers 96 | isUseHttps:(BOOL)isUseHttps 97 | progressBlock:(nullable YHHttpRequestProgressBlock)progressBlock 98 | successBlock:(nullable YHHttpRequestSuccessBlock)successBlock 99 | errorBlock:(nullable YHHttpRequestErrorBlock)errorBlock; 100 | 101 | // 取消某个网络请求 102 | - (void)cancelRequestWithTask:(nullable NSURLSessionDataTask *)task; 103 | 104 | // 根据URL取消某个网络请求 105 | // 此处的url为baseURL之后的相对路径 106 | - (void)cancelRequestWithURL:(nullable NSString *)url; 107 | 108 | // 取消所有的网络请求 109 | - (void)cancelAllRequest; 110 | 111 | @end 112 | 113 | 114 | 115 | @interface YHNet (YHRequestHTTP) 116 | + (AFHTTPRequestSerializer *)requestSerializerForHTTP; 117 | @end 118 | 119 | @interface YHNet (YHRequestJSON) 120 | + (AFJSONRequestSerializer *)requestSerializerForJSON; 121 | @end 122 | 123 | @interface YHNet (YHResponseHTTP) 124 | + (AFHTTPResponseSerializer *)responseSerializerForHTTP; 125 | @end 126 | 127 | 128 | @interface YHNet (YHResponseJSON) 129 | + (AFJSONResponseSerializer *)responseSerializerForJSON; 130 | @end 131 | 132 | 133 | 134 | 135 | @interface YHUploadFileModel : NSObject 136 | /** 137 | * name 138 | */ 139 | @property (nonatomic, copy) NSString *name; 140 | /** 141 | * 文件名 142 | */ 143 | @property (nonatomic, copy) NSString *fileName; 144 | /** 145 | * mimeType 146 | * image/jpeg、image/png 147 | */ 148 | @property (nonatomic, copy) NSString *mimeType; 149 | /** 150 | * 上传data(如果data和fileURL重复,则优先取data,如果data为空,则取fileURL,如果fileURL为空,如跳过上传此对象) 151 | */ 152 | @property (nonatomic, strong, nullable) NSData *data; 153 | /** 154 | * 本地文件路径 155 | */ 156 | @property (nonatomic, strong, nullable) NSURL *fileURL; 157 | 158 | @end 159 | 160 | 161 | 162 | 163 | 164 | 165 | NS_ASSUME_NONNULL_END 166 | -------------------------------------------------------------------------------- /Sources/Core/PhotoManager/YHPhotoManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHPhotoManager.h 3 | // HiFanSmooth 4 | // 5 | // Created by 银河 on 2019/5/19. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | @interface YHPhotoManager : NSObject 15 | 16 | /** 17 | * 检查某个相册是否存在,一般是自定义相册名 18 | */ 19 | + (void)checkAlbumIsExistWithAlbum:(NSString *)albumName completionBlock:(void(^)(BOOL isExist))completionBlock; 20 | 21 | /** 22 | * 创建一个自定义相册 23 | */ 24 | + (void)createAlbum:(NSString *)albumName completionBlock:(void(^)(BOOL isSuccess, PHAssetCollection *_Nullable assetCollection))completionBlock; 25 | 26 | /** 27 | * 根据相册名字获取PHAssetCollection相册实例,如果没有给定相册名字的相册,则会新建 28 | */ 29 | + (void)getAlbumWithAlbum:(NSString *)albumName completionBlock:(void(^)(PHAssetCollection *_Nullable assetCollection))completionBlock; 30 | 31 | /** 32 | * 把data存进相册,支持Image和GIF 33 | */ 34 | + (void)saveToPhotoAlbumWithAlbumName:(NSString *)albumName data:(NSData *)data completionBlock:(void(^_Nullable)(BOOL isSuccess, NSError *_Nullable error))completionBlock; 35 | 36 | /** 37 | * 把Image存进相册 38 | */ 39 | + (void)saveToPhotoAlbumWithAlbumName:(NSString *)albumName image:(UIImage *)image completionBlock:(void(^_Nullable)(BOOL isSuccess, NSError *_Nullable error))completionBlock; 40 | 41 | 42 | 43 | // 把图片压缩到指定尺寸 44 | + (nullable NSData *)compressImageWithImage1:(UIImage *)sourceImage toByte:(NSUInteger)maxSize; // 第一种方法 45 | + (nullable NSData *)compressImageWithImage2:(UIImage *)sourceImage toByte:(NSUInteger)maxSize; // 第二种方法 46 | 47 | 48 | 49 | @end 50 | 51 | NS_ASSUME_NONNULL_END 52 | -------------------------------------------------------------------------------- /Sources/Core/SendSMS/YHSendSMS.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHSendSMS.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/16. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface YHSendSMS : NSObject 16 | 17 | // Send SMS to some people. 18 | + (void)sendSmsWithPhones:(NSArray *)phones smsContent:(nullable NSString *)smsContent showVC:(UIViewController *)showVC completionBlock:(void(^_Nullable)(MessageComposeResult result, NSError *_Nullable error))completionBlock; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Sources/Core/SendSMS/YHSendSMS.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHSendSMS.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/16. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import "YHSendSMS.h" 10 | #import 11 | 12 | static char yh_send_sms_completion_key; 13 | static char yh_send_sms_associated_key; 14 | 15 | @interface YHSendSMS() 16 | @property (nonatomic, weak) UIViewController *showVC; 17 | @end 18 | 19 | @implementation YHSendSMS 20 | - (void)dealloc{ 21 | //NSLog(@"%@ dealloc",NSStringFromClass([self class])); 22 | } 23 | 24 | // Send SMS to some people. 25 | + (void)sendSmsWithPhones:(NSArray *)phones smsContent:(NSString *)smsContent showVC:(UIViewController *)showVC completionBlock:(void (^ _Nullable)(MessageComposeResult, NSError * _Nullable))completionBlock{ 26 | if ([MFMessageComposeViewController canSendText]) { 27 | YHSendSMS *sms = [[YHSendSMS alloc] init]; 28 | MFMessageComposeViewController * controller = [[MFMessageComposeViewController alloc] init]; 29 | controller.recipients = phones; 30 | controller.body = smsContent; 31 | controller.messageComposeDelegate = sms; 32 | controller.modalPresentationStyle = UIModalPresentationFullScreen; 33 | [showVC presentViewController:controller animated:YES completion:nil]; 34 | objc_setAssociatedObject(sms, &yh_send_sms_completion_key, completionBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); 35 | objc_setAssociatedObject(showVC, &yh_send_sms_associated_key, sms, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 36 | sms.showVC = showVC; 37 | } else { 38 | NSError *error = [NSError errorWithDomain:@"com.yinhe.sendSms" code:-1 userInfo:@{NSLocalizedDescriptionKey:@"该设备不支持发送短信."}]; 39 | completionBlock ? completionBlock(MessageComposeResultFailed, error) : nil; 40 | } 41 | } 42 | 43 | #pragma mark - MFMessageComposeViewControllerDelegate 44 | - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result{ 45 | [controller dismissViewControllerAnimated:YES completion:nil]; 46 | void(^block)(MessageComposeResult rt, NSError *_Nullable error) = objc_getAssociatedObject(self, &yh_send_sms_completion_key); 47 | block ? block(result, nil) : nil; 48 | objc_setAssociatedObject(self.showVC, &yh_send_sms_associated_key, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);// Remove associated. 49 | } 50 | @end 51 | -------------------------------------------------------------------------------- /Sources/Core/SystemImagePicker/YHSystemImagePicker.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHSystemImagePicker.h 3 | // FrameDating 4 | // 5 | // Created by apple on 2019/5/10. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | typedef NS_ENUM(NSUInteger, YHSystemImagePickerState) { 15 | YHSystemImagePicker_Allow, 16 | YHSystemImagePicker_PhotoDenied, 17 | YHSystemImagePicker_CameraDenied, 18 | YHSystemImagePicker_PhotoUnAvailable, 19 | YHSystemImagePicker_CameraUnAvailable, 20 | }; 21 | 22 | /** 23 | * 系统UIImagePickerController封装. 24 | */ 25 | @interface YHSystemImagePicker : NSObject 26 | 27 | 28 | /** 29 | 系统UIImagePickerController封装.(内部已实现授权) 30 | 31 | @param showVC present UIAlertController的控制器 32 | @param title UIAlertController的标题 33 | @param message UIAlertController的信息 34 | @param alblumTitle 相册标题 35 | @param cameraTitle 相机标题 36 | @param cancelTitle 取消标题 37 | @param completionBlock 回调 38 | */ 39 | + (void)showIn:(UIViewController *)showVC 40 | title:(nullable NSString *)title 41 | message:(nullable NSString *)message 42 | alblumTitle:(nullable NSString *)alblumTitle 43 | cameraTitle:(nullable NSString *)cameraTitle 44 | cancelTitle:(nullable NSString *)cancelTitle 45 | completionBlock:(void(^)(UIImage *_Nullable editImage, NSDictionary *_Nullable info, YHSystemImagePickerState state))completionBlock; 46 | 47 | @end 48 | 49 | NS_ASSUME_NONNULL_END 50 | -------------------------------------------------------------------------------- /Sources/Core/TimeCountDown/YHTimeCountDownManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHTimeCountDownManager.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/3/28. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | extern NSString *const kYHTimeCountDownNotification; // NotificationName 14 | 15 | extern NSString *const kYHTimeCountDownIdentifierKey; // identifier 16 | extern NSString *const kYHTimeCountDownIntervalKey; // interval 17 | extern NSString *const kYHTimeCountDownTimeIntervalKey; // timeInterval 18 | 19 | @interface YHTimeCountDownManager : NSObject 20 | 21 | + (instancetype)shareInstance; 22 | - (instancetype)init NS_UNAVAILABLE; 23 | + (instancetype)new NS_UNAVAILABLE; 24 | 25 | 26 | - (void)addTimeInterval:(NSTimeInterval)interval 27 | identifier:(NSString *)identifier; 28 | 29 | - (void)removeTimerIntervalWithIdentifer:(NSString *)identifier; 30 | - (void)removeAllTimer; 31 | 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /Sources/Core/TimeCountDown/YHTimeCountDownManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHTimeCountDownManager.m 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/3/28. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHTimeCountDownManager.h" 10 | #import 11 | 12 | NSString *const kYHTimeCountDownNotification = @"kYHTimeCountDownNotification"; 13 | 14 | NSString *const kYHTimeCountDownIdentifierKey = @"kYHTimeCountDownIdentifierKey"; 15 | NSString *const kYHTimeCountDownIntervalKey = @"kYHTimeCountDownIntervalKey"; 16 | NSString *const kYHTimeCountDownTimeIntervalKey = @"kYHTimeCountDownTimeIntervalKey"; 17 | 18 | 19 | // Model 20 | @interface YHTimeCountDownModel : NSObject 21 | @property (nonatomic, strong) dispatch_source_t timer; 22 | @property (nonatomic, copy) NSString *identifier; 23 | @property (nonatomic, assign) NSTimeInterval interval; 24 | @property (nonatomic, assign) NSTimeInterval timeInterval; 25 | @property (nonatomic, assign) BOOL isPause; 26 | @end 27 | 28 | 29 | @implementation YHTimeCountDownModel 30 | 31 | @end 32 | 33 | 34 | @interface YHTimeCountDownManager() 35 | @property (nonatomic, strong) NSMutableArray *timers; 36 | 37 | @property (nonatomic, assign) CFAbsoluteTime lastTime; 38 | @end 39 | 40 | @implementation YHTimeCountDownManager 41 | 42 | + (instancetype)shareInstance{ 43 | static YHTimeCountDownManager *instance = nil; 44 | static dispatch_once_t onceToken; 45 | dispatch_once(&onceToken, ^{ 46 | instance = [[self alloc] init]; 47 | }); 48 | return instance; 49 | } 50 | 51 | - (instancetype)init 52 | { 53 | self = [super init]; 54 | if (self) { 55 | self.timers = [NSMutableArray array]; 56 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; 57 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; 58 | } 59 | return self; 60 | } 61 | 62 | - (void)addTimeInterval:(NSTimeInterval)interval identifier:(NSString *)identifier{ 63 | __block BOOL isContain = NO; 64 | [self.timers enumerateObjectsUsingBlock:^(YHTimeCountDownModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 65 | if ([obj.identifier isEqualToString:identifier]) { 66 | isContain = YES; 67 | *stop = YES; 68 | } 69 | }]; 70 | if (isContain) { 71 | return; 72 | } 73 | 74 | YHTimeCountDownModel *model = [[YHTimeCountDownModel alloc] init]; 75 | model.identifier = identifier; 76 | model.interval = interval; 77 | model.timeInterval = 0; 78 | model.isPause = NO; 79 | 80 | __weak typeof(self) weakSelf = self; 81 | dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); 82 | dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, interval * NSEC_PER_SEC, 0 * NSEC_PER_SEC); 83 | dispatch_source_set_event_handler(timer, ^{ 84 | [weakSelf.timers enumerateObjectsUsingBlock:^(YHTimeCountDownModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 85 | if (obj.timer == timer) { 86 | obj.timeInterval += obj.interval; 87 | NSDictionary *info = @{kYHTimeCountDownIdentifierKey : obj.identifier, 88 | kYHTimeCountDownIntervalKey : @(obj.interval), 89 | kYHTimeCountDownTimeIntervalKey : @(obj.timeInterval)}; 90 | [[NSNotificationCenter defaultCenter] postNotificationName:kYHTimeCountDownNotification object:nil userInfo:info]; 91 | } 92 | }]; 93 | }); 94 | dispatch_resume(timer); 95 | 96 | 97 | model.timer = timer; 98 | 99 | [self.timers addObject:model]; 100 | } 101 | 102 | - (void)removeTimerIntervalWithIdentifer:(NSString *)identifier{ 103 | [self.timers enumerateObjectsUsingBlock:^(YHTimeCountDownModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 104 | if ([obj.identifier isEqualToString:identifier]) { 105 | dispatch_source_cancel(obj.timer); 106 | obj.timer = nil; 107 | [self.timers removeObject:obj]; 108 | *stop = YES; 109 | } 110 | }]; 111 | } 112 | 113 | - (void)removeAllTimer{ 114 | [self.timers enumerateObjectsUsingBlock:^(YHTimeCountDownModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 115 | dispatch_source_cancel(obj.timer); 116 | obj.timer = nil; 117 | }]; 118 | [self.timers removeAllObjects]; 119 | } 120 | 121 | 122 | #pragma mark ------------------ Notification ------------------ 123 | - (void)didEnterBackground:(NSNotification *)noti{ 124 | self.lastTime = CFAbsoluteTimeGetCurrent(); 125 | [self.timers enumerateObjectsUsingBlock:^(YHTimeCountDownModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 126 | if (!obj.isPause) { 127 | obj.isPause = YES; 128 | dispatch_suspend(obj.timer); 129 | } 130 | }]; 131 | } 132 | 133 | - (void)willEnterForeground:(NSNotification *)noti{ 134 | CFAbsoluteTime timeInterval = CFAbsoluteTimeGetCurrent() - self.lastTime; 135 | [self.timers enumerateObjectsUsingBlock:^(YHTimeCountDownModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 136 | obj.timeInterval += timeInterval; 137 | if (obj.isPause) { 138 | obj.isPause = NO; 139 | dispatch_resume(obj.timer); 140 | } 141 | }]; 142 | } 143 | @end 144 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/AppDelegate+YHNotiExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate+YHNotiExtension.h 3 | // Kit 4 | // 5 | // Created by apple on 2019/1/31. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | 10 | #if __has_include() 11 | 12 | #import "AppDelegate.h" 13 | 14 | 15 | 16 | @interface AppDelegate (YHNotiExtension) 17 | 18 | // 注册远程推送 19 | // 请在AppDelegate的 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{} 里面调用 20 | - (void)yh_registerRemoteNotificationWithOptions:(NSDictionary *)launchOptions NS_AVAILABLE_IOS(8_0); 21 | 22 | // 点击通知,远程通知的回调 23 | @property (nonatomic, copy) void(^yh_remoteNotiInfoBlock)(NSDictionary *_Nullable remoteNotiInfo); 24 | 25 | // 点击通知,本地通知的回调 26 | @property (nonatomic, copy) void(^yh_localNotiInfoBlock)(NSDictionary *_Nullable localNotiInfo); 27 | 28 | // 处理通知的回调,主要适用于第三方 29 | @property (nonatomic, copy) void(^yh_handleNotiInfoBlock)(NSDictionary *_Nullable notiInfo); 30 | 31 | // 成功注册通知,收到deviceToken的回调 32 | @property (nonatomic, copy) void(^yh_deviceTokenBlock)(NSString *deviceToken, NSData *deviceTokenData); 33 | 34 | @end 35 | 36 | #endif 37 | 38 | 39 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/UIButton+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIButton+YHExtension.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/15. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface UIButton (YHExtension) 14 | 15 | - (void)yh_addTapActionBlock:(void(^_Nullable)(void))tapActionBlock; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/UIButton+YHExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIButton+YHExtension.m 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/5/15. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "UIButton+YHExtension.h" 10 | #import 11 | 12 | static char yh_button_action_key; 13 | 14 | @implementation UIButton (YHExtension) 15 | 16 | - (void)yh_addTapActionBlock:(void (^)(void))tapActionBlock{ 17 | if (tapActionBlock) { 18 | objc_setAssociatedObject(self, &yh_button_action_key, tapActionBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); 19 | } 20 | [self addTarget:self action:@selector(tapAction) forControlEvents:UIControlEventTouchUpInside]; 21 | } 22 | 23 | - (void)tapAction{ 24 | void(^block)(void) = objc_getAssociatedObject(self, &yh_button_action_key); 25 | if (block) { 26 | block(); 27 | } 28 | } 29 | @end 30 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/UIDevice+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIDevice+YHExtension.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/2. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @interface UIDevice (YHExtension) 13 | 14 | 15 | // Get the device name. Such as 'iPhone 7 Plus'. 16 | @property (nonatomic, copy, readonly) NSString *yh_deviceName; 17 | 18 | 19 | /** 20 | * 是否是iPhone X系列手机(刘海屏手机) 21 | * 备用判断方法,要跟着Apple每年发布新版手机的变化而调整 22 | */ 23 | + (BOOL)yh_isIphoneX; 24 | 25 | @end 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/UIImage+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+YHExtension.h 3 | // Kit 4 | // 5 | // Created by apple on 2019/1/17. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @interface UIImage (YHExtension) 13 | 14 | // Color Transfer Picture. 15 | + (UIImage *)yh_imageWithColor:(UIColor *)color; 16 | 17 | @end 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/UIImage+YHExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+YHExtension.m 3 | // Kit 4 | // 5 | // Created by apple on 2019/1/17. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "UIImage+YHExtension.h" 10 | 11 | @implementation UIImage (YHExtension) 12 | 13 | // Color Transfer Picture. 14 | + (UIImage *)yh_imageWithColor:(UIColor *)color{ 15 | CGRect rect = CGRectMake(0.0f, 0.0f, 1, 1); 16 | UIGraphicsBeginImageContext(rect.size); 17 | CGContextRef context = UIGraphicsGetCurrentContext(); 18 | CGContextSetFillColorWithColor(context, [color CGColor]); 19 | CGContextFillRect(context, rect); 20 | UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext(); 21 | UIGraphicsEndImageContext(); 22 | return theImage; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/UINavigationController+YHRotationExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+YHRotationExtension.h 3 | // Kit 4 | // 5 | // Created by 银河 on 2019/1/31. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @interface UINavigationController (YHRotationExtension) 13 | 14 | @end 15 | NS_ASSUME_NONNULL_END 16 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/UINavigationController+YHRotationExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+YHRotationExtension.m 3 | // Kit 4 | // 5 | // Created by 银河 on 2019/1/31. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "UINavigationController+YHRotationExtension.h" 10 | 11 | @implementation UINavigationController (YHRotationExtension) 12 | 13 | //// 屏幕旋转以当前所在的navi或者VC为准 14 | //- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController{ 15 | // if ([rootViewController isKindOfClass:[UITabBarController class]]) { 16 | // UITabBarController *tabBarController = (UITabBarController*)rootViewController; 17 | // return [self topViewControllerWithRootViewController:tabBarController.selectedViewController]; 18 | // } else if (rootViewController.childViewControllers.count > 0) { 19 | // return [self topViewControllerWithRootViewController:rootViewController.childViewControllers.lastObject]; 20 | // } else if ([rootViewController isKindOfClass:[UINavigationController class]]) { 21 | // return ((UINavigationController *)rootViewController).viewControllers.lastObject; 22 | // } else { 23 | // return rootViewController; 24 | // } 25 | //} 26 | // 27 | //#pragma mark - StatusBar 28 | //- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation{ 29 | // UIViewController *vc = [self topViewControllerWithRootViewController:self]; 30 | // return vc.preferredStatusBarUpdateAnimation; 31 | //} 32 | //- (UIViewController *)childViewControllerForStatusBarStyle{ 33 | // UIViewController *vc = [self topViewControllerWithRootViewController:self]; 34 | // return vc; 35 | //} 36 | //- (UIViewController *)childViewControllerForStatusBarHidden{ 37 | // UIViewController *vc = [self topViewControllerWithRootViewController:self]; 38 | // return vc; 39 | //} 40 | //- (BOOL)shouldAutorotate{ 41 | // UIViewController *vc = [self topViewControllerWithRootViewController:self]; 42 | // return vc.shouldAutorotate; 43 | //} 44 | //- (UIInterfaceOrientationMask)supportedInterfaceOrientations{ 45 | // UIViewController *vc = [self topViewControllerWithRootViewController:self]; 46 | // return vc.supportedInterfaceOrientations; 47 | //} 48 | // 49 | // 50 | // 51 | ////这个方法感觉没怎么调用。。。。em...... 52 | //- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{ 53 | // UIViewController *vc = [self topViewControllerWithRootViewController:self]; 54 | // return vc.preferredInterfaceOrientationForPresentation; 55 | //} 56 | 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/UIView+YHFrame.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+YHFrame.h 3 | // chanDemo 4 | // 5 | // Created by 银河 on 2018/11/8. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @interface UIView (YHFrame) 13 | 14 | 15 | #pragma mark - Origin 16 | @property (nonatomic, assign) CGPoint yh_origin; 17 | @property (nonatomic, assign) CGFloat yh_x; 18 | @property (nonatomic, assign) CGFloat yh_y; 19 | 20 | 21 | #pragma mark - Size 22 | @property (nonatomic, assign) CGSize yh_size; 23 | @property (nonatomic, assign) CGFloat yh_width; 24 | @property (nonatomic, assign) CGFloat yh_height; 25 | 26 | #pragma mark - Center 27 | @property (nonatomic, assign) CGFloat yh_centerX; 28 | @property (nonatomic, assign) CGFloat yh_centerY; 29 | 30 | #pragma mark - Edge 31 | @property (nonatomic, assign) CGFloat yh_top; 32 | @property (nonatomic, assign) CGFloat yh_bottom; 33 | @property (nonatomic, assign) CGFloat yh_left; 34 | @property (nonatomic, assign) CGFloat yh_right; 35 | 36 | @end 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/UIView+YHFrame.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+YHFrame.m 3 | // chanDemo 4 | // 5 | // Created by 银河 on 2018/11/8. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "UIView+YHFrame.h" 10 | 11 | @implementation UIView (YHFrame) 12 | 13 | #pragma mark - origin 14 | - (CGPoint)yh_origin{ 15 | return self.frame.origin; 16 | } 17 | - (void)setYh_origin:(CGPoint)yh_origin{ 18 | CGRect frame = self.frame; 19 | frame.origin = yh_origin; 20 | self.frame = frame; 21 | } 22 | - (CGFloat)yh_x{ 23 | return self.frame.origin.x; 24 | } 25 | - (void)setYh_x:(CGFloat)yh_x{ 26 | CGRect frame = self.frame; 27 | frame.origin.x = yh_x; 28 | self.frame = frame; 29 | } 30 | - (CGFloat)yh_y{ 31 | return self.frame.origin.y; 32 | } 33 | - (void)setYh_y:(CGFloat)yh_y{ 34 | CGRect frame = self.frame; 35 | frame.origin.y = yh_y; 36 | self.frame = frame; 37 | } 38 | 39 | 40 | #pragma mark - Size 41 | - (CGSize)yh_size{ 42 | return self.frame.size; 43 | } 44 | - (void)setYh_size:(CGSize)yh_size{ 45 | CGRect frame = self.frame; 46 | frame.size = yh_size; 47 | self.frame = frame; 48 | } 49 | - (CGFloat)yh_width{ 50 | return self.frame.size.width; 51 | } 52 | - (void)setYh_width:(CGFloat)yh_width{ 53 | CGRect frame = self.frame; 54 | frame.size.width = yh_width; 55 | self.frame = frame; 56 | } 57 | - (CGFloat)yh_height{ 58 | return self.frame.size.height; 59 | } 60 | - (void)setYh_height:(CGFloat)yh_height{ 61 | CGRect frame = self.frame; 62 | frame.size.height = yh_height; 63 | self.frame = frame; 64 | } 65 | 66 | #pragma mark - Center 67 | - (CGFloat)yh_centerX{ 68 | return self.center.x; 69 | } 70 | - (void)setYh_centerX:(CGFloat)yh_centerX{ 71 | self.center = CGPointMake(yh_centerX, self.center.y); 72 | } 73 | - (CGFloat)yh_centerY{ 74 | return self.center.y; 75 | } 76 | - (void)setYh_centerY:(CGFloat)yh_centerY{ 77 | self.center = CGPointMake(self.center.x, yh_centerY); 78 | } 79 | 80 | #pragma mark - Edge 81 | - (CGFloat)yh_top{ 82 | return self.frame.origin.y; 83 | } 84 | - (void)setYh_top:(CGFloat)yh_top{ 85 | CGRect frame = self.frame; 86 | frame.origin.y = yh_top; 87 | self.frame = frame; 88 | } 89 | - (CGFloat)yh_bottom{ 90 | return self.frame.origin.y + self.frame.size.height; 91 | } 92 | - (void)setYh_bottom:(CGFloat)yh_bottom{ 93 | CGRect frame = self.frame; 94 | frame.origin.y = yh_bottom - self.frame.size.height; 95 | self.frame = frame; 96 | } 97 | - (CGFloat)yh_left{ 98 | return self.frame.origin.x; 99 | } 100 | - (void)setYh_left:(CGFloat)yh_left{ 101 | CGRect frame = self.frame; 102 | frame.origin.x = yh_left; 103 | self.frame = frame; 104 | } 105 | - (CGFloat)yh_right{ 106 | return self.frame.origin.x + self.frame.size.width; 107 | } 108 | - (void)setYh_right:(CGFloat)yh_right{ 109 | CGRect frame = self.frame; 110 | frame.origin.x = yh_right - self.frame.size.width; 111 | self.frame = frame; 112 | } 113 | 114 | 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/UIViewController+YHExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+YHExtension.h 3 | // Kit 4 | // 5 | // Created by apple on 2019/1/29. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface UIViewController (YHExtension) 14 | 15 | 16 | 17 | 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/UIViewController+YHExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+YHExtension.m 3 | // Kit 4 | // 5 | // Created by apple on 2019/1/29. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+YHExtension.h" 10 | 11 | @implementation UIViewController (YHExtension) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/YHTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHTextView.h 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/7/19. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface YHTextView : UITextView 14 | @property (nonatomic, strong) NSString *placeholder; 15 | @property (nonatomic, strong) UIColor *placeholderColor; 16 | @property (nonatomic, strong) UIFont *placeholderFont; 17 | 18 | @property (nonatomic, strong) NSMutableAttributedString *attributePlaceholder; 19 | 20 | @end 21 | 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Sources/Core/UIKit/YHTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHTextView.m 3 | // HiFanSmooth 4 | // 5 | // Created by apple on 2019/7/19. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YHTextView.h" 10 | 11 | @implementation YHTextView 12 | 13 | - (void)dealloc{ 14 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:nil]; 15 | } 16 | 17 | - (instancetype)initWithFrame:(CGRect)frame 18 | { 19 | self = [super initWithFrame:frame]; 20 | if (self) { 21 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange:) name:UITextViewTextDidChangeNotification object:self]; 22 | } 23 | return self; 24 | } 25 | 26 | - (void)textDidChange:(NSNotification *)note{ 27 | [self setNeedsDisplay]; 28 | } 29 | 30 | 31 | - (void)drawRect:(CGRect)rect{ 32 | if (self.text.length > 0) { 33 | return; 34 | } 35 | 36 | CGRect rt = CGRectMake(self.contentInset.left + 5, self.contentInset.top + 8, self.frame.size.width - self.contentInset.left - self.contentInset.right - 5 - 5, self.frame.size.height - self.contentInset.top - self.contentInset.bottom - 8 - 8); 37 | 38 | if (self.attributePlaceholder) { 39 | [self.attributePlaceholder drawWithRect:rt options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil]; 40 | } else if (self.placeholder) { 41 | NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:self.placeholder]; 42 | if (self.placeholderFont) { 43 | [attr addAttribute:NSFontAttributeName value:self.placeholderFont range:NSMakeRange(0, self.placeholder.length)]; 44 | } 45 | if (self.placeholderColor) { 46 | [attr addAttribute:NSForegroundColorAttributeName value:self.placeholderColor range:NSMakeRange(0, self.placeholder.length)]; 47 | } 48 | [attr drawWithRect:rt options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil]; 49 | } 50 | } 51 | 52 | - (void)layoutSubviews{ 53 | [super layoutSubviews]; 54 | [self setNeedsDisplay]; 55 | } 56 | 57 | - (void)setPlaceholder:(NSString *)placeholder{ 58 | _placeholder = placeholder; 59 | [self setNeedsDisplay]; 60 | } 61 | 62 | - (void)setPlaceholderFont:(UIFont *)placeholderFont{ 63 | _placeholderFont = placeholderFont; 64 | [self setNeedsDisplay]; 65 | } 66 | 67 | - (void)setPlaceholderColor:(UIColor *)placeholderColor{ 68 | _placeholderColor = placeholderColor; 69 | [self setNeedsDisplay]; 70 | } 71 | 72 | - (void)setAttributePlaceholder:(NSMutableAttributedString *)attributePlaceholder{ 73 | _attributePlaceholder = attributePlaceholder; 74 | [self setNeedsDisplay]; 75 | } 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHBaseViewChainModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHBaseViewChainModel.h 3 | // chanDemo 4 | // 5 | // Created by 银河 on 2018/11/7. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | //__covariant:协变 程序中的对象应该是可以在不改变程序正确性的前提下被它的子类所替换的 13 | //__contravariant:逆变 父类可以强制转为子类 14 | //NSArray就使用了__covariant修饰符 15 | //__kindof:表示其中的类型为该类型或者其子类 16 | NS_ASSUME_NONNULL_BEGIN 17 | @interface YHBaseViewChainModel <__covariant ObjcType> : NSObject 18 | 19 | @property (nonatomic, strong, readonly) __kindof UIView *view; 20 | 21 | - (instancetype)initWithView:(__kindof UIView *)view; 22 | 23 | #pragma mark - 24 | /** 25 | * improves the readability 26 | */ 27 | @property (nonatomic, copy, readonly) ObjcType with; 28 | 29 | #pragma mark - view 30 | @property (nonatomic, copy, readonly) ObjcType (^frame)(CGRect frame); 31 | @property (nonatomic, copy, readonly) ObjcType (^backgroundColor)(UIColor *backgroundColor); 32 | @property (nonatomic, copy, readonly) ObjcType (^alpha)(CGFloat alpha); 33 | @property (nonatomic, copy, readonly) ObjcType (^hidden)(BOOL hidden); 34 | @property (nonatomic, copy, readonly) ObjcType (^clipsToBounds)(BOOL clipsToBounds); 35 | @property (nonatomic, copy, readonly) ObjcType (^contentMode)(UIViewContentMode contentMode); 36 | @property (nonatomic, copy, readonly) ObjcType (^tintColor)(UIColor *tintColor); 37 | @property (nonatomic, copy, readonly) ObjcType (^userInteractionEnabled)(BOOL userInteractionEnabled); 38 | #pragma mark - Layer 39 | @property (nonatomic, copy, readonly) ObjcType (^cornerRadius)(CGFloat cornerRadius); 40 | @property (nonatomic, copy, readonly) ObjcType (^maskToBounds)(BOOL maskToBounds); 41 | @property (nonatomic, copy, readonly) ObjcType (^borderWidth)(CGFloat borderWidth); 42 | @property (nonatomic, copy, readonly) ObjcType (^borderColor)(UIColor *borderColor); 43 | @property (nonatomic, copy, readonly) ObjcType (^shadowOffset)(CGSize shadowOffset); 44 | @property (nonatomic, copy, readonly) ObjcType (^shadowRadius)(CGFloat shadowRadius); 45 | @property (nonatomic, copy, readonly) ObjcType (^shadowColor)(UIColor *shadowColor); 46 | @property (nonatomic, copy, readonly) ObjcType (^shadowOpacity)(CGFloat shadowOpacity); 47 | 48 | 49 | @end 50 | NS_ASSUME_NONNULL_END 51 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHBaseViewChainModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHBaseViewChainModel.m 3 | // chanDemo 4 | // 5 | // Created by 银河 on 2018/11/7. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHBaseViewChainModel.h" 10 | 11 | 12 | @interface YHBaseViewChainModel() 13 | @property (nonatomic, strong) __kindof UIView *view; 14 | @end 15 | 16 | @implementation YHBaseViewChainModel 17 | 18 | - (instancetype)initWithView:(__kindof UIView *)view 19 | { 20 | self = [super init]; 21 | if (self) { 22 | self.view = view; 23 | } 24 | return self; 25 | } 26 | #pragma mark - 27 | - (id)with{ 28 | return self; 29 | } 30 | 31 | #pragma mark - 32 | - (id _Nonnull (^)(CGRect))frame{ 33 | __weak typeof(self) weakSelf = self; 34 | return ^id (CGRect frame) { 35 | weakSelf.view.frame = frame; 36 | return weakSelf; 37 | }; 38 | } 39 | 40 | - (id _Nonnull (^)(UIColor * _Nonnull))backgroundColor{ 41 | __weak typeof(self) weakSelf = self; 42 | return ^id (UIColor *backgroundColor) { 43 | weakSelf.view.backgroundColor = backgroundColor; 44 | return weakSelf; 45 | }; 46 | } 47 | - (id _Nonnull (^)(CGFloat))alpha{ 48 | __weak typeof(self) weakSelf = self; 49 | return ^id (CGFloat alpha) { 50 | weakSelf.view.alpha = alpha; 51 | return weakSelf; 52 | }; 53 | } 54 | - (id _Nonnull (^)(BOOL))hidden{ 55 | __weak typeof(self) weakSelf = self; 56 | return ^id (BOOL hidden) { 57 | weakSelf.view.hidden = hidden; 58 | return weakSelf; 59 | }; 60 | } 61 | - (id _Nonnull (^)(BOOL))clipsToBounds{ 62 | __weak typeof(self) weakSelf = self; 63 | return ^id (BOOL clipsToBounds) { 64 | weakSelf.view.clipsToBounds = clipsToBounds; 65 | return weakSelf; 66 | }; 67 | } 68 | - (id _Nonnull (^)(UIViewContentMode))contentMode{ 69 | __weak typeof(self) weakSelf = self; 70 | return ^id (UIViewContentMode contentMode) { 71 | weakSelf.view.contentMode = contentMode; 72 | return weakSelf; 73 | }; 74 | } 75 | - (id _Nonnull (^)(UIColor *))tintColor{ 76 | __weak typeof(self) weakSelf = self; 77 | return ^id (UIColor *tintColor) { 78 | weakSelf.view.tintColor = tintColor; 79 | return weakSelf; 80 | }; 81 | } 82 | - (id _Nonnull (^)(BOOL))userInteractionEnabled{ 83 | __weak typeof(self) weakSelf = self; 84 | return ^id (BOOL userInteractionEnabled) { 85 | weakSelf.view.userInteractionEnabled = userInteractionEnabled; 86 | return weakSelf; 87 | }; 88 | } 89 | #pragma mark - Layer 90 | - (id _Nonnull (^)(CGFloat))cornerRadius{ 91 | __weak typeof(self) weakSelf = self; 92 | return ^id (CGFloat cornerRadius) { 93 | weakSelf.view.layer.cornerRadius = cornerRadius; 94 | return weakSelf; 95 | }; 96 | } 97 | - (id _Nonnull (^)(BOOL))maskToBounds{ 98 | __weak typeof(self) weakSelf = self; 99 | return ^id (BOOL maskToBounds) { 100 | weakSelf.view.layer.masksToBounds = maskToBounds; 101 | return weakSelf; 102 | }; 103 | } 104 | 105 | - (id _Nonnull (^)(CGFloat))borderWidth{ 106 | __weak typeof(self) weakSelf = self; 107 | return ^id (CGFloat borderWidth) { 108 | weakSelf.view.layer.borderWidth = borderWidth; 109 | return weakSelf; 110 | }; 111 | } 112 | - (id _Nonnull (^)(UIColor * _Nonnull))borderColor{ 113 | __weak typeof(self) weakSelf = self; 114 | return ^id (UIColor *borderColor) { 115 | weakSelf.view.layer.borderColor = borderColor.CGColor; 116 | return weakSelf; 117 | }; 118 | } 119 | - (id _Nonnull (^)(CGSize))shadowOffset{ 120 | __weak typeof(self) weakSelf = self; 121 | return ^id (CGSize shadowOffset) { 122 | weakSelf.view.layer.shadowOffset = shadowOffset; 123 | return weakSelf; 124 | }; 125 | } 126 | - (id _Nonnull (^)(CGFloat))shadowRadius{ 127 | __weak typeof(self) weakSelf = self; 128 | return ^id (CGFloat shadowRadius) { 129 | weakSelf.view.layer.shadowRadius = shadowRadius; 130 | return weakSelf; 131 | }; 132 | } 133 | - (id _Nonnull (^)(UIColor * _Nonnull))shadowColor{ 134 | __weak typeof(self) weakSelf = self; 135 | return ^id (UIColor * shadowColor) { 136 | weakSelf.view.layer.shadowColor = shadowColor.CGColor; 137 | return weakSelf; 138 | }; 139 | } 140 | - (id _Nonnull (^)(CGFloat))shadowOpacity{ 141 | __weak typeof(self) weakSelf = self; 142 | return ^id (CGFloat shadowOpacity) { 143 | weakSelf.view.layer.shadowOpacity = shadowOpacity; 144 | return weakSelf; 145 | }; 146 | } 147 | @end 148 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHButtonChainModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHButtonChainModel.h 3 | // chanDemo 4 | // 5 | // Created by 银河 on 2018/11/9. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHBaseViewChainModel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @class YHButtonChainModel; 13 | @interface YHButtonChainModel : YHBaseViewChainModel 14 | 15 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^title)(NSString *title); 16 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^titleHL)(NSString *titleHL); 17 | 18 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^titleColor)(UIColor *titleColor); 19 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^titleColorHL)(UIColor *titleColorHL); 20 | 21 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^image)(UIImage *image); 22 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^imageHL)(UIImage *imageHL); 23 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^imageSelected)(UIImage *imageSelected); 24 | 25 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^backgroundImage)(UIImage *backgroundImage); 26 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^backgroundImageHL)(UIImage *backgroundImageHL); 27 | 28 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^backgroundImageColor)(UIColor *backgroundImageColor); 29 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^backgroundImageColorHL)(UIColor *backgroundImageColorHL); 30 | 31 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^attributedTitle)(NSAttributedString *attributedTitle); 32 | 33 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^titleFont)(UIFont *titleFont); 34 | 35 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^contentVAlign)(UIControlContentVerticalAlignment contentVAlign); 36 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^contentHAlign)(UIControlContentHorizontalAlignment contentHAlign); 37 | 38 | 39 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^contentEdgeInsets)(UIEdgeInsets contentEdgeInsets); 40 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^titleEdgeInsets)(UIEdgeInsets titleEdgeInsets); 41 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^imageEdgeInsets)(UIEdgeInsets imageEdgeInsets); 42 | 43 | 44 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^selected)(BOOL selected); 45 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^highlighted)(BOOL highlighted); 46 | 47 | @property (nonatomic, copy, readonly) YHButtonChainModel *(^adjustsFontSizeToFitWidth)(BOOL adjustsFontSizeToFitWidth); 48 | 49 | @end 50 | 51 | 52 | @interface UIButton (YH_Chain) 53 | @property (nonatomic, copy, readonly) YHButtonChainModel *yh_buttonChain; 54 | + (YHButtonChainModel *)yh_system_creat; 55 | + (YHButtonChainModel *)yh_custom_creat; 56 | @end 57 | NS_ASSUME_NONNULL_END 58 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHImageViewChainModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageViewChainModel.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2018/11/12. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHBaseViewChainModel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @class YHImageViewChainModel; 13 | @interface YHImageViewChainModel : YHBaseViewChainModel 14 | 15 | @property (nonatomic, copy, readonly) YHImageViewChainModel *(^image)(UIImage *image); 16 | @property (nonatomic, copy, readonly) YHImageViewChainModel *(^imageHL)(UIImage *imageHL); 17 | 18 | @end 19 | 20 | @interface UIImageView (YH_Chain) 21 | @property (nonatomic, copy, readonly) YHImageViewChainModel *yh_imageViewChain; 22 | + (YHImageViewChainModel *)yh_creat; 23 | @end 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHImageViewChainModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHImageViewChainModel.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2018/11/12. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHImageViewChainModel.h" 10 | 11 | #define YH_IMAGEVIEW ((UIImageView *)weakSelf.view) 12 | 13 | @implementation YHImageViewChainModel 14 | - (YHImageViewChainModel * _Nonnull (^)(UIImage * _Nonnull))image{ 15 | __weak typeof(self) weakSelf = self; 16 | return ^YHImageViewChainModel * (UIImage *image) { 17 | YH_IMAGEVIEW.image = image; 18 | return weakSelf; 19 | }; 20 | } 21 | - (YHImageViewChainModel * _Nonnull (^)(UIImage * _Nonnull))imageHL{ 22 | __weak typeof(self) weakSelf = self; 23 | return ^YHImageViewChainModel * (UIImage *imageHL) { 24 | YH_IMAGEVIEW.highlightedImage = imageHL; 25 | return weakSelf; 26 | }; 27 | } 28 | 29 | @end 30 | 31 | 32 | @implementation UIImageView (YH_Chain) 33 | - (YHImageViewChainModel *)yh_imageViewChain{ 34 | return [[YHImageViewChainModel alloc] initWithView:self]; 35 | } 36 | + (YHImageViewChainModel *)yh_creat{ 37 | UIImageView *imageView = [[UIImageView alloc] init]; 38 | return [[YHImageViewChainModel alloc] initWithView:imageView]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHLabelChainModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHLabelChainModel.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2018/11/8. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHBaseViewChainModel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @class YHLabelChainModel; 13 | ///必须加上,因为父类用了泛型 14 | @interface YHLabelChainModel : YHBaseViewChainModel 15 | 16 | @property (nonatomic, copy, readonly) YHLabelChainModel *(^text)(NSString *text); 17 | @property (nonatomic, copy, readonly) YHLabelChainModel *(^textColor)(UIColor *textColor); 18 | @property (nonatomic, copy, readonly) YHLabelChainModel *(^textAlignment)(NSTextAlignment alignment); 19 | @property (nonatomic, copy, readonly) YHLabelChainModel *(^font)(UIFont *font); 20 | @property (nonatomic, copy, readonly) YHLabelChainModel *(^numberOfLines)(NSInteger numberOfLines); 21 | @property (nonatomic, copy, readonly) YHLabelChainModel *(^lineBreakMode)(NSLineBreakMode lineBreakMode); 22 | @property (nonatomic, copy, readonly) YHLabelChainModel *(^adjustsFontSizeToFitWidth)(BOOL adjustsFontSizeToFitWidth); 23 | @property (nonatomic, copy, readonly) YHLabelChainModel *(^attributedText)(NSAttributedString *attributedText); 24 | 25 | @end 26 | 27 | 28 | @interface UILabel (YH_Chain) 29 | @property (nonatomic, copy, readonly) YHLabelChainModel *yh_labelChain; 30 | + (YHLabelChainModel *)yh_creat; 31 | @end 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHLabelChainModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHLabelChainModel.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2018/11/8. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHLabelChainModel.h" 10 | 11 | @implementation YHLabelChainModel 12 | 13 | - (YHLabelChainModel * _Nonnull (^)(NSString * _Nonnull))text{ 14 | __weak typeof(self) weakSelf = self; 15 | return ^YHLabelChainModel * (NSString *text) { 16 | ((UILabel *)weakSelf.view).text = text; 17 | return weakSelf; 18 | }; 19 | } 20 | - (YHLabelChainModel * _Nonnull (^)(NSTextAlignment))textAlignment{ 21 | __weak typeof(self) weakSelf = self; 22 | return ^YHLabelChainModel * (NSTextAlignment textAlignment) { 23 | ((UILabel *)weakSelf.view).textAlignment = textAlignment; 24 | return weakSelf; 25 | }; 26 | } 27 | - (YHLabelChainModel * _Nonnull (^)(UIColor * _Nonnull))textColor{ 28 | __weak typeof(self) weakSelf = self; 29 | return ^YHLabelChainModel * (UIColor *textColor) { 30 | ((UILabel *)weakSelf.view).textColor = textColor; 31 | return weakSelf; 32 | }; 33 | } 34 | - (YHLabelChainModel * _Nonnull (^)(UIFont * _Nonnull))font{ 35 | __weak typeof(self) weakSelf = self; 36 | return ^YHLabelChainModel * (UIFont *font) { 37 | ((UILabel *)weakSelf.view).font = font; 38 | return weakSelf; 39 | }; 40 | } 41 | - (YHLabelChainModel * _Nonnull (^)(NSInteger))numberOfLines{ 42 | __weak typeof(self) weakSelf = self; 43 | return ^YHLabelChainModel * (NSInteger numberOfLines) { 44 | ((UILabel *)weakSelf.view).numberOfLines = numberOfLines; 45 | return weakSelf; 46 | }; 47 | } 48 | - (YHLabelChainModel * _Nonnull (^)(NSLineBreakMode))lineBreakMode{ 49 | __weak typeof(self) weakSelf = self; 50 | return ^YHLabelChainModel * (NSLineBreakMode lineBreakMode) { 51 | ((UILabel *)weakSelf.view).lineBreakMode = lineBreakMode; 52 | return weakSelf; 53 | }; 54 | } 55 | - (YHLabelChainModel * _Nonnull (^)(BOOL))adjustsFontSizeToFitWidth{ 56 | __weak typeof(self) weakSelf = self; 57 | return ^YHLabelChainModel * (BOOL adjustsFontSizeToFitWidth) { 58 | ((UILabel *)weakSelf.view).adjustsFontSizeToFitWidth = adjustsFontSizeToFitWidth; 59 | return weakSelf; 60 | }; 61 | } 62 | - (YHLabelChainModel * _Nonnull (^)(NSAttributedString * _Nonnull))attributedText{ 63 | __weak typeof(self) weakSelf = self; 64 | return ^YHLabelChainModel * (NSAttributedString *attributedText) { 65 | ((UILabel *)weakSelf.view).attributedText = attributedText; 66 | return weakSelf; 67 | }; 68 | } 69 | @end 70 | 71 | 72 | 73 | 74 | 75 | @implementation UILabel (YH_Chain) 76 | - (YHLabelChainModel *)yh_labelChain{ 77 | return [[YHLabelChainModel alloc] initWithView:self]; 78 | } 79 | + (YHLabelChainModel *)yh_creat{ 80 | UILabel *label = [[UILabel alloc] init]; 81 | return [[YHLabelChainModel alloc] initWithView:label]; 82 | } 83 | @end 84 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHScrollViewChainModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHScrollViewChainModel.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2018/11/13. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHBaseViewChainModel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @class YHScrollViewChainModel; 13 | @interface YHScrollViewChainModel : YHBaseViewChainModel 14 | 15 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *(^delegate)(id); 16 | 17 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *(^contentSize)(CGSize contentSize); 18 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *(^contentOffset)(CGPoint contentOffset); 19 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *(^contentInset)(UIEdgeInsets contentInset); 20 | 21 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *(^bounces)(BOOL bounces); 22 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *(^alwaysBounceVertical)(BOOL alwaysBounceVertical); 23 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *(^alwaysBounceHorizontal)(BOOL alwaysBounceHorizontal); 24 | 25 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *(^pagingEnabled)(BOOL pagingEnabled); 26 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *(^scrollEnabled)(BOOL scrollEnabled); 27 | 28 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *(^showsHorizontalScrollIndicator)(BOOL showsHorizontalScrollIndicator); 29 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *(^showsVerticalScrollIndicator)(BOOL showsVerticalScrollIndicator); 30 | 31 | @end 32 | 33 | 34 | 35 | 36 | @interface UIScrollView (YH_Chain) 37 | @property (nonatomic, copy, readonly) YHScrollViewChainModel *yh_scrollChain; 38 | + (YHScrollViewChainModel *)yh_creat; 39 | @end 40 | NS_ASSUME_NONNULL_END 41 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHScrollViewChainModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHScrollViewChainModel.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2018/11/13. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHScrollViewChainModel.h" 10 | 11 | #define YH_SCROLLVIEW ((UIScrollView *)weakSelf.view) 12 | 13 | @implementation YHScrollViewChainModel 14 | 15 | - (YHScrollViewChainModel * _Nonnull (^)(id _Nonnull))delegate{ 16 | __weak typeof(self) weakSelf = self; 17 | return ^YHScrollViewChainModel * (id delegate) { 18 | YH_SCROLLVIEW.delegate = delegate; 19 | return weakSelf; 20 | }; 21 | } 22 | - (YHScrollViewChainModel * _Nonnull (^)(CGSize))contentSize{ 23 | __weak typeof(self) weakSelf = self; 24 | return ^YHScrollViewChainModel * (CGSize contentSize) { 25 | YH_SCROLLVIEW.contentSize = contentSize; 26 | return weakSelf; 27 | }; 28 | } 29 | - (YHScrollViewChainModel * _Nonnull (^)(CGPoint))contentOffset{ 30 | __weak typeof(self) weakSelf = self; 31 | return ^YHScrollViewChainModel * (CGPoint contentOffset) { 32 | YH_SCROLLVIEW.contentOffset = contentOffset; 33 | return weakSelf; 34 | }; 35 | } 36 | - (YHScrollViewChainModel * _Nonnull (^)(UIEdgeInsets))contentInset{ 37 | __weak typeof(self) weakSelf = self; 38 | return ^YHScrollViewChainModel * (UIEdgeInsets contentInset) { 39 | YH_SCROLLVIEW.contentInset = contentInset; 40 | return weakSelf; 41 | }; 42 | } 43 | - (YHScrollViewChainModel * _Nonnull (^)(BOOL))bounces{ 44 | __weak typeof(self) weakSelf = self; 45 | return ^YHScrollViewChainModel * (BOOL bounces) { 46 | YH_SCROLLVIEW.bounces = bounces; 47 | return weakSelf; 48 | }; 49 | } 50 | - (YHScrollViewChainModel * _Nonnull (^)(BOOL))alwaysBounceVertical{ 51 | __weak typeof(self) weakSelf = self; 52 | return ^YHScrollViewChainModel * (BOOL alwaysBounceVertical) { 53 | YH_SCROLLVIEW.alwaysBounceVertical = alwaysBounceVertical; 54 | return weakSelf; 55 | }; 56 | } 57 | - (YHScrollViewChainModel * _Nonnull (^)(BOOL))alwaysBounceHorizontal{ 58 | __weak typeof(self) weakSelf = self; 59 | return ^YHScrollViewChainModel * (BOOL alwaysBounceHorizontal) { 60 | YH_SCROLLVIEW.alwaysBounceHorizontal = alwaysBounceHorizontal; 61 | return weakSelf; 62 | }; 63 | } 64 | - (YHScrollViewChainModel * _Nonnull (^)(BOOL))pagingEnabled{ 65 | __weak typeof(self) weakSelf = self; 66 | return ^YHScrollViewChainModel * (BOOL pagingEnabled) { 67 | YH_SCROLLVIEW.pagingEnabled = pagingEnabled; 68 | return weakSelf; 69 | }; 70 | } 71 | - (YHScrollViewChainModel * _Nonnull (^)(BOOL))scrollEnabled{ 72 | __weak typeof(self) weakSelf = self; 73 | return ^YHScrollViewChainModel * (BOOL scrollEnabled) { 74 | YH_SCROLLVIEW.scrollEnabled = scrollEnabled; 75 | return weakSelf; 76 | }; 77 | } 78 | - (YHScrollViewChainModel * _Nonnull (^)(BOOL))showsHorizontalScrollIndicator{ 79 | __weak typeof(self) weakSelf = self; 80 | return ^YHScrollViewChainModel * (BOOL showsHorizontalScrollIndicator) { 81 | YH_SCROLLVIEW.showsHorizontalScrollIndicator = showsHorizontalScrollIndicator; 82 | return weakSelf; 83 | }; 84 | } 85 | - (YHScrollViewChainModel * _Nonnull (^)(BOOL))showsVerticalScrollIndicator{ 86 | __weak typeof(self) weakSelf = self; 87 | return ^YHScrollViewChainModel * (BOOL showsVerticalScrollIndicator) { 88 | YH_SCROLLVIEW.showsVerticalScrollIndicator = showsVerticalScrollIndicator; 89 | return weakSelf; 90 | }; 91 | } 92 | 93 | 94 | 95 | 96 | 97 | @end 98 | 99 | 100 | 101 | 102 | @implementation UIScrollView (YH_Chain) 103 | - (YHScrollViewChainModel *)yh_scrollChain{ 104 | return [[YHScrollViewChainModel alloc] initWithView:self]; 105 | } 106 | + (YHScrollViewChainModel *)yh_creat{ 107 | UIScrollView *scrollView = [[UIScrollView alloc] init]; 108 | return [[YHScrollViewChainModel alloc] initWithView:scrollView]; 109 | } 110 | @end 111 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHTextFieldChainModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHTextFieldChainModel.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2018/11/13. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHBaseViewChainModel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @class YHTextFieldChainModel; 13 | @interface YHTextFieldChainModel : YHBaseViewChainModel 14 | 15 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^text)(NSString *text); 16 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^font)(UIFont *font); 17 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^textColor)(UIColor *textColor); 18 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^textAlignment)(NSTextAlignment textAlignment); 19 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^borderStyle)(UITextBorderStyle borderStyle); 20 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^placeholder)(NSString *placeholder); 21 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^attributedPlaceholder)(NSAttributedString *attributedPlaceholder); 22 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^keyboardType)(UIKeyboardType keyboardType); 23 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^clearsOnBeginEditing)(BOOL clearsOnBeginEditing); 24 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^adjustsFontSizeToFitWidth)(BOOL adjustsFontSizeToFitWidth); 25 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^minimumFontSize)(CGFloat minimumFontSize); 26 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^delegate)(id delegate); 27 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^clearButtonMode)(UITextFieldViewMode clearButtonMode); 28 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^secureTextEntry)(BOOL secureTextEntry); 29 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^returnKeyType)(UIReturnKeyType returnKeyType); 30 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^enablesReturnKeyAutomatically)(BOOL enablesReturnKeyAutomatically); 31 | 32 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^leftView)(UIView *leftView); 33 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^rightView)(UIView *rightView); 34 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^leftViewMode)(UITextFieldViewMode leftViewMode); 35 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^rightViewMode)(UITextFieldViewMode rightViewMode); 36 | 37 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^inputView)(UIView *inputView); 38 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *(^inputAccessoryView)(UIView *inputAccessoryView); 39 | 40 | 41 | @end 42 | 43 | 44 | @interface UITextField (YH_Chain) 45 | @property (nonatomic, copy, readonly) YHTextFieldChainModel *yh_textFieldChain; 46 | + (YHTextFieldChainModel *)yh_creat; 47 | 48 | /** 49 | * A proprietary method written for UITextField's attributed Placeholder. 50 | */ 51 | + (NSAttributedString *)yh_attributedPlaceholderWithString:(NSString *)string color:(UIColor *)color font:(UIFont *)font; 52 | 53 | @end 54 | NS_ASSUME_NONNULL_END 55 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHTextViewChainModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHTextViewChainModel.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2018/12/13. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHBaseViewChainModel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @class YHTextViewChainModel; 13 | @interface YHTextViewChainModel : YHBaseViewChainModel 14 | 15 | 16 | 17 | 18 | 19 | @end 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | @interface UITextView (YH_Chain) 30 | @property (nonatomic, copy, readonly) YHTextViewChainModel *yh_textViewChain; 31 | + (YHTextViewChainModel *)yh_creat; 32 | @end 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHTextViewChainModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHTextViewChainModel.m 3 | // chanDemo 4 | // 5 | // Created by apple on 2018/12/13. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHTextViewChainModel.h" 10 | 11 | @implementation YHTextViewChainModel 12 | 13 | @end 14 | 15 | 16 | 17 | 18 | @implementation UITextView (YH_Chain) 19 | - (YHTextViewChainModel *)yh_textViewChain{ 20 | return [[YHTextViewChainModel alloc] initWithView:self]; 21 | } 22 | + (YHTextViewChainModel *)yh_creat{ 23 | UITextView *textView = [[UITextView alloc] init]; 24 | return [[YHTextViewChainModel alloc] initWithView:textView]; 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHViewChainModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHViewChainModel.h 3 | // chanDemo 4 | // 5 | // Created by 银河 on 2018/11/7. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHBaseViewChainModel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | @class YHViewChainModel; 13 | @interface YHViewChainModel : YHBaseViewChainModel 14 | 15 | @end 16 | 17 | 18 | 19 | @interface UIView (YH_Chain) 20 | @property (nonatomic, copy, readonly) YHViewChainModel *yh_viewChain; 21 | + (YHViewChainModel *)yh_creat; 22 | @end 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Sources/Core/ViewChain/YHViewChainModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // YHViewChainModel.m 3 | // chanDemo 4 | // 5 | // Created by 银河 on 2018/11/7. 6 | // Copyright © 2018 银河. All rights reserved. 7 | // 8 | 9 | #import "YHViewChainModel.h" 10 | 11 | @implementation YHViewChainModel 12 | 13 | 14 | @end 15 | 16 | @implementation UIView (YH_Chain) 17 | - (YHViewChainModel *)yh_viewChain { 18 | return [[YHViewChainModel alloc] initWithView:self]; 19 | } 20 | + (YHViewChainModel *)yh_creat{ 21 | UIView *view = [[UIView alloc] init]; 22 | return [[YHViewChainModel alloc] initWithView:view]; 23 | } 24 | @end 25 | 26 | 27 | -------------------------------------------------------------------------------- /Sources/Core/YHKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHKit.h 3 | // Kit 4 | // 5 | // Created by 银河 on 2019/2/11. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #ifndef YHKit_h 10 | #define YHKit_h 11 | 12 | // Base Macro. 13 | #import "YHMacro.h" 14 | 15 | // AdressBook. 16 | #import "YHAddressBook.h" 17 | 18 | // Authorizetion. 19 | #import "YHAuthorizetion.h" 20 | 21 | // ChineseSort. 22 | #import "YHChineseSort.h" 23 | 24 | // Send SMS. 25 | #import "YHSendSMS.h" 26 | 27 | // Location. 28 | #import "YHLocation.h" 29 | 30 | // System ImagePicker. 31 | #import "YHSystemImagePicker.h" 32 | 33 | // MBProgressHUD. 34 | #import "YHMBHud.h" 35 | 36 | // Net 37 | #import "YHNet.h" 38 | 39 | // Time Count Down. 40 | #import "YHTimeCountDownManager.h" 41 | 42 | // ImageBrowser. 43 | #import "YHImageBrowser.h" 44 | 45 | // UIAlertController. 46 | #import "YHAlertViewController.h" 47 | 48 | // PhotoManager 49 | #import "YHPhotoManager.h" 50 | 51 | // View Chain. 52 | #import "YHButtonChainModel.h" 53 | #import "YHImageViewChainModel.h" 54 | #import "YHLabelChainModel.h" 55 | #import "YHScrollViewChainModel.h" 56 | #import "YHTextViewChainModel.h" 57 | #import "YHTextFieldChainModel.h" 58 | #import "YHViewChainModel.h" 59 | 60 | // UIKit. 61 | #import "UIView+YHFrame.h" 62 | #import "UIDevice+YHExtension.h" 63 | #import "UIImage+YHExtension.h" 64 | #import "UIViewController+YHExtension.h" 65 | #import "UINavigationController+YHRotationExtension.h" 66 | #import "AppDelegate+YHNotiExtension.h" 67 | #import "UIButton+YHExtension.h" 68 | #import "YHTextView.h" 69 | 70 | // Foundation. 71 | #import "NSObject+YHExtension.h" 72 | #import "NSDate+YHExtension.h" 73 | #import "NSString+YHExtension.h" 74 | #import "NSDictionary+YHExtension.h" 75 | #import "NSArray+YHExtension.h" 76 | #import "NSAttributedString+YHExtension.h" 77 | #import "NSMutableAttributedString+YHExtension.h" 78 | #import "NSParagraphStyle+YHExtension.h" 79 | 80 | 81 | // AsyncDisplayKit. 82 | #import "YHASEnlargeEdgeControlNode.h" 83 | #import "ASDisplayNode+YHAddTap.h" 84 | #import "ASControlNode+YHAddTap.h" 85 | #import "ASTextNode+YHHighlight.h" 86 | #import "YHASNetworkImageNode.h" 87 | #import "ASTableNode+YHASReload.h" 88 | #import "ASCollectionNode+YHASReload.h" 89 | #import "YHASCollectionLayoutDelegate.h" 90 | 91 | 92 | // YYLabel. 93 | #import "YYLabel+YHBugFix.h" 94 | 95 | 96 | #endif /* YHKit_h */ 97 | -------------------------------------------------------------------------------- /Sources/Core/YHMacro.h: -------------------------------------------------------------------------------- 1 | // 2 | // YHMacro.h 3 | // chanDemo 4 | // 5 | // Created by apple on 2019/1/16. 6 | // Copyright © 2019 银河. All rights reserved. 7 | // 8 | 9 | #ifndef YHMacro_h 10 | #define YHMacro_h 11 | #import 12 | 13 | #pragma mark - DEBUG 14 | // __VA_ARGS__:可变参数的宏,宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉的作用,否则会编译出错. 15 | // __FILE__:宏在预编译时会替换成当前的源文件名. 16 | // __LINE__:宏在预编译时会替换成当前的行号. 17 | // __FUNCTION__:宏在预编译时会替换成当前的函数名称 18 | #ifdef DEBUG 19 | #define YHLog(format, ...) printf("👉 [YHLog] [%s] [%d] %s\n" ,[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:format, ##__VA_ARGS__] UTF8String]) 20 | #else 21 | #define YHLog(format, ...) 22 | #endif 23 | 24 | 25 | #pragma mark - APP 26 | /** APP version */ 27 | #define YH__AppVersion [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] 28 | /** APP build */ 29 | #define YH__AppBuild [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] 30 | /** APP bundleID */ 31 | #define YH__AppBundleID [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"] 32 | /** APP Name */ 33 | #define YH__AppName [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]//CFBundleDisplayName 34 | /** APP Default StatusBarStyle **/ 35 | #define YH__DefaultStatusBarStyle [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UIStatusBarStyle"] // NSString 36 | 37 | 38 | 39 | 40 | #pragma mark - UIKit 41 | #define YH__RandomColor [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1] 42 | #define YH__RGB(R,G,B) [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:1] 43 | #define YH__RGBA(R,G,B,A) [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:A] 44 | #define YH__HexColor(hex) [UIColor colorWithRed:((float)((hex & 0xFF0000) >> 16))/255.0 green:((float)((hex & 0xFF00) >> 8))/255.0 blue:((float)(hex & 0xFF))/255.0 alpha:1.0] 45 | 46 | 47 | 48 | 49 | 50 | 51 | #pragma mark - Foundation 52 | /** 弧度转角度 */ 53 | #define YH__RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI)) 54 | /** 角度转弧度 */ 55 | #define YH__DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI) 56 | 57 | #define YH__WeakSelf(__weakName__) __weak typeof(self) __weakName__ = self 58 | #define YH__Weak(__name__,__weakName__) __weak typeof(__name__) __weakName__ = __name__ 59 | 60 | 61 | /* 62 | iPhone XR: 414 x 896 2x 63 | 64 | iPhone Xs Max: 414 x 896 3x 65 | iPhone X/Xs: 375 x 812 3x 66 | 67 | IPhone X: 375 x 812 3x 68 | 69 | IPhone 8: 375 x 667 2x 70 | iPhone 8 Plus: 414 x 736 3x 71 | 72 | IPhone 7: 375 x 667 2x 73 | IPhone 7 plus: 414 x 736 3x 74 | 75 | IPhone 6: 375 x 667 2x 76 | IPhone 6s: 375 x 667 2x (UI设计图一般都是以6s为基准的,如果不是,那么锤他) 77 | iPhone 6 Plus: 414 x 736 3x 78 | IPhone 6s plus: 414 x 736 3x 79 | 80 | IPhone 5: 320 x 568 2x 81 | IPhone 5s: 320 x 568 2x 82 | */ 83 | 84 | #define YH__ScreenWidth [UIScreen mainScreen].bounds.size.width 85 | #define YH__ScreenHeight [UIScreen mainScreen].bounds.size.height 86 | 87 | // 当前屏幕的旋转方向,与状态栏是否隐藏无关 88 | #define YH__DeviceOrientation [UIApplication sharedApplication].statusBarOrientation 89 | 90 | 91 | #define YH__IsPortrait \ 92 | ({ \ 93 | BOOL isPortrait = NO; \ 94 | if (YH_DeviceOrientation == UIInterfaceOrientationPortrait || \ 95 | YH_DeviceOrientation == UIInterfaceOrientationPortraitUpsideDown) { \ 96 | isPortrait = YES; \ 97 | } \ 98 | (isPortrait); \ 99 | }) 100 | 101 | /** 102 | * 是否是iPhone X(iPhone X系列) 103 | * iPhone X/XS :375 * 812 (Portrait) 104 | * iPhone XS Max :414 * 896 (Portrait) 105 | * iPhone XR :414 * 896 (Portrait) 106 | */ 107 | #define YH__IS_IPHONE_X \ 108 | ({ \ 109 | BOOL isIphoneX = NO; \ 110 | if (YH__DeviceOrientation == UIInterfaceOrientationPortrait || \ 111 | YH__DeviceOrientation == UIInterfaceOrientationPortraitUpsideDown) { \ 112 | if ((YH__ScreenWidth == 375.f && YH__ScreenHeight == 812.f) || (YH__ScreenWidth == 414.f && YH__ScreenHeight == 896.f)) { \ 113 | isIphoneX = YES; \ 114 | } \ 115 | } else { \ 116 | if ((YH__ScreenWidth == 812.f && YH__ScreenHeight == 375.f) || (YH__ScreenWidth == 896.f && YH__ScreenHeight == 414.f)) { \ 117 | isIphoneX = YES; \ 118 | } \ 119 | } \ 120 | (isIphoneX); \ 121 | }) 122 | 123 | 124 | /** 125 | * 底部高度,主要针对刘海屏幕 126 | * 在iPhone X以前的手机上,底部高度为0,iPhone X及以后的手机,底部高度要根据手机的旋转方向做判断 127 | * 在iPhone X系列手机上,竖屏情况下是34pt,横屏是21pt 128 | */ 129 | #define YH__Bottom_Height \ 130 | ({ \ 131 | CGFloat bottomHeight = 0.0; \ 132 | if (YH__IS_IPHONE_X) { \ 133 | if (YH__DeviceOrientation == UIDeviceOrientationPortrait || \ 134 | YH__DeviceOrientation == UIDeviceOrientationPortraitUpsideDown || \ 135 | YH__DeviceOrientation == UIDeviceOrientationFaceUp || \ 136 | YH__DeviceOrientation == UIDeviceOrientationFaceDown) { \ 137 | bottomHeight = 34.f; \ 138 | } else { \ 139 | bottomHeight = 21.f; \ 140 | } \ 141 | } \ 142 | (bottomHeight); \ 143 | }) 144 | 145 | // 导航栏高度,不管在什么机型上,都是44pt 146 | #define YH__NaviBar_Height 44.f 147 | 148 | // 当开启个人热点时,状态栏高度是40(在刘海屏手机上,状态栏高度不会发生变化) 149 | #define YH__PersonalHotspotStatusBarHeight 40.0 150 | 151 | 152 | /** 状态栏Frame 153 | 1、当状态栏是隐藏的时候,是CGRectZero,iPhone X系列状态栏永远不隐藏 154 | 2、当状态栏不隐藏的时候。iPhone X:44pt 其他机型:20pt 155 | 3、当开启个人热点时,状态栏高度变为40pt,页面会整体下移20pt。特别是TabBar,下移20pt之后,严重影响用户体验。当状态栏高度发生变化时,会走UIApplicationWillChangeStatusBarFrameNotification通知 156 | 4、当设备是iPhone X系列时,开启个人热点和没有开启个人热点时一样的,状态栏尺寸不会发生变化 157 | */ 158 | #define YH__StatusBarFrame [[UIApplication sharedApplication] statusBarFrame] 159 | 160 | 161 | //只有当设备是5系列时,才对宽度做处理,其他情况用实际宽度 基于6s 162 | //#define YH_Width(w) \ 163 | //({ \ 164 | //CGFloat width = w; \ 165 | //if (YH_ScreenWidth == 320.0) { \ 166 | //width = w/375.f*YH_ScreenWidth; \ 167 | //} \ 168 | //(width); \ 169 | //}) 170 | 171 | 172 | 173 | // 不同机型的适配(已6s为基准) 174 | #define YH__Base_6S_AutoFit(__vale__) \ 175 | ({ \ 176 | CGFloat tmp = __vale__; \ 177 | CGFloat min = MIN([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); \ 178 | tmp = min / 375.0 * __vale__; \ 179 | (tmp); \ 180 | }) 181 | 182 | #endif /* YHMacro_h */ 183 | -------------------------------------------------------------------------------- /Sources/Core/YYText Bug Fix/YYLabel+YHBugFix.h: -------------------------------------------------------------------------------- 1 | // 2 | // YYLabel+YHBugFix.h 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/15. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | /** 13 | * 解决YYText纯中文显示不垂直居中的问题 14 | */ 15 | @interface YYLabel (YHBugFix) 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Sources/Core/YYText Bug Fix/YYLabel+YHBugFix.m: -------------------------------------------------------------------------------- 1 | // 2 | // YYLabel+YHBugFix.m 3 | // QAQSmooth 4 | // 5 | // Created by apple on 2019/3/15. 6 | // Copyright © 2019 yinhe. All rights reserved. 7 | // 8 | 9 | #import "YYLabel+YHBugFix.h" 10 | #import 11 | #import "NSString+YHExtension.h" 12 | 13 | @implementation YYLabel (YHBugFix) 14 | 15 | + (void)load{ 16 | Method originMethod = class_getInstanceMethod(self, NSSelectorFromString(@"setAttributedText:")); 17 | Method myMethod = class_getInstanceMethod(self, NSSelectorFromString(@"_yh_setAttributedText:")); 18 | method_exchangeImplementations(originMethod, myMethod); 19 | } 20 | 21 | - (void)_yh_setAttributedText:(NSAttributedString *)attributedText{ 22 | if (attributedText.string.yh_isContainChinese && !attributedText.string.yh_isContainEmoji) { 23 | NSMutableAttributedString *atr = (NSMutableAttributedString *)attributedText; 24 | if (atr.yy_underlineStyle == NSUnderlineStyleNone) { 25 | if (@available(iOS 11.0, *)) { 26 | [atr addAttribute:NSBaselineOffsetAttributeName value:@(-1) range:NSMakeRange(0, atr.length)]; 27 | } else { 28 | [atr addAttribute:NSBaselineOffsetAttributeName value:@(-0.4) range:NSMakeRange(0, atr.length)]; 29 | } 30 | } 31 | } 32 | [self _yh_setAttributedText:attributedText]; 33 | } 34 | @end 35 | -------------------------------------------------------------------------------- /YHOCTool.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | s.name = 'YHOCTool' 4 | s.homepage = 'https://github.com/liujunliuhong/Kit' 5 | s.summary = 'OC版本的开发工具,逐步向Swift迁移' 6 | s.description = 'OC版本的开发工具,逐步向Swift迁移' 7 | s.author = { 'liujunliuhong' => '1035841713@qq.com' } 8 | s.version = '0.0.2' 9 | s.source = { :git => 'https://github.com/liujunliuhong/Kit.git', :tag => s.version.to_s } 10 | s.platform = :ios, '9.0' 11 | s.license = { :type => 'MIT', :file => 'LICENSE' } 12 | s.module_name = 'YHOCTool' 13 | s.swift_version = '5.0' 14 | s.ios.deployment_target = '9.0' 15 | s.requires_arc = true 16 | s.static_framework = true 17 | 18 | 19 | 20 | 21 | # Core 22 | s.subspec 'Core' do |ss| 23 | ss.source_files = 'Sources/Core/*', 'Sources/Core/*/*', 'Sources/Core/*/*/*' 24 | ss.dependency 'AFNetworking' 25 | ss.dependency 'Texture' 26 | ss.dependency 'SDWebImage' 27 | ss.dependency 'SDWebImageWebPCoder' 28 | ss.dependency 'YYText' 29 | ss.dependency 'MBProgressHUD' 30 | ss.dependency 'Masonry' 31 | ss.dependency 'FLAnimatedImage' 32 | end 33 | 34 | end 35 | --------------------------------------------------------------------------------