├── CHANGELOG ├── Example ├── Podfile ├── Example SDWebIm+CPV │ ├── LookHereViewController.h │ ├── AppDelegate.h │ ├── main.m │ ├── LookHereViewController.m │ ├── Libraries │ │ ├── EXPhotoViewer.h │ │ └── EXPhotoViewer.m │ ├── Info.plist │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.m │ └── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard ├── Podfile.lock └── Example SDWebIm+CPV.xcodeproj │ └── project.pbxproj ├── Screenshots └── NKVProgressView.png ├── .gitignore ├── Classes ├── LinearProgressViewSettings.m ├── CircularProgressViewSettings.m ├── LinearProgressViewSettings.h ├── CircularProgressViewSettings.h ├── UIImageView+CircularProgressView.h └── UIImageView+CircularProgressView.m ├── LICENSE ├── SDWebImage-CircularProgressView.podspec └── README.md /CHANGELOG: -------------------------------------------------------------------------------- 1 | *** 0.1.0 *** 2 | - First upload. 3 | 4 | *** 0.x.x *** 5 | - 6 | - -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | 2 | target 'Example SDWebIm+CPV' do 3 | pod 'SDWebImage-CircularProgressView', :path => '../' 4 | end 5 | -------------------------------------------------------------------------------- /Screenshots/NKVProgressView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NikKovIos/SDWebImage-CircularProgressView/HEAD/Screenshots/NKVProgressView.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Xcode legacy 4 | *.mode1 5 | *.mode1v3 6 | *.mode2v3 7 | *.perspective 8 | *.perspectivev3 9 | *.pbxuser 10 | 11 | # User 12 | xcuserdata/ 13 | DerivedData/ 14 | *.xcworkspace/ 15 | 16 | # Other 17 | Pods/ 18 | *.generated.swift 19 | fastlane/report.xml 20 | -------------------------------------------------------------------------------- /Classes/LinearProgressViewSettings.m: -------------------------------------------------------------------------------- 1 | // 2 | // LinearProgressViewSettings.m 3 | // 4 | // 5 | // Created by Nik Kov on 13.09.16. 6 | // Copyright © 2016 Nik Kov. All rights reserved. 7 | // 8 | 9 | #import "LinearProgressViewSettings.h" 10 | 11 | @implementation LinearProgressViewSettings 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/CircularProgressViewSettings.m: -------------------------------------------------------------------------------- 1 | // 2 | // CircularProgressViewSettings.m 3 | // 4 | // 5 | // Created by Nik Kov on 13.09.16. 6 | // Copyright © 2016 Nik Kov. All rights reserved. 7 | // 8 | 9 | #import "CircularProgressViewSettings.h" 10 | 11 | @implementation CircularProgressViewSettings 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV/LookHereViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // Example SDWebIm+CPV 4 | // 5 | // Created by Nikita Kovalenok on 07.02.17. 6 | // Copyright © 2017 NikKovIos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LookHereViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Example SDWebIm+CPV 4 | // 5 | // Created by Nikita Kovalenok on 07.02.17. 6 | // Copyright © 2017 NikKovIos. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Example SDWebIm+CPV 4 | // 5 | // Created by Nikita Kovalenok on 07.02.17. 6 | // Copyright © 2017 NikKovIos. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV/LookHereViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // Example SDWebIm+CPV 4 | // 5 | // Created by Nikita Kovalenok on 07.02.17. 6 | // Copyright © 2017 NikKovIos. All rights reserved. 7 | // 8 | 9 | #import "LookHereViewController.h" 10 | #import "EXPhotoViewer.h" 11 | 12 | @interface LookHereViewController () 13 | 14 | @end 15 | 16 | @implementation LookHereViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Classes/LinearProgressViewSettings.h: -------------------------------------------------------------------------------- 1 | // 2 | // LinearProgressViewSettings.h 3 | // 4 | // 5 | // Created by Nik Kov on 13.09.16. 6 | // Copyright © 2016 Nik Kov. All rights reserved. 7 | // 8 | 9 | @interface LinearProgressViewSettings : NSObject 10 | 11 | @property (nonatomic) float progress; 12 | @property (nonatomic, strong) UIColor* progressTintColor; 13 | @property (nonatomic, strong) UIColor* trackTintColor; 14 | @property (nonatomic, strong) UIImage* progressImage; 15 | @property (nonatomic, strong) UIImage* trackImage; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - DACircularProgress (2.3.1) 3 | - SDWebImage (3.8.2): 4 | - SDWebImage/Core (= 3.8.2) 5 | - SDWebImage-CircularProgressView (0.1.1): 6 | - DACircularProgress (~> 2.3) 7 | - SDWebImage (> 3.7.0) 8 | - SDWebImage/Core (3.8.2) 9 | 10 | DEPENDENCIES: 11 | - SDWebImage-CircularProgressView (from `../`) 12 | 13 | EXTERNAL SOURCES: 14 | SDWebImage-CircularProgressView: 15 | :path: "../" 16 | 17 | SPEC CHECKSUMS: 18 | DACircularProgress: 4dd437c0fc3da5161cb289e07ac449493d41db71 19 | SDWebImage: 098e97e6176540799c27e804c96653ee0833d13c 20 | SDWebImage-CircularProgressView: d9f944aab3856b0da9b9acfbdce59f717c0233e4 21 | 22 | PODFILE CHECKSUM: 685b506ba327e8f1c50be08f900befc257e1f411 23 | 24 | COCOAPODS: 1.1.1 25 | -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV/Libraries/EXPhotoViewer.h: -------------------------------------------------------------------------------- 1 | // 2 | // EXPhotoViewer.h 3 | // EXPhotoViewerDemo 4 | // 5 | // Created by Julio Carrettoni on 3/20/14. 6 | // Copyright (c) 2014 Julio Carrettoni. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EXPhotoViewer : UIViewController 12 | 13 | /** 14 | * The scale to be applied as transformation to the background. IE, a scall of 15 | * 0.8 would "shrink" the background making it appear inset from the screen edges. 16 | */ 17 | @property (nonatomic) CGFloat backgroundScale; 18 | 19 | /** 20 | * The background color of the screen while image is being viewed. Default is black. 21 | */ 22 | @property (nonatomic, strong) UIColor *backgroundColor; 23 | 24 | @property (atomic, readonly) BOOL isClosing; 25 | 26 | + (instancetype)showImageFrom:(UIImageView *)imageView; 27 | + (instancetype)newViewerFor:(UIImageView *)imageView; 28 | 29 | - (void)show; 30 | - (void)close; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Nik Kov 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 | -------------------------------------------------------------------------------- /Classes/CircularProgressViewSettings.h: -------------------------------------------------------------------------------- 1 | // 2 | // CircularProgressViewSettings.h 3 | // 4 | // 5 | // Created by Nik Kov on 13.09.16. 6 | // Copyright © 2016 Nik Kov. All rights reserved. 7 | // 8 | 9 | @interface CircularProgressViewSettings : NSObject 10 | 11 | /// Color of background of a track 12 | @property (nonatomic, strong) UIColor *trackTintColor; 13 | /// Color of circle, that filling track 14 | @property (nonatomic, strong) UIColor *progressTintColor; 15 | /// Color of circle inside the progress view 16 | @property (nonatomic, strong) UIColor *innerTintColor; 17 | /// Rounded corner of progress. On/Off. Between 0 and 1. 18 | @property (nonatomic) NSInteger roundedCorners; 19 | /// Thickness of progress 20 | @property (nonatomic) CGFloat thicknessRatio; 21 | /// Сounterclockwise or clockwise filling. On/Off. Between 0 and 1. 22 | @property (nonatomic) NSInteger clockwiseProgress; 23 | /// Progress state 24 | @property (nonatomic) CGFloat progress; 25 | 26 | /// If you don't know the size of data. Speed. 27 | @property (nonatomic) CGFloat indeterminateDuration; 28 | /// If you don't know the size of data. On/Off. Between 0 and 1. 29 | @property (nonatomic) NSInteger indeterminate; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /SDWebImage-CircularProgressView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "SDWebImage-CircularProgressView" 3 | s.version = "0.1.2" 4 | s.summary = "Category for UIImageView. Adds circular, linear or custom progress view. Images downloading by SDWebImage." 5 | s.description = <<-DESC 6 | Progress View to see how much left to download an Image. It can be Circular or Apples Linear progress view. You can customize colors and other properties in data source. 7 | DESC 8 | s.homepage = "https://github.com/NikKovV/SDWebImage-CircularProgressView" 9 | s.screenshots = 'https://raw.githubusercontent.com/NikKovIos/SDWebImage-CircularProgressView/master/Screenshots/NKVProgressView.png' 10 | s.license = { :type => 'MIT', :file => 'LICENSE' } 11 | s.author = { "Nik Kov" => "nikkovios@gmail.com" } 12 | s.source = { 13 | :git => "https://github.com/NikKovV/SDWebImage-CircularProgressView.git", 14 | :tag => s.version.to_s 15 | } 16 | s.ios.deployment_target = '8.0' 17 | s.source_files = 'Classes/*.{h,m}' 18 | s.requires_arc = true 19 | s.frameworks = 'UIKit' 20 | s.dependency 'SDWebImage', '> 3.7.0' 21 | s.dependency 'DACircularProgress', '~> 2.3' 22 | end 23 | -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | 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 | -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV/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 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Example SDWebIm+CPV 4 | // 5 | // Created by Nikita Kovalenok on 07.02.17. 6 | // Copyright © 2017 NikKovIos. 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 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Classes/UIImageView+CircularProgressView.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+CircularProgressView.h 3 | // 4 | // 5 | // Created by Nik Kov on 13.09.16. 6 | // Copyright © 2016 Nik Kov. All rights reserved. 7 | // 8 | 9 | #import "CircularProgressViewSettings.h" 10 | #import "LinearProgressViewSettings.h" 11 | #import 12 | #import 13 | 14 | 15 | typedef enum : NSUInteger { 16 | LinearPV = 1, 17 | CircularPV, 18 | } ProgressViewType; 19 | 20 | typedef SDImageLoaderProgressBlock SDWebImageDownloaderProgressBlock; 21 | 22 | @protocol ProgressViewDataSource 23 | 24 | @optional 25 | - (LinearProgressViewSettings *)setupLinearProgressViewSettings; 26 | - (CircularProgressViewSettings *)setupCircularProgressViewSettings; 27 | 28 | @end 29 | 30 | 31 | @interface UIImageView (CircularProgressView) 32 | 33 | #pragma mark - Progress view settings 34 | /** Delegate to customize your ProgressView if you had choosen one from ProgressViewType. 35 | * @param Delegate that responds to protocol 36 | */ 37 | - (void)nkvSetProgressViewDataSource:(id )nkvDataSource; 38 | 39 | #pragma mark - Image setting methods 40 | - (void)nkv_setImageWithURL:(NSURL *)url usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 41 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 42 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 43 | - (void)nkv_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 44 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 45 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 46 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 47 | 48 | - (void)removeProgressView; 49 | 50 | 51 | @end 52 | 53 | -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV/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 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SDWebImage-CircularProgressView 2 | ![Cocoapods](https://img.shields.io/badge/pod-available-brightgreen.svg?style=flat) 3 | ![Platform](https://img.shields.io/badge/platform-ios-blue.svg?style=flat) 4 | ![Version](https://img.shields.io/badge/version-1.1-blue.svg?style=flat) 5 | ![Objective-C version](https://img.shields.io/badge/Objective--C-latest-lightgrey.svg?style=flat) 6 | ![License](https://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat) 7 | 8 | Good day everybody!) 9 | 10 | This is a category to SDWebImage that offer you to add ProgressView in three ways: 11 | - Circular (using [DACircularProgress](https://github.com/danielamitay/DACircularProgress)) 12 | - Linear 13 | - Custom 14 | 15 | Images are downloading by SDWebImage (3.7.0 and up) 16 | 17 | ## SCREENSHOTS 18 | 19 | ![Screenshot_here](https://github.com/NikKovV/SDWebImage-CircularProgressView/blob/master/Screenshots/NKVProgressView.png "Screenshot") 20 | 21 | 22 | ## Installation 23 | [Cocoapods](http://cocoapods.org): 24 | ``` 25 | pod 'SDWebImage-CircularProgressView' 26 | ``` 27 | ## Code examples 28 | There are two parameters and unique prefix to easier finding. 29 | - `progressViewType` - LinearPV or CircularPV. Choose the type of Progress View. 30 | - `progressView` - If you init your own UIProgressView than put it there. It should be a class or subclass of UIProgressView. 31 | ``` 32 | - (void)nkv_setImageWithURL:(NSURL *)url usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 33 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 34 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 35 | - (void)nkv_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 36 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 37 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 38 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView; 39 | ``` 40 | #### cancelCurrentImageLoad 41 | If you're using the `sd_cancelCurrentImageLoad method`, you'll also have to call removeProgressView. 42 | ``` 43 | - (void)prepareForReuse { 44 | [super prepareForReuse]; 45 | [self.imageView sd_cancelCurrentImageLoad]; 46 | [self.imageView removeProgressView]; 47 | } 48 | ``` 49 | 50 | #### Customize UIProgressView by DataSource methods 51 | 1. `#import "UIImageView+CircularProgressView.h"` 52 | 2. `@interface NKVTableCell () ` 53 | 3. `[self.bodyImageV nkvSetProgressViewDataSource:self];` 54 | 4. `[self.bodyImageV nkv_setImageWithURL:url usingProgressViewType:CircularPV orCustomProgressView:nil];` 55 | 5. In self (DataSource's class) implement method: 56 | ``` 57 | - (CircularProgressViewSettings *)setupCircularProgressViewSettings 58 | { 59 | CircularProgressViewSettings *circularSettings = [CircularProgressViewSettings new]; 60 | circularSettings.progressTintColor = [UIColor redColor]; 61 | circularSettings.thicknessRatio = 0.2; 62 | return circularSettings; 63 | } 64 | ``` 65 | #### Customize all UIProgressViews in app 66 | ``` 67 | [DACircularProgressView appearance].trackTintColor = [UIColor lightGrayColor]; 68 | [DACircularProgressView appearance].progressTintColor = [UIColor blackColor]; 69 | [UIProgressView appearance].trackTintColor = [UIColor lightGrayColor]; 70 | [UIProgressView appearance].progressTintColor = [UIColor blackColor]; 71 | ``` 72 | ## You should know 73 | - It uses SDWebImage and DACircularProgress. 74 | - CirclePV type implements transparent view by default. Use appearance in AppDelegate or somewhere else to customize it. 75 | - Custom progress bar is a priority for other types. Otherwords if you choose `LinearPV` and then add `orCustomProgressView:(UIProgressView*)yourCustomProgressView` than it would be your custom ProgressView. 76 | 77 | ### References 78 | 79 | Inspired by projects: 80 | - https://github.com/kevinrenskers/SDWebImage-ProgressView 81 | - https://github.com/danielamitay/DACircularProgress 82 | 83 | #### TODO: 84 | - [x] Add http://shields.io/ 85 | - [ ] Add example 86 | - [ ] Add UIedgeInsets like property 87 | - [ ] Add refresh button to image 88 | - [ ] Think about default settings for CircleV 89 | 90 | ## My other Repos 91 | 92 | - [x] https://github.com/NikKovIos/ObjectMapper_RealmSwift - extension to add Realm object support for ObjectMapper 93 | - [x] https://github.com/NikKovIos/NKVPhonePicker - UITextField subclass picker for country phone codes 94 | 95 | ### by Nik Kov 96 | -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV/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 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /Classes/UIImageView+CircularProgressView.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+CircularProgressView.m 3 | // 4 | // 5 | // Created by Nik Kov on 13.09.16. 6 | // Copyright © 2016 Nik Kov. All rights reserved. 7 | // 8 | 9 | #import "UIImageView+CircularProgressView.h" 10 | 11 | #define TAG_PROGRESS_VIEW 777333777 12 | typedef SDImageLoaderProgressBlock SDWebImageDownloaderProgressBlock; 13 | 14 | @implementation UIImageView (CircularProgressView) 15 | 16 | id dataSource; 17 | 18 | #pragma mark - Custom ProgressView 19 | - (void)addCustomProgressView:(UIProgressView *)customProgressView 20 | { 21 | UIProgressView *existingProgressView = (UIProgressView *)[self viewWithTag:TAG_PROGRESS_VIEW]; 22 | 23 | if ( ! existingProgressView) 24 | { 25 | [self setupFrameAndAttributesForProgressView:customProgressView]; 26 | [self addSubview:customProgressView]; 27 | } 28 | } 29 | 30 | #pragma mark - Linear ProgressView 31 | - (void)addLinearProgressView 32 | { 33 | UIProgressView *existingProgressView = (UIProgressView *)[self viewWithTag:TAG_PROGRESS_VIEW]; 34 | 35 | if ( ! existingProgressView) 36 | { 37 | UIProgressView *linearProgressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; 38 | [self setupFrameAndAttributesForProgressView:linearProgressView]; 39 | 40 | if ( dataSource ) 41 | { 42 | if ( [dataSource respondsToSelector:@selector(setupLinearProgressViewSettings)] ) 43 | { 44 | LinearProgressViewSettings *settings = [dataSource setupLinearProgressViewSettings]; 45 | if ( ! settings ) 46 | NSLog(@"Please, be sure, you are returning something in method in your Data Source."); 47 | else 48 | { 49 | linearProgressView.progress = settings.progress; 50 | linearProgressView.progressTintColor = settings.progressTintColor; 51 | linearProgressView.trackTintColor = settings.trackTintColor; 52 | linearProgressView.progressImage = settings.progressImage; 53 | linearProgressView.trackImage = settings.trackImage; 54 | } 55 | } 56 | else 57 | NSLog(@"Please, implement method in your Data Source."); 58 | } 59 | 60 | [self addSubview:linearProgressView]; 61 | } 62 | } 63 | 64 | #pragma mark - Circular ProgressView 65 | 66 | - (void)addCircularProgressView 67 | { 68 | DACircularProgressView *existingProgressView = (DACircularProgressView *)[self viewWithTag:TAG_PROGRESS_VIEW]; 69 | 70 | if ( ! existingProgressView) 71 | { 72 | DACircularProgressView *circularProgressView = [[DACircularProgressView alloc] init]; 73 | [self setupFrameAndAttributesForProgressView:circularProgressView]; 74 | 75 | if ( dataSource ) 76 | { 77 | if ( ! [dataSource respondsToSelector:@selector(setupCircularProgressViewSettings)] ) 78 | NSLog(@"Please, implement method in your Data Source."); 79 | else 80 | { 81 | CircularProgressViewSettings *settings = [dataSource setupCircularProgressViewSettings]; 82 | if ( ! settings ) 83 | NSLog(@"Please, be sure, you are returning something in method in your Data Source."); 84 | else 85 | { 86 | circularProgressView.trackTintColor = settings.trackTintColor; 87 | circularProgressView.progressTintColor = settings.progressTintColor; 88 | circularProgressView.innerTintColor = settings.innerTintColor; 89 | circularProgressView.roundedCorners = settings.roundedCorners; 90 | circularProgressView.thicknessRatio = settings.thicknessRatio; 91 | circularProgressView.clockwiseProgress = settings.clockwiseProgress; 92 | circularProgressView.progress = settings.progress; 93 | circularProgressView.indeterminateDuration = settings.indeterminateDuration; 94 | circularProgressView.indeterminate = settings.indeterminate; 95 | } 96 | } 97 | } 98 | 99 | [self addSubview:circularProgressView]; 100 | } 101 | } 102 | 103 | #pragma mark - Update and delete ProgressView 104 | 105 | - (void)updateProgress:(CGFloat)progress 106 | { 107 | DACircularProgressView *progressView = (DACircularProgressView *)[self viewWithTag:TAG_PROGRESS_VIEW]; 108 | if (progressView) 109 | progressView.progress = progress; 110 | } 111 | 112 | - (void)removeProgressView 113 | { 114 | UIView *progressView = [self viewWithTag:TAG_PROGRESS_VIEW]; 115 | if (progressView) 116 | [progressView removeFromSuperview]; 117 | } 118 | 119 | #pragma mark - Image setting methods 120 | 121 | - (void)nkv_setImageWithURL:(NSURL *)url usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView 122 | { 123 | [self nkv_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil usingProgressViewType:progressViewType orCustomProgressView:progressView]; 124 | } 125 | 126 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView 127 | { 128 | [self nkv_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil usingProgressViewType:progressViewType orCustomProgressView:progressView]; 129 | } 130 | 131 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView 132 | { 133 | [self nkv_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil usingProgressViewType:progressViewType orCustomProgressView:progressView]; 134 | } 135 | 136 | - (void)nkv_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView 137 | { 138 | [self nkv_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock usingProgressViewType:progressViewType orCustomProgressView:progressView]; 139 | } 140 | 141 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView 142 | { 143 | [self nkv_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock usingProgressViewType:progressViewType orCustomProgressView:progressView]; 144 | } 145 | 146 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView 147 | { 148 | [self nkv_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock usingProgressViewType:progressViewType orCustomProgressView:progressView]; 149 | } 150 | 151 | - (void)nkv_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock usingProgressViewType:(ProgressViewType)progressViewType orCustomProgressView:(UIProgressView *)progressView 152 | { 153 | if (progressView) 154 | [self addCustomProgressView:progressView]; 155 | else 156 | switch (progressViewType) 157 | { 158 | case CircularPV: 159 | { 160 | [self addCircularProgressView]; 161 | break; 162 | } 163 | case LinearPV: 164 | default: 165 | { 166 | [self addLinearProgressView]; 167 | break; 168 | } 169 | } 170 | 171 | __weak typeof(self) weakSelf = self; 172 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL *url) { 173 | 174 | CGFloat progress = ((CGFloat)receivedSize / (CGFloat)expectedSize); 175 | dispatch_async(dispatch_get_main_queue(), ^{ 176 | [weakSelf updateProgress:progress]; 177 | }); 178 | 179 | if (progressBlock) 180 | progressBlock(receivedSize, expectedSize, url); 181 | } 182 | 183 | completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 184 | [weakSelf removeProgressView]; 185 | if (completedBlock) 186 | completedBlock(image, error, cacheType, imageURL); 187 | }]; 188 | } 189 | 190 | #pragma mark - Accessors and Others 191 | 192 | - (void)setupFrameAndAttributesForProgressView:(UIView*)view; 193 | { 194 | view.tag = TAG_PROGRESS_VIEW; 195 | view.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin; 196 | 197 | float width = view.frame.size.width; 198 | float height = view.frame.size.height; 199 | float x = (self.frame.size.width / 2.0) - width / 2; 200 | float y = (self.frame.size.height / 2.0) - height / 2; 201 | view.frame = CGRectMake(x, y, width, height); 202 | } 203 | 204 | - (void)nkvSetProgressViewDataSource:(id)nkvDataSource 205 | { 206 | dataSource = nkvDataSource; 207 | } 208 | 209 | @end 210 | 211 | -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV/Libraries/EXPhotoViewer.m: -------------------------------------------------------------------------------- 1 | // 2 | // EXPhotoViewer.m 3 | // EXPhotoViewerDemo 4 | // 5 | // Created by Julio Carrettoni on 3/20/14. 6 | // Copyright (c) 2014 Julio Carrettoni. All rights reserved. 7 | // 8 | 9 | #import "EXPhotoViewer.h" 10 | 11 | @interface EXPhotoViewer () 12 | 13 | @property (nonatomic, retain) UIScrollView *zoomeableScrollView; 14 | @property (nonatomic, retain) UIImageView *originalImageView; 15 | @property (nonatomic, retain) UIImageView *theImageView; 16 | @property (nonatomic, retain) UIView* tempViewContainer; 17 | @property (nonatomic, assign) CGRect originalImageRect; 18 | @property (nonatomic, retain) UIViewController* controller; 19 | @property (nonatomic, retain) UIViewController* selfController; 20 | @property (atomic, readwrite) BOOL isClosing; 21 | 22 | @end 23 | 24 | @implementation EXPhotoViewer 25 | 26 | + (instancetype)showImageFrom:(UIImageView *)imageView { 27 | EXPhotoViewer *viewer = [self newViewerFor:imageView]; 28 | 29 | [viewer show]; 30 | 31 | return viewer; 32 | } 33 | 34 | + (instancetype)newViewerFor:(UIImageView *)imageView { 35 | EXPhotoViewer *viewer = nil; 36 | 37 | if (imageView.image) { 38 | viewer = [[self alloc] init]; 39 | viewer.originalImageView = imageView; 40 | viewer.backgroundScale = 1.0; 41 | } 42 | 43 | return viewer; 44 | } 45 | 46 | -(void)loadView { 47 | self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; 48 | self.view.backgroundColor = [UIColor clearColor]; 49 | 50 | UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; 51 | scrollView.maximumZoomScale = 10.f; 52 | scrollView.minimumZoomScale = 1.f; 53 | scrollView.delegate = self; 54 | scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 55 | [self.view addSubview: scrollView]; 56 | self.zoomeableScrollView = scrollView; 57 | 58 | UIImageView* imageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; 59 | imageView.clipsToBounds = YES; 60 | imageView.contentMode = self.originalImageView.contentMode; 61 | [self.zoomeableScrollView addSubview: imageView]; 62 | self.theImageView = imageView; 63 | } 64 | 65 | -(UIViewController *)rootViewController { 66 | UIViewController* controller = [UIApplication sharedApplication].keyWindow.rootViewController; 67 | 68 | if ([controller presentedViewController]) { 69 | controller = [controller presentedViewController]; 70 | } 71 | return controller; 72 | } 73 | 74 | - (void)show { 75 | if (self.controller) 76 | return; 77 | 78 | UIViewController * controller = [self rootViewController]; 79 | 80 | self.tempViewContainer = [[UIView alloc] initWithFrame:controller.view.bounds]; 81 | self.tempViewContainer.backgroundColor = controller.view.backgroundColor; 82 | controller.view.backgroundColor = [UIColor blackColor]; 83 | 84 | for (UIView* subView in controller.view.subviews) { 85 | [self.tempViewContainer addSubview:subView]; 86 | } 87 | 88 | [controller.view addSubview:self.tempViewContainer]; 89 | 90 | self.controller = controller; 91 | 92 | self.view.frame = controller.view.bounds; //CGRectZero; 93 | self.view.backgroundColor = [UIColor clearColor]; 94 | 95 | [controller.view addSubview:self.view]; 96 | 97 | self.theImageView.image = self.originalImageView.image; 98 | self.originalImageRect = [self.originalImageView convertRect:self.originalImageView.bounds toView:self.view]; 99 | 100 | self.theImageView.frame = self.originalImageRect; 101 | 102 | //listen to the orientation change notification 103 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil]; 104 | 105 | 106 | [UIView animateWithDuration:0.3 animations:^{ 107 | self.view.backgroundColor = (self.backgroundColor) ? self.backgroundColor : [UIColor blackColor]; 108 | self.tempViewContainer.layer.transform = CATransform3DMakeScale(self.backgroundScale, self.backgroundScale, self.backgroundScale); 109 | self.theImageView.frame = [self centeredOnScreenImage:self.theImageView.image]; 110 | } completion:^(BOOL finished) { 111 | [self adjustScrollInsetsToCenterImage]; 112 | UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(close)]; 113 | [self.view addGestureRecognizer:tap]; 114 | }]; 115 | 116 | self.selfController = self; //Stupid ARC I need to do this to avoid being dealloced :P 117 | } 118 | 119 | -(void)dealloc { 120 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];} 121 | 122 | - (void)orientationDidChange:(NSNotification *)note { 123 | self.theImageView.frame = [self centeredOnScreenImage:self.theImageView.image]; 124 | 125 | CGRect newFrame = [self rootViewController].view.bounds; 126 | self.tempViewContainer.frame = newFrame; 127 | self.view.frame = newFrame; 128 | [self adjustScrollInsetsToCenterImage]; 129 | } 130 | 131 | - (void)close { 132 | if (!self.isClosing) { 133 | self.isClosing = YES; 134 | 135 | CGRect absoluteCGRect = [self.view convertRect:self.theImageView.frame fromView:self.theImageView.superview]; 136 | self.zoomeableScrollView.contentOffset = CGPointZero; 137 | self.zoomeableScrollView.contentInset = UIEdgeInsetsZero; 138 | self.theImageView.frame = absoluteCGRect; 139 | 140 | [UIView animateWithDuration:0.3 animations:^{ 141 | self.theImageView.frame = self.originalImageRect; 142 | self.view.backgroundColor = [UIColor clearColor]; 143 | self.tempViewContainer.layer.transform = CATransform3DIdentity; 144 | }completion:^(BOOL finished) { 145 | self.originalImageView.image = self.theImageView.image; 146 | self.controller.view.backgroundColor = self.tempViewContainer.backgroundColor; 147 | for (UIView* subView in self.tempViewContainer.subviews) { 148 | [self.controller.view addSubview:subView]; 149 | } 150 | [self.view removeFromSuperview]; 151 | [self.tempViewContainer removeFromSuperview]; 152 | 153 | self.isClosing = NO; 154 | }]; 155 | 156 | self.selfController = nil;//Ok ARC you can kill me now. 157 | } 158 | } 159 | 160 | - (CGRect)centeredOnScreenImage:(UIImage*) image { 161 | CGSize imageSize = [self imageSizesizeThatFitsForImage:self.theImageView.image]; 162 | CGPoint imageOrigin = CGPointMake(self.view.frame.size.width/2.0 - imageSize.width/2.0, self.view.frame.size.height/2.0 - imageSize.height/2.0); 163 | return CGRectMake(imageOrigin.x, imageOrigin.y, imageSize.width, imageSize.height); 164 | } 165 | 166 | - (CGSize)imageSizesizeThatFitsForImage:(UIImage*) image { 167 | if (!image) 168 | return CGSizeZero; 169 | 170 | CGSize imageSize = image.size; 171 | CGFloat ratio = MIN(self.view.frame.size.width/imageSize.width, self.view.frame.size.height/imageSize.height); 172 | return CGSizeMake(imageSize.width*ratio, imageSize.height*ratio); 173 | } 174 | 175 | #pragma mark - ZOOM 176 | - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { 177 | return self.theImageView; 178 | } 179 | 180 | - (void)adjustScrollInsetsToCenterImage { 181 | CGSize imageSize = [self imageSizesizeThatFitsForImage:self.theImageView.image]; 182 | self.zoomeableScrollView.zoomScale = 1.0; 183 | self.theImageView.frame = CGRectMake(0, 0, imageSize.width, imageSize.height); 184 | self.zoomeableScrollView.contentSize = self.theImageView.frame.size; 185 | 186 | CGRect innerFrame = self.theImageView.frame; 187 | CGRect scrollerBounds = self.zoomeableScrollView.bounds; 188 | CGPoint myScrollViewOffset = self.zoomeableScrollView.contentOffset; 189 | 190 | if ( ( innerFrame.size.width < scrollerBounds.size.width ) || ( innerFrame.size.height < scrollerBounds.size.height ) ) 191 | { 192 | CGFloat tempx = self.theImageView.center.x - ( scrollerBounds.size.width / 2 ); 193 | CGFloat tempy = self.theImageView.center.y - ( scrollerBounds.size.height / 2 ); 194 | myScrollViewOffset = CGPointMake( tempx, tempy); 195 | } 196 | 197 | UIEdgeInsets anEdgeInset = { 0, 0, 0, 0}; 198 | if ( scrollerBounds.size.width > innerFrame.size.width ) 199 | { 200 | anEdgeInset.left = (scrollerBounds.size.width - innerFrame.size.width) / 2; 201 | anEdgeInset.right = -anEdgeInset.left; // I don't know why this needs to be negative, but that's what works 202 | } 203 | if ( scrollerBounds.size.height > innerFrame.size.height ) 204 | { 205 | anEdgeInset.top = (scrollerBounds.size.height - innerFrame.size.height) / 2; 206 | anEdgeInset.bottom = -anEdgeInset.top; // I don't know why this needs to be negative, but that's what works 207 | } 208 | 209 | self.zoomeableScrollView.contentOffset = myScrollViewOffset; 210 | self.zoomeableScrollView.contentInset = anEdgeInset; 211 | } 212 | 213 | - (void)scrollViewDidZoom:(UIScrollView *)scrollView { 214 | UIView* view = self.theImageView; 215 | 216 | CGRect innerFrame = view.frame; 217 | CGRect scrollerBounds = scrollView.bounds; 218 | CGPoint myScrollViewOffset = scrollView.contentOffset; 219 | 220 | if ( ( innerFrame.size.width < scrollerBounds.size.width ) || ( innerFrame.size.height < scrollerBounds.size.height ) ) 221 | { 222 | CGFloat tempx = view.center.x - ( scrollerBounds.size.width / 2 ); 223 | CGFloat tempy = view.center.y - ( scrollerBounds.size.height / 2 ); 224 | myScrollViewOffset = CGPointMake( tempx, tempy); 225 | } 226 | 227 | UIEdgeInsets anEdgeInset = { 0, 0, 0, 0}; 228 | if ( scrollerBounds.size.width > innerFrame.size.width ) 229 | { 230 | anEdgeInset.left = (scrollerBounds.size.width - innerFrame.size.width) / 2; 231 | anEdgeInset.right = -anEdgeInset.left; // I don't know why this needs to be negative, but that's what works 232 | } 233 | if ( scrollerBounds.size.height > innerFrame.size.height ) 234 | { 235 | anEdgeInset.top = (scrollerBounds.size.height - innerFrame.size.height) / 2; 236 | anEdgeInset.bottom = -anEdgeInset.top; // I don't know why this needs to be negative, but that's what works 237 | } 238 | 239 | [UIView animateWithDuration:0.3 animations:^{ 240 | scrollView.contentOffset = myScrollViewOffset; 241 | scrollView.contentInset = anEdgeInset; 242 | }]; 243 | } 244 | 245 | @end 246 | -------------------------------------------------------------------------------- /Example/Example SDWebIm+CPV.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 96D4472E1E49F2820053E323 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96D4472D1E49F2820053E323 /* main.m */; }; 11 | 96D447311E49F2820053E323 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 96D447301E49F2820053E323 /* AppDelegate.m */; }; 12 | 96D447341E49F2820053E323 /* LookHereViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 96D447331E49F2820053E323 /* LookHereViewController.m */; }; 13 | 96D447371E49F2820053E323 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 96D447351E49F2820053E323 /* Main.storyboard */; }; 14 | 96D447391E49F2820053E323 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96D447381E49F2820053E323 /* Assets.xcassets */; }; 15 | 96D4473C1E49F2820053E323 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 96D4473A1E49F2820053E323 /* LaunchScreen.storyboard */; }; 16 | 96D447471E49FADD0053E323 /* EXPhotoViewer.m in Sources */ = {isa = PBXBuildFile; fileRef = 96D447461E49FADD0053E323 /* EXPhotoViewer.m */; }; 17 | C6B3756A6D02F12DA40A3F0B /* libPods-Example SDWebIm+CPV.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B048095A14E8F930D96403E /* libPods-Example SDWebIm+CPV.a */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 6B048095A14E8F930D96403E /* libPods-Example SDWebIm+CPV.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Example SDWebIm+CPV.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | 84F55E8305F6A06FB5EF2440 /* Pods-Example SDWebIm+CPV.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example SDWebIm+CPV.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example SDWebIm+CPV/Pods-Example SDWebIm+CPV.release.xcconfig"; sourceTree = ""; }; 23 | 96D447291E49F2820053E323 /* Example SDWebIm+CPV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example SDWebIm+CPV.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | 96D4472D1E49F2820053E323 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 25 | 96D4472F1E49F2820053E323 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 26 | 96D447301E49F2820053E323 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 27 | 96D447321E49F2820053E323 /* LookHereViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LookHereViewController.h; sourceTree = ""; }; 28 | 96D447331E49F2820053E323 /* LookHereViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LookHereViewController.m; sourceTree = ""; }; 29 | 96D447361E49F2820053E323 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 30 | 96D447381E49F2820053E323 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 31 | 96D4473B1E49F2820053E323 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 32 | 96D4473D1E49F2820053E323 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | 96D447451E49FADD0053E323 /* EXPhotoViewer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EXPhotoViewer.h; path = Libraries/EXPhotoViewer.h; sourceTree = ""; }; 34 | 96D447461E49FADD0053E323 /* EXPhotoViewer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EXPhotoViewer.m; path = Libraries/EXPhotoViewer.m; sourceTree = ""; }; 35 | AE05C920AC8391F404C4F7EB /* Pods-Example SDWebIm+CPV.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example SDWebIm+CPV.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example SDWebIm+CPV/Pods-Example SDWebIm+CPV.debug.xcconfig"; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | 96D447261E49F2820053E323 /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | C6B3756A6D02F12DA40A3F0B /* libPods-Example SDWebIm+CPV.a in Frameworks */, 44 | ); 45 | runOnlyForDeploymentPostprocessing = 0; 46 | }; 47 | /* End PBXFrameworksBuildPhase section */ 48 | 49 | /* Begin PBXGroup section */ 50 | 6D7E9AF5A6727CAF8D261CA9 /* Frameworks */ = { 51 | isa = PBXGroup; 52 | children = ( 53 | 6B048095A14E8F930D96403E /* libPods-Example SDWebIm+CPV.a */, 54 | ); 55 | name = Frameworks; 56 | sourceTree = ""; 57 | }; 58 | 96D447201E49F2820053E323 = { 59 | isa = PBXGroup; 60 | children = ( 61 | 96D4472B1E49F2820053E323 /* Example SDWebIm+CPV */, 62 | 96D4472A1E49F2820053E323 /* Products */, 63 | F000650C4AC03372464C62A0 /* Pods */, 64 | 6D7E9AF5A6727CAF8D261CA9 /* Frameworks */, 65 | ); 66 | sourceTree = ""; 67 | }; 68 | 96D4472A1E49F2820053E323 /* Products */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 96D447291E49F2820053E323 /* Example SDWebIm+CPV.app */, 72 | ); 73 | name = Products; 74 | sourceTree = ""; 75 | }; 76 | 96D4472B1E49F2820053E323 /* Example SDWebIm+CPV */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 96D4472F1E49F2820053E323 /* AppDelegate.h */, 80 | 96D447301E49F2820053E323 /* AppDelegate.m */, 81 | 96D447321E49F2820053E323 /* LookHereViewController.h */, 82 | 96D447331E49F2820053E323 /* LookHereViewController.m */, 83 | 96D447351E49F2820053E323 /* Main.storyboard */, 84 | 96D4472C1E49F2820053E323 /* ... */, 85 | 96D447431E49FA480053E323 /* FullScreenImageViewer */, 86 | ); 87 | path = "Example SDWebIm+CPV"; 88 | sourceTree = ""; 89 | }; 90 | 96D4472C1E49F2820053E323 /* ... */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 96D447381E49F2820053E323 /* Assets.xcassets */, 94 | 96D4473A1E49F2820053E323 /* LaunchScreen.storyboard */, 95 | 96D4473D1E49F2820053E323 /* Info.plist */, 96 | 96D4472D1E49F2820053E323 /* main.m */, 97 | ); 98 | name = ...; 99 | sourceTree = ""; 100 | }; 101 | 96D447431E49FA480053E323 /* FullScreenImageViewer */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 96D447451E49FADD0053E323 /* EXPhotoViewer.h */, 105 | 96D447461E49FADD0053E323 /* EXPhotoViewer.m */, 106 | ); 107 | name = FullScreenImageViewer; 108 | sourceTree = ""; 109 | }; 110 | F000650C4AC03372464C62A0 /* Pods */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | AE05C920AC8391F404C4F7EB /* Pods-Example SDWebIm+CPV.debug.xcconfig */, 114 | 84F55E8305F6A06FB5EF2440 /* Pods-Example SDWebIm+CPV.release.xcconfig */, 115 | ); 116 | name = Pods; 117 | sourceTree = ""; 118 | }; 119 | /* End PBXGroup section */ 120 | 121 | /* Begin PBXNativeTarget section */ 122 | 96D447281E49F2820053E323 /* Example SDWebIm+CPV */ = { 123 | isa = PBXNativeTarget; 124 | buildConfigurationList = 96D447401E49F2820053E323 /* Build configuration list for PBXNativeTarget "Example SDWebIm+CPV" */; 125 | buildPhases = ( 126 | C8D47E57580B7AF2E669AF15 /* [CP] Check Pods Manifest.lock */, 127 | 96D447251E49F2820053E323 /* Sources */, 128 | 96D447261E49F2820053E323 /* Frameworks */, 129 | 96D447271E49F2820053E323 /* Resources */, 130 | 8A7ADE56784DE07DBB275F43 /* [CP] Embed Pods Frameworks */, 131 | 28672EE13721BB866FBE611C /* [CP] Copy Pods Resources */, 132 | ); 133 | buildRules = ( 134 | ); 135 | dependencies = ( 136 | ); 137 | name = "Example SDWebIm+CPV"; 138 | productName = "Example SDWebIm+CPV"; 139 | productReference = 96D447291E49F2820053E323 /* Example SDWebIm+CPV.app */; 140 | productType = "com.apple.product-type.application"; 141 | }; 142 | /* End PBXNativeTarget section */ 143 | 144 | /* Begin PBXProject section */ 145 | 96D447211E49F2820053E323 /* Project object */ = { 146 | isa = PBXProject; 147 | attributes = { 148 | LastUpgradeCheck = 0820; 149 | ORGANIZATIONNAME = NikKovIos; 150 | TargetAttributes = { 151 | 96D447281E49F2820053E323 = { 152 | CreatedOnToolsVersion = 8.2; 153 | DevelopmentTeam = B3U3XRF8D7; 154 | ProvisioningStyle = Automatic; 155 | }; 156 | }; 157 | }; 158 | buildConfigurationList = 96D447241E49F2820053E323 /* Build configuration list for PBXProject "Example SDWebIm+CPV" */; 159 | compatibilityVersion = "Xcode 3.2"; 160 | developmentRegion = English; 161 | hasScannedForEncodings = 0; 162 | knownRegions = ( 163 | en, 164 | Base, 165 | ); 166 | mainGroup = 96D447201E49F2820053E323; 167 | productRefGroup = 96D4472A1E49F2820053E323 /* Products */; 168 | projectDirPath = ""; 169 | projectRoot = ""; 170 | targets = ( 171 | 96D447281E49F2820053E323 /* Example SDWebIm+CPV */, 172 | ); 173 | }; 174 | /* End PBXProject section */ 175 | 176 | /* Begin PBXResourcesBuildPhase section */ 177 | 96D447271E49F2820053E323 /* Resources */ = { 178 | isa = PBXResourcesBuildPhase; 179 | buildActionMask = 2147483647; 180 | files = ( 181 | 96D4473C1E49F2820053E323 /* LaunchScreen.storyboard in Resources */, 182 | 96D447391E49F2820053E323 /* Assets.xcassets in Resources */, 183 | 96D447371E49F2820053E323 /* Main.storyboard in Resources */, 184 | ); 185 | runOnlyForDeploymentPostprocessing = 0; 186 | }; 187 | /* End PBXResourcesBuildPhase section */ 188 | 189 | /* Begin PBXShellScriptBuildPhase section */ 190 | 28672EE13721BB866FBE611C /* [CP] Copy Pods Resources */ = { 191 | isa = PBXShellScriptBuildPhase; 192 | buildActionMask = 2147483647; 193 | files = ( 194 | ); 195 | inputPaths = ( 196 | ); 197 | name = "[CP] Copy Pods Resources"; 198 | outputPaths = ( 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | shellPath = /bin/sh; 202 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Example SDWebIm+CPV/Pods-Example SDWebIm+CPV-resources.sh\"\n"; 203 | showEnvVarsInLog = 0; 204 | }; 205 | 8A7ADE56784DE07DBB275F43 /* [CP] Embed Pods Frameworks */ = { 206 | isa = PBXShellScriptBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | ); 210 | inputPaths = ( 211 | ); 212 | name = "[CP] Embed Pods Frameworks"; 213 | outputPaths = ( 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | shellPath = /bin/sh; 217 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Example SDWebIm+CPV/Pods-Example SDWebIm+CPV-frameworks.sh\"\n"; 218 | showEnvVarsInLog = 0; 219 | }; 220 | C8D47E57580B7AF2E669AF15 /* [CP] Check Pods Manifest.lock */ = { 221 | isa = PBXShellScriptBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | ); 225 | inputPaths = ( 226 | ); 227 | name = "[CP] Check Pods Manifest.lock"; 228 | outputPaths = ( 229 | ); 230 | runOnlyForDeploymentPostprocessing = 0; 231 | shellPath = /bin/sh; 232 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 233 | showEnvVarsInLog = 0; 234 | }; 235 | /* End PBXShellScriptBuildPhase section */ 236 | 237 | /* Begin PBXSourcesBuildPhase section */ 238 | 96D447251E49F2820053E323 /* Sources */ = { 239 | isa = PBXSourcesBuildPhase; 240 | buildActionMask = 2147483647; 241 | files = ( 242 | 96D447341E49F2820053E323 /* LookHereViewController.m in Sources */, 243 | 96D447311E49F2820053E323 /* AppDelegate.m in Sources */, 244 | 96D4472E1E49F2820053E323 /* main.m in Sources */, 245 | 96D447471E49FADD0053E323 /* EXPhotoViewer.m in Sources */, 246 | ); 247 | runOnlyForDeploymentPostprocessing = 0; 248 | }; 249 | /* End PBXSourcesBuildPhase section */ 250 | 251 | /* Begin PBXVariantGroup section */ 252 | 96D447351E49F2820053E323 /* Main.storyboard */ = { 253 | isa = PBXVariantGroup; 254 | children = ( 255 | 96D447361E49F2820053E323 /* Base */, 256 | ); 257 | name = Main.storyboard; 258 | sourceTree = ""; 259 | }; 260 | 96D4473A1E49F2820053E323 /* LaunchScreen.storyboard */ = { 261 | isa = PBXVariantGroup; 262 | children = ( 263 | 96D4473B1E49F2820053E323 /* Base */, 264 | ); 265 | name = LaunchScreen.storyboard; 266 | sourceTree = ""; 267 | }; 268 | /* End PBXVariantGroup section */ 269 | 270 | /* Begin XCBuildConfiguration section */ 271 | 96D4473E1E49F2820053E323 /* Debug */ = { 272 | isa = XCBuildConfiguration; 273 | buildSettings = { 274 | ALWAYS_SEARCH_USER_PATHS = NO; 275 | CLANG_ANALYZER_NONNULL = YES; 276 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 277 | CLANG_CXX_LIBRARY = "libc++"; 278 | CLANG_ENABLE_MODULES = YES; 279 | CLANG_ENABLE_OBJC_ARC = YES; 280 | CLANG_WARN_BOOL_CONVERSION = YES; 281 | CLANG_WARN_CONSTANT_CONVERSION = YES; 282 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 283 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 284 | CLANG_WARN_EMPTY_BODY = YES; 285 | CLANG_WARN_ENUM_CONVERSION = YES; 286 | CLANG_WARN_INFINITE_RECURSION = YES; 287 | CLANG_WARN_INT_CONVERSION = YES; 288 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 289 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 290 | CLANG_WARN_UNREACHABLE_CODE = YES; 291 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 292 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 293 | COPY_PHASE_STRIP = NO; 294 | DEBUG_INFORMATION_FORMAT = dwarf; 295 | ENABLE_STRICT_OBJC_MSGSEND = YES; 296 | ENABLE_TESTABILITY = YES; 297 | GCC_C_LANGUAGE_STANDARD = gnu99; 298 | GCC_DYNAMIC_NO_PIC = NO; 299 | GCC_NO_COMMON_BLOCKS = YES; 300 | GCC_OPTIMIZATION_LEVEL = 0; 301 | GCC_PREPROCESSOR_DEFINITIONS = ( 302 | "DEBUG=1", 303 | "$(inherited)", 304 | ); 305 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 306 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 307 | GCC_WARN_UNDECLARED_SELECTOR = YES; 308 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 309 | GCC_WARN_UNUSED_FUNCTION = YES; 310 | GCC_WARN_UNUSED_VARIABLE = YES; 311 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 312 | MTL_ENABLE_DEBUG_INFO = YES; 313 | ONLY_ACTIVE_ARCH = YES; 314 | SDKROOT = iphoneos; 315 | TARGETED_DEVICE_FAMILY = "1,2"; 316 | }; 317 | name = Debug; 318 | }; 319 | 96D4473F1E49F2820053E323 /* Release */ = { 320 | isa = XCBuildConfiguration; 321 | buildSettings = { 322 | ALWAYS_SEARCH_USER_PATHS = NO; 323 | CLANG_ANALYZER_NONNULL = YES; 324 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 325 | CLANG_CXX_LIBRARY = "libc++"; 326 | CLANG_ENABLE_MODULES = YES; 327 | CLANG_ENABLE_OBJC_ARC = YES; 328 | CLANG_WARN_BOOL_CONVERSION = YES; 329 | CLANG_WARN_CONSTANT_CONVERSION = YES; 330 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 331 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 332 | CLANG_WARN_EMPTY_BODY = YES; 333 | CLANG_WARN_ENUM_CONVERSION = YES; 334 | CLANG_WARN_INFINITE_RECURSION = YES; 335 | CLANG_WARN_INT_CONVERSION = YES; 336 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 337 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 338 | CLANG_WARN_UNREACHABLE_CODE = YES; 339 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 340 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 341 | COPY_PHASE_STRIP = NO; 342 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 343 | ENABLE_NS_ASSERTIONS = NO; 344 | ENABLE_STRICT_OBJC_MSGSEND = YES; 345 | GCC_C_LANGUAGE_STANDARD = gnu99; 346 | GCC_NO_COMMON_BLOCKS = YES; 347 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 348 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 349 | GCC_WARN_UNDECLARED_SELECTOR = YES; 350 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 351 | GCC_WARN_UNUSED_FUNCTION = YES; 352 | GCC_WARN_UNUSED_VARIABLE = YES; 353 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 354 | MTL_ENABLE_DEBUG_INFO = NO; 355 | SDKROOT = iphoneos; 356 | TARGETED_DEVICE_FAMILY = "1,2"; 357 | VALIDATE_PRODUCT = YES; 358 | }; 359 | name = Release; 360 | }; 361 | 96D447411E49F2820053E323 /* Debug */ = { 362 | isa = XCBuildConfiguration; 363 | baseConfigurationReference = AE05C920AC8391F404C4F7EB /* Pods-Example SDWebIm+CPV.debug.xcconfig */; 364 | buildSettings = { 365 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 366 | DEVELOPMENT_TEAM = B3U3XRF8D7; 367 | INFOPLIST_FILE = "Example SDWebIm+CPV/Info.plist"; 368 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 369 | PRODUCT_BUNDLE_IDENTIFIER = "com.nikkov.Example-SDWebIm-CPV"; 370 | PRODUCT_NAME = "$(TARGET_NAME)"; 371 | }; 372 | name = Debug; 373 | }; 374 | 96D447421E49F2820053E323 /* Release */ = { 375 | isa = XCBuildConfiguration; 376 | baseConfigurationReference = 84F55E8305F6A06FB5EF2440 /* Pods-Example SDWebIm+CPV.release.xcconfig */; 377 | buildSettings = { 378 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 379 | DEVELOPMENT_TEAM = B3U3XRF8D7; 380 | INFOPLIST_FILE = "Example SDWebIm+CPV/Info.plist"; 381 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 382 | PRODUCT_BUNDLE_IDENTIFIER = "com.nikkov.Example-SDWebIm-CPV"; 383 | PRODUCT_NAME = "$(TARGET_NAME)"; 384 | }; 385 | name = Release; 386 | }; 387 | /* End XCBuildConfiguration section */ 388 | 389 | /* Begin XCConfigurationList section */ 390 | 96D447241E49F2820053E323 /* Build configuration list for PBXProject "Example SDWebIm+CPV" */ = { 391 | isa = XCConfigurationList; 392 | buildConfigurations = ( 393 | 96D4473E1E49F2820053E323 /* Debug */, 394 | 96D4473F1E49F2820053E323 /* Release */, 395 | ); 396 | defaultConfigurationIsVisible = 0; 397 | defaultConfigurationName = Release; 398 | }; 399 | 96D447401E49F2820053E323 /* Build configuration list for PBXNativeTarget "Example SDWebIm+CPV" */ = { 400 | isa = XCConfigurationList; 401 | buildConfigurations = ( 402 | 96D447411E49F2820053E323 /* Debug */, 403 | 96D447421E49F2820053E323 /* Release */, 404 | ); 405 | defaultConfigurationIsVisible = 0; 406 | defaultConfigurationName = Release; 407 | }; 408 | /* End XCConfigurationList section */ 409 | }; 410 | rootObject = 96D447211E49F2820053E323 /* Project object */; 411 | } 412 | --------------------------------------------------------------------------------