├── example.gif
├── screenshots
├── pixelperfect-screen1.png
└── pixelperfect-screen2.png
├── PixelPerfect-Example
├── mockups
│ └── add-point.png
├── resources
│ ├── background@2x.png
│ ├── add-point-icon.png
│ ├── add-password-icon.png
│ ├── add-point-icon@2x.png
│ ├── add-point-icon@3x.png
│ ├── add-password-icon@2x.png
│ ├── add-password-icon@3x.png
│ ├── facebook-btn-normal.png
│ ├── facebook-btn-normal@2x.png
│ ├── facebook-btn-normal@3x.png
│ ├── facebook-btn-selected.png
│ ├── facebook-btn-selected@2x.png
│ └── facebook-btn-selected@3x.png
├── classes
│ ├── ExampleViewController.h
│ └── ExampleViewController.m
├── AppDelegate.h
├── main.m
├── AppDelegate.m
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
└── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
├── PixelPerfect-Example.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── PixelPerfect
├── PIXELWindow.h
├── PIXELViewController.h
├── UIImage+ColorInverse.h
├── PIXELSettingsViewController.h
├── PIXELPerfect+Public.h
├── PIXELWindow.m
├── UIImage+ColorInverse.m
├── PIXELPerfect.h
├── PIXELSettingsViewController.m
├── PIXELPerfect.m
└── PIXELViewController.m
├── .gitignore
├── PixelPerfect.podspec
├── PixelPerfectTests
├── Info.plist
└── PixelPerfectTests.m
├── LICENSE
└── README.md
/example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/example.gif
--------------------------------------------------------------------------------
/screenshots/pixelperfect-screen1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/screenshots/pixelperfect-screen1.png
--------------------------------------------------------------------------------
/screenshots/pixelperfect-screen2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/screenshots/pixelperfect-screen2.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/mockups/add-point.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/mockups/add-point.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/background@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/background@2x.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/add-point-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/add-point-icon.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/add-password-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/add-password-icon.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/add-point-icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/add-point-icon@2x.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/add-point-icon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/add-point-icon@3x.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/add-password-icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/add-password-icon@2x.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/add-password-icon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/add-password-icon@3x.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/facebook-btn-normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/facebook-btn-normal.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/facebook-btn-normal@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/facebook-btn-normal@2x.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/facebook-btn-normal@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/facebook-btn-normal@3x.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/facebook-btn-selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/facebook-btn-selected.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/facebook-btn-selected@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/facebook-btn-selected@2x.png
--------------------------------------------------------------------------------
/PixelPerfect-Example/resources/facebook-btn-selected@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuraware/PixelPerfect/HEAD/PixelPerfect-Example/resources/facebook-btn-selected@3x.png
--------------------------------------------------------------------------------
/PixelPerfect-Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PixelPerfect/PIXELWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // PerfectWindow.h
3 | // PixelPerfect
4 | //
5 | // Created by Yuri on 5/2/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface PIXELWindow : UIWindow
12 |
13 | - (void)removeSubviews;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/PixelPerfect/PIXELViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // PPPerfectViewController.h
3 | // PerfectPixel-Example
4 | //
5 | // Created by Yuri on 4/30/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface PIXELViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/PixelPerfect/UIImage+ColorInverse.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+ColorInverse.h
3 | // PixelPerfect
4 | //
5 | // Created by Yuri on 5/2/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIImage (ColorInverse)
12 |
13 | - (UIImage *)inverseColors;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/PixelPerfect-Example/classes/ExampleViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleViewController.h
3 | // PixelPerfect-Example
4 | //
5 | // Created by Yuri on 5/14/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ExampleViewController : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/PixelPerfect/PIXELSettingsViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // PIXELSettingsViewController.h
3 | // PixelPerfect-Example
4 | //
5 | // Created by Yuri on 5/17/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface PIXELSettingsViewController : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/PixelPerfect/PIXELPerfect+Public.h:
--------------------------------------------------------------------------------
1 | //
2 | // PIXELPerfect+Public.h
3 | // PixelPerfect-Example
4 | //
5 | // Created by Yuri on 8/31/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #ifndef PixelPerfect_Example_PIXELPerfect_Public_h
10 | #define PixelPerfect_Example_PIXELPerfect_Public_h
11 |
12 | #import "PIXELPerfect.h"
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/PixelPerfect-Example/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // PixelPerfect
4 | //
5 | // Created by Yuri on 5/14/15.
6 | // Copyright (c) 2015 Yuri Kobets. 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 |
--------------------------------------------------------------------------------
/PixelPerfect-Example/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // PixelPerfect
4 | //
5 | // Created by Yuri on 5/14/15.
6 | // Copyright (c) 2015 Yuri Kobets. 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 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
20 | #AppCode
21 | *.idea
22 |
23 | # CocoaPods
24 | #
25 | # We recommend against adding the Pods directory to your .gitignore. However
26 | # you should judge for yourself, the pros and cons are mentioned at:
27 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
28 | #
29 | #Pods/
30 |
--------------------------------------------------------------------------------
/PixelPerfect/PIXELWindow.m:
--------------------------------------------------------------------------------
1 | //
2 | // PerfectWindow.m
3 | // PixelPerfect
4 | //
5 | // Created by Yuri on 5/2/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import "PIXELWindow.h"
10 |
11 | @implementation PIXELWindow
12 |
13 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
14 | {
15 | // accept only touches on status bar
16 | if (point.y < 20.) {
17 | return [super hitTest:point withEvent:event];
18 | }
19 | return nil;
20 | }
21 |
22 | - (void)removeSubviews
23 | {
24 | for (UIView *view in self.subviews) {
25 | [view removeFromSuperview];
26 | }
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/PixelPerfect/UIImage+ColorInverse.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+ColorInverse.m
3 | // PixelPerfect
4 | //
5 | // Created by Yuri on 5/2/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import "UIImage+ColorInverse.h"
10 | #import
11 |
12 | @implementation UIImage (ColorInverse)
13 |
14 | - (UIImage *)inverseColors
15 | {
16 | CIImage *coreImage = [CIImage imageWithCGImage:self.CGImage];
17 | CIFilter *filter = [CIFilter filterWithName:@"CIColorInvert"];
18 | [filter setValue:coreImage forKey:kCIInputImageKey];
19 | CIImage *result = [filter valueForKey:kCIOutputImageKey];
20 | return [UIImage imageWithCIImage:result];
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/PixelPerfect.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'PixelPerfect'
3 | s.version = '0.1.0'
4 | s.platform = :ios, '7.0'
5 | s.license = 'MIT'
6 | s.summary = 'Compare mockup design with your interface on iOS'
7 | s.description = 'Compare mockup design images with user interface on iOS. Get the diff of images using inversion or transparency of design mockups.'
8 | s.homepage = 'https://github.com/ykobets/PixelPerfect'
9 | s.authors = { 'Yuri Kobets' => 'y.kobets@me.com' }
10 | s.source = { :git => 'https://github.com/ykobets/PixelPerfect.git', :tag => s.version.to_s }
11 | s.source_files = 'PixelPerfect'
12 | s.requires_arc = true
13 | s.frameworks = ['CoreImage', 'UIKit']
14 | s.public_header_files = 'PixelPerfect/PIXELPerfect+Public.h'
15 | end
--------------------------------------------------------------------------------
/PixelPerfectTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.perfectpixel.ios.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/PixelPerfect-Example/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // PixelPerfect
4 | //
5 | // Created by Yuri on 5/14/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | #import "PIXELPerfect.h"
12 | #import "ExampleViewController.h"
13 |
14 | @interface AppDelegate ()
15 |
16 | @end
17 |
18 | @implementation AppDelegate
19 |
20 |
21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
22 |
23 |
24 | // Use it only in DEBUG mode
25 | // #ifdef DEBUG
26 | // 'code'
27 | // #else
28 |
29 |
30 | NSDictionary *classesImagesDictionary = @{ NSStringFromClass([ExampleViewController class]) : @"add-point.png" };
31 | [[PIXELPerfect shared] setControllersClassesAndImages:classesImagesDictionary];
32 |
33 |
34 | return YES;
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/PixelPerfectTests/PixelPerfectTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PixelPerfectTests.m
3 | // PixelPerfectTests
4 | //
5 | // Created by Yuri on 5/14/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface PixelPerfectTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation PixelPerfectTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Yuri Kobets
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 |
23 |
--------------------------------------------------------------------------------
/PixelPerfect-Example/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/PixelPerfect/PIXELPerfect.h:
--------------------------------------------------------------------------------
1 | //
2 | // PPPerfectManager.h
3 | // PerfectPixel-Project
4 | //
5 | // Created by Yuri on 4/30/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class PIXELWindow;
13 |
14 | @interface PIXELPerfect : NSObject
15 |
16 | @property (nonatomic,strong) PIXELWindow *overlayWindow;
17 |
18 | @property (nonatomic,strong) Class recentUsedClass;
19 |
20 | @property (nonatomic,assign, getter=isShowingOnStart) BOOL showOnStart;
21 | @property (nonatomic,assign, getter=isImageInverted) BOOL imageInverted;
22 | @property (nonatomic,assign) float imageAlpha;
23 |
24 | + (PIXELPerfect *)shared;
25 |
26 | /**
27 | Sets dictionary with keys as `UIViewController class` string and values as corresponding mockup image name
28 | The dictionary with structure @{NSStringFromClass([UIViewController class]) : @"image.png" }
29 | @param classesImagesDict - dictionary with `keys` - NSString of class, `values` - image name
30 |
31 | key - NSString representation of UIViewController subclass
32 | value - image name. Note that image should be added to bundle
33 | */
34 | - (void)setControllersClassesAndImages:(NSDictionary *)classesImagesDict;
35 |
36 | /**
37 | Retrieves an image for specific UIViewController subclass
38 |
39 | @param aClass the subclass of UIViewController
40 |
41 | @return image of corresponding subclass of UIViewController
42 | */
43 | - (UIImage *)imageForControllerClass:(Class)aClass;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/PixelPerfect-Example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.perfectpixel.ios.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/PixelPerfect-Example/classes/ExampleViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleViewController.m
3 | // PixelPerfect-Example
4 | //
5 | // Created by Yuri on 5/14/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import "ExampleViewController.h"
10 |
11 | @implementation ExampleViewController
12 |
13 | - (void)viewDidLoad
14 | {
15 | [super viewDidLoad];
16 |
17 | self.title = @"New point";
18 |
19 | self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:20/255.
20 | green:162./255.
21 | blue:218./255.
22 | alpha:1.0];
23 | self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]};
24 |
25 | UIBarButtonItem *addItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
26 | target:nil
27 | action:nil];
28 | addItem.tintColor = [UIColor whiteColor];
29 | UIBarButtonItem *saveItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
30 | target:nil
31 | action:nil];
32 | saveItem.tintColor = [UIColor whiteColor];
33 |
34 | self.navigationItem.leftBarButtonItem = addItem;
35 | self.navigationItem.rightBarButtonItem = saveItem;
36 |
37 | UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
38 | [backgroundImageView setImage:[UIImage imageNamed:@"background.png"]];
39 |
40 | self.tableView.backgroundView = backgroundImageView;
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PixelPerfect
2 | [](https://github.com/ykobets/PixelPerfect)
3 |
4 | Compare mockup design images with a user interface on iOS, get the diff of images using inversion or transparency of design mockups.
5 |
6 | ##Features
7 | * show a mockup image imposed with a user interface
8 | * change a mockup image transparency
9 | * invert colors of a mockup image to see design difference
10 |
11 | 
12 |
13 | ##Usage
14 |
15 | 1. Copy mockup design images to project.
16 | 2. Create dictionary with class name and corresponding mockup image name.
17 | 3. Instantiate `PIXELPerfect` with this dictionary in application delegate class.
18 |
19 | In the status bar there appears buttons "show/hide" and "settings".
20 | Now you can compare mockup image with actual user interface.
21 |
22 | `AppDelegate.m`
23 |
24 | `Objective-C`
25 |
26 | ```
27 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
28 |
29 | #ifdef DEBUG
30 | NSDictionary *classesImagesDictionary = @{ NSStringFromClass([ExampleViewController class]) : @"viewcontroller-mockup.png" };
31 | [[PIXELPerfect shared] setControllersClassesAndImages:classesImagesDictionary];
32 | #endif
33 |
34 | return YES;
35 | }
36 | ```
37 |
38 | `Swift`
39 | ```
40 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
41 |
42 | let classesImagesDictionary = [NSStringFromClass(ViewController.self) : "viewcontroller-mockup.png"]
43 | PIXELPerfect.shared().setControllersClassesAndImages(classesImagesDictionary)
44 |
45 | return true
46 | }
47 | ```
48 |
49 | ##Install
50 |
51 | Install with [CocoaPods](http://cocoapods.org/). Add next lines to `Podfile`
52 |
53 | ```
54 | platform :ios, '7.0'
55 |
56 | pod 'PixelPerfect'
57 | ```
58 |
59 | In case of using Swift project
60 |
61 | ```
62 | platform :ios, '7.0'
63 | use_frameworks!
64 |
65 | pod 'PixelPerfect'
66 | ```
67 |
--------------------------------------------------------------------------------
/PixelPerfect-Example/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/PixelPerfect/PIXELSettingsViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // PIXELSettingsViewController.m
3 | // PixelPerfect-Example
4 | //
5 | // Created by Yuri on 5/17/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import "PIXELSettingsViewController.h"
10 | #import "PIXELPerfect.h"
11 |
12 | @interface PIXELSettingsViewController ()
13 |
14 | @end
15 |
16 | @implementation PIXELSettingsViewController
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 |
21 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Back"
22 | style:UIBarButtonItemStylePlain
23 | target:self
24 | action:@selector(backPressed)];
25 | }
26 |
27 | - (void)backPressed
28 | {
29 | [self dismissViewControllerAnimated:YES completion:nil];
30 | }
31 |
32 | #pragma mark - Table view data source
33 |
34 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
35 | {
36 | return 3;
37 | }
38 |
39 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
40 | {
41 | return 1;
42 | }
43 |
44 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
45 | {
46 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
47 |
48 | if (indexPath.section == 0) { //invert cell
49 |
50 | cell.textLabel.text = @"Show inverted image";
51 |
52 | UISwitch *invertSwitch = [[UISwitch alloc] init];
53 | invertSwitch.center = cell.contentView.center;
54 | CGRect rect = invertSwitch.frame;
55 | rect.origin.x = CGRectGetWidth(self.view.frame) - CGRectGetWidth(rect) - 10.;
56 | invertSwitch.frame = rect;
57 |
58 | invertSwitch.on = [PIXELPerfect shared].isImageInverted;
59 |
60 | [invertSwitch addTarget:self action:@selector(didChangeInvertedSwitch:) forControlEvents:UIControlEventValueChanged];
61 |
62 | [cell.contentView addSubview:invertSwitch];
63 |
64 | } else if (indexPath.section == 1) { // alpha cell
65 |
66 | cell.textLabel.text = @"Alpha";
67 | UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(80., 10., CGRectGetWidth(self.view.bounds) - 90., 20.)];
68 |
69 | [slider addTarget:self action:@selector(didChangeSliderImageAlpha:) forControlEvents:UIControlEventValueChanged];
70 |
71 | slider.value = [PIXELPerfect shared].imageAlpha;
72 | [cell.contentView addSubview:slider];
73 |
74 | } else if (indexPath.section == 2) { // show on start
75 |
76 | cell.textLabel.text = @"Show mockup image on start";
77 |
78 | UISwitch *showSwitch = [[UISwitch alloc] init];
79 | showSwitch.center = cell.contentView.center;
80 | CGRect rect = showSwitch.frame;
81 | rect.origin.x = CGRectGetWidth(self.view.frame) - CGRectGetWidth(rect) - 10.;
82 | showSwitch.frame = rect;
83 |
84 | showSwitch.on = [PIXELPerfect shared].isShowingOnStart;
85 |
86 | [showSwitch addTarget:self action:@selector(didChangeShowOnStartSwitch:) forControlEvents:UIControlEventValueChanged];
87 |
88 | [cell.contentView addSubview:showSwitch];
89 | }
90 |
91 | return cell;
92 | }
93 |
94 | #pragma mark -
95 |
96 | - (void)didChangeInvertedSwitch:(UISwitch *)sender
97 | {
98 | [[PIXELPerfect shared] setImageInverted:sender.on];
99 | }
100 |
101 | - (void)didChangeSliderImageAlpha:(UISlider *)sender
102 | {
103 | [[PIXELPerfect shared] setImageAlpha:sender.value];
104 | }
105 |
106 | - (void)didChangeShowOnStartSwitch:(UISwitch *)sender
107 | {
108 | [[PIXELPerfect shared] setShowOnStart:sender.on];
109 | }
110 |
111 | @end
112 |
--------------------------------------------------------------------------------
/PixelPerfect/PIXELPerfect.m:
--------------------------------------------------------------------------------
1 | //
2 | // PPPerfectManager.m
3 | // PerfectPixel-Project
4 | //
5 | // Created by Yuri on 4/30/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import "PIXELPerfect.h"
10 | #import
11 | #import
12 | #import "PIXELViewController.h"
13 | #import "PIXELWindow.h"
14 |
15 | static PIXELPerfect *_sharedInstance = nil;
16 |
17 | static NSString * const kPIXELImageInvertedImageKey = @"kPIXELImageInvertedImageKey";
18 | static NSString * const kPIXELImageAlphaKey = @"kPIXELImageAlphaKey";
19 | static NSString * const kPIXELShowOnStartKey = @"kPIXELShowOnStartKey";
20 |
21 | static float const kPIXELDefaultImageAlpha = 0.5;
22 |
23 | static IMP viewDidLoadImplementation = NULL;
24 | static IMP viewWillDisappearImplementation = NULL;
25 | static IMP viewDidAppearImplementation = NULL;
26 | static IMP viewWillAppearImplementation = NULL;
27 |
28 | @interface PIXELPerfect ()
29 |
30 | - (void)swizzleUIViewControllerMethods;
31 |
32 | @property (nonatomic,strong) NSDictionary * classesImagesDict;
33 |
34 | @end
35 |
36 | @implementation PIXELPerfect
37 |
38 | + (PIXELPerfect *)shared
39 | {
40 | static dispatch_once_t onceToken;
41 | dispatch_once(&onceToken, ^{
42 | _sharedInstance = [PIXELPerfect new];
43 | });
44 |
45 | return _sharedInstance;
46 | }
47 |
48 | - (instancetype)init
49 | {
50 | if (self = [super init]) {
51 | [self swizzleUIViewControllerMethods];
52 | }
53 |
54 | return self;
55 | }
56 |
57 | - (void)setImageInverted:(BOOL)imageInverted
58 | {
59 | [[NSUserDefaults standardUserDefaults] setBool:imageInverted forKey:kPIXELImageInvertedImageKey];
60 | [[NSUserDefaults standardUserDefaults] synchronize];
61 | }
62 |
63 | - (BOOL)isImageInverted
64 | {
65 | return [[NSUserDefaults standardUserDefaults] boolForKey:kPIXELImageInvertedImageKey];
66 | }
67 |
68 | - (void)setImageAlpha:(float)imageAlpha
69 | {
70 | [[NSUserDefaults standardUserDefaults] setFloat:imageAlpha forKey:kPIXELImageAlphaKey];
71 | [[NSUserDefaults standardUserDefaults] synchronize];
72 | }
73 |
74 | - (float)imageAlpha
75 | {
76 | if ([[NSUserDefaults standardUserDefaults] objectForKey:kPIXELImageAlphaKey] == nil) {
77 | return kPIXELDefaultImageAlpha;
78 | }
79 |
80 | return [[NSUserDefaults standardUserDefaults] floatForKey:kPIXELImageAlphaKey];
81 | }
82 |
83 | - (void)setShowOnStart:(BOOL)showOnStart
84 | {
85 | [[NSUserDefaults standardUserDefaults] setBool:showOnStart forKey:kPIXELShowOnStartKey];
86 | [[NSUserDefaults standardUserDefaults] synchronize];
87 | }
88 |
89 | - (BOOL)isShowingOnStart
90 | {
91 | return [[NSUserDefaults standardUserDefaults] boolForKey:kPIXELShowOnStartKey];
92 | }
93 |
94 | - (void)swizzleUIViewControllerMethods
95 | {
96 | static dispatch_once_t onceToken;
97 | dispatch_once(&onceToken, ^{
98 |
99 | SEL viewDidLoadSelector = @selector(viewDidLoad);
100 | SEL viewWillDisappearSelector = @selector(viewWillDisappear:);
101 | SEL viewDidAppearSelector = @selector(viewDidAppear:);
102 | SEL viewWillAppearSelector = @selector(viewWillAppear:);
103 |
104 | viewDidLoadImplementation = class_getMethodImplementation([UIViewController class], viewDidLoadSelector);
105 | viewWillDisappearImplementation = class_getMethodImplementation([UIViewController class], viewWillDisappearSelector);
106 | viewDidAppearImplementation = class_getMethodImplementation([UIViewController class], viewDidAppearSelector);
107 | viewWillAppearImplementation = class_getMethodImplementation([UIViewController class], viewWillAppearSelector);
108 |
109 | Method originalViewDidLoadMethod = class_getInstanceMethod([UIViewController class], viewDidLoadSelector);
110 | Method swizzledViewDidLoadMethod = class_getInstanceMethod([PIXELViewController class], viewDidLoadSelector);
111 |
112 | Method originalViewWillDisappearMethod = class_getInstanceMethod([UIViewController class], viewWillDisappearSelector);
113 | Method swizzledViewWillDisappearMethod = class_getInstanceMethod([PIXELViewController class], viewWillDisappearSelector);
114 |
115 | Method originalViewDidAppearMethod = class_getInstanceMethod([UIViewController class], viewDidAppearSelector);
116 | Method swizzledViewDidAppearMethod = class_getInstanceMethod([PIXELViewController class], viewDidAppearSelector);
117 |
118 | Method originalViewWillAppearMethod = class_getInstanceMethod([UIViewController class], viewWillAppearSelector);
119 | Method swizzledViewWillAppearMethod = class_getInstanceMethod([PIXELViewController class], viewWillAppearSelector);
120 |
121 | method_exchangeImplementations(originalViewDidLoadMethod, swizzledViewDidLoadMethod);
122 | method_exchangeImplementations(originalViewWillDisappearMethod, swizzledViewWillDisappearMethod);
123 | method_exchangeImplementations(originalViewDidAppearMethod, swizzledViewDidAppearMethod);
124 | method_exchangeImplementations(originalViewWillAppearMethod, swizzledViewWillAppearMethod);
125 | });
126 | }
127 |
128 | - (void)viewDidLoad
129 | {
130 | viewDidLoadImplementation();
131 | }
132 |
133 | - (void)viewWillDisappear:(BOOL)animated
134 | {
135 | viewWillDisappearImplementation();
136 | }
137 |
138 | - (void)viewDidAppear:(BOOL)animated
139 | {
140 | viewDidAppearImplementation();
141 | }
142 |
143 | - (void)viewWillAppear:(BOOL)animated
144 | {
145 | viewWillAppearImplementation();
146 | }
147 |
148 | - (void)setControllersClassesAndImages:(NSDictionary *)classesImagesDict
149 | {
150 | _classesImagesDict = classesImagesDict;
151 | }
152 |
153 | - (UIImage *)imageForControllerClass:(Class)aClass
154 | {
155 | NSString *keyClass = NSStringFromClass(aClass);
156 | NSString *imageName = self.classesImagesDict[keyClass];
157 |
158 | return [UIImage imageNamed:imageName];
159 | }
160 |
161 | - (UIWindow *)overlayWindow
162 | {
163 | if (_overlayWindow == nil) {
164 | _overlayWindow = [[PIXELWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
165 | _overlayWindow.windowLevel = UIWindowLevelStatusBar;
166 | _overlayWindow.hidden = NO;
167 | _overlayWindow.backgroundColor = [UIColor clearColor];
168 | }
169 |
170 | return _overlayWindow;
171 | }
172 |
173 | @end
174 |
--------------------------------------------------------------------------------
/PixelPerfect/PIXELViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // PPPerfectViewController.m
3 | // PerfectPixel-Example
4 | //
5 | // Created by Yuri on 4/30/15.
6 | // Copyright (c) 2015 Yuri Kobets. All rights reserved.
7 | //
8 |
9 | #import "PIXELViewController.h"
10 | #import "PIXELPerfect.h"
11 | #import "PIXELWindow.h"
12 | #import "UIImage+ColorInverse.h"
13 | #import
14 | #import "PIXELSettingsViewController.h"
15 |
16 | static NSInteger const kPIXELShowButtonTag = 1001;
17 | static NSInteger const kPIXELSettingsButtonTag = 1002;
18 | static NSInteger const kPIXELMockupImageViewTag = 1003;
19 |
20 | @interface PIXELViewController ()
21 | {
22 | UIImageView *_mockupImageView;
23 | }
24 |
25 | @end
26 |
27 | @implementation PIXELViewController
28 |
29 |
30 | - (void)viewDidLoad
31 | {
32 | Class class = object_getClass(self);
33 |
34 | SEL showMockupSelector = @selector(showOrHideMockupImageView);
35 | Method showMockupMethod = class_getInstanceMethod([PIXELViewController class], showMockupSelector);
36 | IMP showMockupImp = method_getImplementation(showMockupMethod);
37 | const char *showMockupMethodTypeEncoding = method_getTypeEncoding(showMockupMethod);
38 | class_addMethod(class, showMockupSelector, showMockupImp, showMockupMethodTypeEncoding);
39 |
40 | SEL showSettingsSelector = @selector(settingsPressed:);
41 | Method showSettingsMethod = class_getInstanceMethod([PIXELViewController class], showSettingsSelector);
42 | IMP showSettingsImp = method_getImplementation(showSettingsMethod);
43 | const char *showSettingsMethodTypeEncoding = method_getTypeEncoding(showSettingsMethod);
44 | class_addMethod(class, showSettingsSelector, showSettingsImp, showSettingsMethodTypeEncoding);
45 |
46 | UIImage *image = [[PIXELPerfect shared] imageForControllerClass:[self class]];
47 |
48 | if (image) {
49 |
50 | [PIXELPerfect shared].recentUsedClass = [self class];
51 |
52 | [PIXELPerfect shared].overlayWindow.hidden = NO;
53 |
54 | _mockupImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
55 | _mockupImageView.tag = kPIXELMockupImageViewTag;
56 | _mockupImageView.image = [PIXELPerfect shared].isImageInverted ? image.inverseColors : image;
57 | _mockupImageView.alpha = 0.5;
58 | _mockupImageView.hidden = ![PIXELPerfect shared].isShowingOnStart;
59 |
60 | [[PIXELPerfect shared].overlayWindow makeKeyWindow];
61 | [[PIXELPerfect shared].overlayWindow addSubview:_mockupImageView];
62 |
63 | UIButton *showButton = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.view.bounds)/2. - 110.,
64 | 0,
65 | 100.0,
66 | 20.)];
67 | showButton.tag = kPIXELShowButtonTag;
68 | showButton.backgroundColor = [UIColor lightGrayColor];
69 | showButton.layer.masksToBounds = YES;
70 | showButton.layer.cornerRadius = 5.;
71 |
72 | NSString *title = _mockupImageView.isHidden ? @"show" : @"hide";
73 |
74 | [showButton setTitle:title forState:UIControlStateNormal];
75 | [showButton addTarget:self action:@selector(showOrHideMockupImageView) forControlEvents:UIControlEventTouchUpInside];
76 |
77 | [[PIXELPerfect shared].overlayWindow addSubview:showButton];
78 |
79 | UIButton *settingsButton = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.view.bounds)/2. + 10.,
80 | 0,
81 | 100.0,
82 | 20.)];
83 | settingsButton.tag = kPIXELSettingsButtonTag;
84 | settingsButton.backgroundColor = [UIColor lightGrayColor];
85 | settingsButton.layer.masksToBounds = YES;
86 | settingsButton.layer.cornerRadius = 5.;
87 |
88 | [settingsButton setTitle:@"Settings" forState:UIControlStateNormal];
89 | [settingsButton addTarget:self action:@selector(settingsPressed:) forControlEvents:UIControlEventTouchUpInside];
90 |
91 | [[PIXELPerfect shared].overlayWindow addSubview:settingsButton];
92 | }
93 | }
94 |
95 | - (void)viewWillDisappear:(BOOL)animated
96 | {
97 | if ([self isKindOfClass:[PIXELPerfect shared].recentUsedClass]) {
98 | [PIXELPerfect shared].overlayWindow.hidden = YES;
99 | }
100 | }
101 |
102 | - (void)viewWillAppear:(BOOL)animated
103 | {
104 | if ([self isKindOfClass:[PIXELPerfect shared].recentUsedClass]) {
105 | [PIXELPerfect shared].overlayWindow.hidden = NO;
106 | }
107 |
108 | UIImage *image = [[PIXELPerfect shared] imageForControllerClass:[self class]];
109 |
110 | if (image) {
111 | UIImageView *mockupImageView = (UIImageView *)[[PIXELPerfect shared].overlayWindow viewWithTag:kPIXELMockupImageViewTag];
112 | mockupImageView.image = [PIXELPerfect shared].isImageInverted ? image.inverseColors : image;
113 |
114 | mockupImageView.alpha = [PIXELPerfect shared].imageAlpha;
115 | }
116 | }
117 |
118 | #pragma mark -
119 |
120 | - (void)showOrHideMockupImageView
121 | {
122 | _mockupImageView.hidden = !_mockupImageView.isHidden;
123 |
124 | if (_mockupImageView.isHidden) {
125 | __block CGRect frame = _mockupImageView.frame;
126 | frame.origin.y = -CGRectGetHeight(_mockupImageView.bounds);
127 | _mockupImageView.frame = frame;
128 |
129 | [UIView animateWithDuration:0.8 animations:^{
130 | frame.origin.y = 0;
131 | _mockupImageView.frame = frame;
132 | }];
133 | }
134 |
135 | NSString *title = _mockupImageView.isHidden ? @"show" : @"hide";
136 |
137 | UIButton *showButton = (UIButton *)[[PIXELPerfect shared].overlayWindow viewWithTag:kPIXELShowButtonTag];
138 | [showButton setTitle:title forState:UIControlStateNormal];
139 | }
140 |
141 | - (void)settingsPressed:(id)sender
142 | {
143 | PIXELSettingsViewController *settingsViewController = [[PIXELSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
144 | UINavigationController *navigationViewController = [[UINavigationController alloc] initWithRootViewController:settingsViewController];
145 | [self presentViewController:navigationViewController animated:YES completion:nil];
146 | }
147 |
148 | @end
149 |
--------------------------------------------------------------------------------
/PixelPerfect-Example/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 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/PixelPerfect-Example.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 810BB50A1B1907EE0007746B /* CoreImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 810BB5091B1907EE0007746B /* CoreImage.framework */; };
11 | 81355A6A1B04C459007C9830 /* PixelPerfectTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 81355A691B04C459007C9830 /* PixelPerfectTests.m */; };
12 | 81355A9B1B04C50A007C9830 /* PIXELPerfect.m in Sources */ = {isa = PBXBuildFile; fileRef = 81355A741B04C50A007C9830 /* PIXELPerfect.m */; };
13 | 81355A9C1B04C50A007C9830 /* PIXELViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 81355A761B04C50A007C9830 /* PIXELViewController.m */; };
14 | 81355A9D1B04C50A007C9830 /* PIXELWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 81355A781B04C50A007C9830 /* PIXELWindow.m */; };
15 | 81355A9E1B04C50A007C9830 /* UIImage+ColorInverse.m in Sources */ = {isa = PBXBuildFile; fileRef = 81355A7A1B04C50A007C9830 /* UIImage+ColorInverse.m */; };
16 | 81355A9F1B04C50A007C9830 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 81355A7D1B04C50A007C9830 /* AppDelegate.m */; };
17 | 81355AA01B04C50A007C9830 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 81355A7E1B04C50A007C9830 /* LaunchScreen.xib */; };
18 | 81355AA11B04C50A007C9830 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81355A801B04C50A007C9830 /* Main.storyboard */; };
19 | 81355AA21B04C50A007C9830 /* ExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 81355A841B04C50A007C9830 /* ExampleViewController.m */; };
20 | 81355AA31B04C50A007C9830 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 81355A851B04C50A007C9830 /* Images.xcassets */; };
21 | 81355AA51B04C50A007C9830 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 81355A871B04C50A007C9830 /* main.m */; };
22 | 81355AA61B04C50A007C9830 /* add-point.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A891B04C50A007C9830 /* add-point.png */; };
23 | 81355AA71B04C50A007C9830 /* add-password-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A8B1B04C50A007C9830 /* add-password-icon.png */; };
24 | 81355AA81B04C50A007C9830 /* add-password-icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A8C1B04C50A007C9830 /* add-password-icon@2x.png */; };
25 | 81355AA91B04C50A007C9830 /* add-password-icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A8D1B04C50A007C9830 /* add-password-icon@3x.png */; };
26 | 81355AAA1B04C50A007C9830 /* add-point-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A8E1B04C50A007C9830 /* add-point-icon.png */; };
27 | 81355AAB1B04C50A007C9830 /* add-point-icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A8F1B04C50A007C9830 /* add-point-icon@2x.png */; };
28 | 81355AAC1B04C50A007C9830 /* add-point-icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A901B04C50A007C9830 /* add-point-icon@3x.png */; };
29 | 81355AAD1B04C50A007C9830 /* background@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A911B04C50A007C9830 /* background@2x.png */; };
30 | 81355AAE1B04C50A007C9830 /* facebook-btn-normal.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A921B04C50A007C9830 /* facebook-btn-normal.png */; };
31 | 81355AAF1B04C50A007C9830 /* facebook-btn-normal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A931B04C50A007C9830 /* facebook-btn-normal@2x.png */; };
32 | 81355AB01B04C50A007C9830 /* facebook-btn-normal@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A941B04C50A007C9830 /* facebook-btn-normal@3x.png */; };
33 | 81355AB11B04C50A007C9830 /* facebook-btn-selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A951B04C50A007C9830 /* facebook-btn-selected.png */; };
34 | 81355AB21B04C50A007C9830 /* facebook-btn-selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A961B04C50A007C9830 /* facebook-btn-selected@2x.png */; };
35 | 81355AB31B04C50A007C9830 /* facebook-btn-selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 81355A971B04C50A007C9830 /* facebook-btn-selected@3x.png */; };
36 | 8190EA9D1B08913C0059465E /* PIXELSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8190EA9C1B08913C0059465E /* PIXELSettingsViewController.m */; };
37 | /* End PBXBuildFile section */
38 |
39 | /* Begin PBXContainerItemProxy section */
40 | 81355A641B04C458007C9830 /* PBXContainerItemProxy */ = {
41 | isa = PBXContainerItemProxy;
42 | containerPortal = 8117763D1AF2A8E900D288A7 /* Project object */;
43 | proxyType = 1;
44 | remoteGlobalIDString = 81355A4A1B04C458007C9830;
45 | remoteInfo = PixelPerfect;
46 | };
47 | /* End PBXContainerItemProxy section */
48 |
49 | /* Begin PBXFileReference section */
50 | 810BB5091B1907EE0007746B /* CoreImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; };
51 | 81355A4B1B04C458007C9830 /* PixelPerfect.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PixelPerfect.app; sourceTree = BUILT_PRODUCTS_DIR; };
52 | 81355A631B04C458007C9830 /* PixelPerfectTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PixelPerfectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
53 | 81355A681B04C459007C9830 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
54 | 81355A691B04C459007C9830 /* PixelPerfectTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PixelPerfectTests.m; sourceTree = ""; };
55 | 81355A731B04C50A007C9830 /* PIXELPerfect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PIXELPerfect.h; sourceTree = ""; };
56 | 81355A741B04C50A007C9830 /* PIXELPerfect.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PIXELPerfect.m; sourceTree = ""; };
57 | 81355A751B04C50A007C9830 /* PIXELViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PIXELViewController.h; sourceTree = ""; };
58 | 81355A761B04C50A007C9830 /* PIXELViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PIXELViewController.m; sourceTree = ""; };
59 | 81355A771B04C50A007C9830 /* PIXELWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PIXELWindow.h; sourceTree = ""; };
60 | 81355A781B04C50A007C9830 /* PIXELWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PIXELWindow.m; sourceTree = ""; };
61 | 81355A791B04C50A007C9830 /* UIImage+ColorInverse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+ColorInverse.h"; sourceTree = ""; };
62 | 81355A7A1B04C50A007C9830 /* UIImage+ColorInverse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+ColorInverse.m"; sourceTree = ""; };
63 | 81355A7C1B04C50A007C9830 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
64 | 81355A7D1B04C50A007C9830 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
65 | 81355A7F1B04C50A007C9830 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
66 | 81355A811B04C50A007C9830 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
67 | 81355A831B04C50A007C9830 /* ExampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExampleViewController.h; sourceTree = ""; };
68 | 81355A841B04C50A007C9830 /* ExampleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleViewController.m; sourceTree = ""; };
69 | 81355A851B04C50A007C9830 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ../Images.xcassets; sourceTree = ""; };
70 | 81355A861B04C50A007C9830 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
71 | 81355A871B04C50A007C9830 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
72 | 81355A891B04C50A007C9830 /* add-point.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add-point.png"; sourceTree = ""; };
73 | 81355A8B1B04C50A007C9830 /* add-password-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add-password-icon.png"; sourceTree = ""; };
74 | 81355A8C1B04C50A007C9830 /* add-password-icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add-password-icon@2x.png"; sourceTree = ""; };
75 | 81355A8D1B04C50A007C9830 /* add-password-icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add-password-icon@3x.png"; sourceTree = ""; };
76 | 81355A8E1B04C50A007C9830 /* add-point-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add-point-icon.png"; sourceTree = ""; };
77 | 81355A8F1B04C50A007C9830 /* add-point-icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add-point-icon@2x.png"; sourceTree = ""; };
78 | 81355A901B04C50A007C9830 /* add-point-icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add-point-icon@3x.png"; sourceTree = ""; };
79 | 81355A911B04C50A007C9830 /* background@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background@2x.png"; sourceTree = ""; };
80 | 81355A921B04C50A007C9830 /* facebook-btn-normal.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "facebook-btn-normal.png"; sourceTree = ""; };
81 | 81355A931B04C50A007C9830 /* facebook-btn-normal@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "facebook-btn-normal@2x.png"; sourceTree = ""; };
82 | 81355A941B04C50A007C9830 /* facebook-btn-normal@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "facebook-btn-normal@3x.png"; sourceTree = ""; };
83 | 81355A951B04C50A007C9830 /* facebook-btn-selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "facebook-btn-selected.png"; sourceTree = ""; };
84 | 81355A961B04C50A007C9830 /* facebook-btn-selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "facebook-btn-selected@2x.png"; sourceTree = ""; };
85 | 81355A971B04C50A007C9830 /* facebook-btn-selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "facebook-btn-selected@3x.png"; sourceTree = ""; };
86 | 814D4FF81B94F37800699ED9 /* PIXELPerfect+Public.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PIXELPerfect+Public.h"; sourceTree = ""; };
87 | 8190EA9B1B08913C0059465E /* PIXELSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PIXELSettingsViewController.h; sourceTree = ""; };
88 | 8190EA9C1B08913C0059465E /* PIXELSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PIXELSettingsViewController.m; sourceTree = ""; };
89 | /* End PBXFileReference section */
90 |
91 | /* Begin PBXFrameworksBuildPhase section */
92 | 81355A481B04C458007C9830 /* Frameworks */ = {
93 | isa = PBXFrameworksBuildPhase;
94 | buildActionMask = 2147483647;
95 | files = (
96 | 810BB50A1B1907EE0007746B /* CoreImage.framework in Frameworks */,
97 | );
98 | runOnlyForDeploymentPostprocessing = 0;
99 | };
100 | 81355A601B04C458007C9830 /* Frameworks */ = {
101 | isa = PBXFrameworksBuildPhase;
102 | buildActionMask = 2147483647;
103 | files = (
104 | );
105 | runOnlyForDeploymentPostprocessing = 0;
106 | };
107 | /* End PBXFrameworksBuildPhase section */
108 |
109 | /* Begin PBXGroup section */
110 | 810BB50B1B1908020007746B /* frameworks */ = {
111 | isa = PBXGroup;
112 | children = (
113 | 810BB5091B1907EE0007746B /* CoreImage.framework */,
114 | );
115 | name = frameworks;
116 | sourceTree = "";
117 | };
118 | 8117763C1AF2A8E900D288A7 = {
119 | isa = PBXGroup;
120 | children = (
121 | 81355A721B04C50A007C9830 /* PixelPerfect */,
122 | 81355A7B1B04C50A007C9830 /* PixelPerfect-Example */,
123 | 81355A661B04C459007C9830 /* PixelPerfectTests */,
124 | 811776461AF2A8E900D288A7 /* Products */,
125 | );
126 | sourceTree = "";
127 | };
128 | 811776461AF2A8E900D288A7 /* Products */ = {
129 | isa = PBXGroup;
130 | children = (
131 | 81355A4B1B04C458007C9830 /* PixelPerfect.app */,
132 | 81355A631B04C458007C9830 /* PixelPerfectTests.xctest */,
133 | );
134 | name = Products;
135 | sourceTree = "";
136 | };
137 | 81355A661B04C459007C9830 /* PixelPerfectTests */ = {
138 | isa = PBXGroup;
139 | children = (
140 | 81355A691B04C459007C9830 /* PixelPerfectTests.m */,
141 | 81355A671B04C459007C9830 /* Supporting Files */,
142 | );
143 | path = PixelPerfectTests;
144 | sourceTree = "";
145 | };
146 | 81355A671B04C459007C9830 /* Supporting Files */ = {
147 | isa = PBXGroup;
148 | children = (
149 | 81355A681B04C459007C9830 /* Info.plist */,
150 | );
151 | name = "Supporting Files";
152 | sourceTree = "";
153 | };
154 | 81355A721B04C50A007C9830 /* PixelPerfect */ = {
155 | isa = PBXGroup;
156 | children = (
157 | 81355A731B04C50A007C9830 /* PIXELPerfect.h */,
158 | 81355A741B04C50A007C9830 /* PIXELPerfect.m */,
159 | 81355A751B04C50A007C9830 /* PIXELViewController.h */,
160 | 81355A761B04C50A007C9830 /* PIXELViewController.m */,
161 | 81355A771B04C50A007C9830 /* PIXELWindow.h */,
162 | 81355A781B04C50A007C9830 /* PIXELWindow.m */,
163 | 81355A791B04C50A007C9830 /* UIImage+ColorInverse.h */,
164 | 81355A7A1B04C50A007C9830 /* UIImage+ColorInverse.m */,
165 | 8190EA9B1B08913C0059465E /* PIXELSettingsViewController.h */,
166 | 8190EA9C1B08913C0059465E /* PIXELSettingsViewController.m */,
167 | 814D4FF81B94F37800699ED9 /* PIXELPerfect+Public.h */,
168 | );
169 | path = PixelPerfect;
170 | sourceTree = "";
171 | };
172 | 81355A7B1B04C50A007C9830 /* PixelPerfect-Example */ = {
173 | isa = PBXGroup;
174 | children = (
175 | 81355A7C1B04C50A007C9830 /* AppDelegate.h */,
176 | 81355A7D1B04C50A007C9830 /* AppDelegate.m */,
177 | 81355A7E1B04C50A007C9830 /* LaunchScreen.xib */,
178 | 81355A801B04C50A007C9830 /* Main.storyboard */,
179 | 81355A821B04C50A007C9830 /* classes */,
180 | 810BB50B1B1908020007746B /* frameworks */,
181 | 81355A881B04C50A007C9830 /* mockups */,
182 | 81355A8A1B04C50A007C9830 /* resources */,
183 | 81355AB51B04C518007C9830 /* Supporting Files */,
184 | );
185 | path = "PixelPerfect-Example";
186 | sourceTree = "";
187 | };
188 | 81355A821B04C50A007C9830 /* classes */ = {
189 | isa = PBXGroup;
190 | children = (
191 | 81355A831B04C50A007C9830 /* ExampleViewController.h */,
192 | 81355A841B04C50A007C9830 /* ExampleViewController.m */,
193 | );
194 | path = classes;
195 | sourceTree = "";
196 | };
197 | 81355A881B04C50A007C9830 /* mockups */ = {
198 | isa = PBXGroup;
199 | children = (
200 | 81355A891B04C50A007C9830 /* add-point.png */,
201 | );
202 | path = mockups;
203 | sourceTree = "";
204 | };
205 | 81355A8A1B04C50A007C9830 /* resources */ = {
206 | isa = PBXGroup;
207 | children = (
208 | 81355A851B04C50A007C9830 /* Images.xcassets */,
209 | 81355A8B1B04C50A007C9830 /* add-password-icon.png */,
210 | 81355A8C1B04C50A007C9830 /* add-password-icon@2x.png */,
211 | 81355A8D1B04C50A007C9830 /* add-password-icon@3x.png */,
212 | 81355A8E1B04C50A007C9830 /* add-point-icon.png */,
213 | 81355A8F1B04C50A007C9830 /* add-point-icon@2x.png */,
214 | 81355A901B04C50A007C9830 /* add-point-icon@3x.png */,
215 | 81355A911B04C50A007C9830 /* background@2x.png */,
216 | 81355A921B04C50A007C9830 /* facebook-btn-normal.png */,
217 | 81355A931B04C50A007C9830 /* facebook-btn-normal@2x.png */,
218 | 81355A941B04C50A007C9830 /* facebook-btn-normal@3x.png */,
219 | 81355A951B04C50A007C9830 /* facebook-btn-selected.png */,
220 | 81355A961B04C50A007C9830 /* facebook-btn-selected@2x.png */,
221 | 81355A971B04C50A007C9830 /* facebook-btn-selected@3x.png */,
222 | );
223 | path = resources;
224 | sourceTree = "";
225 | };
226 | 81355AB51B04C518007C9830 /* Supporting Files */ = {
227 | isa = PBXGroup;
228 | children = (
229 | 81355A861B04C50A007C9830 /* Info.plist */,
230 | 81355A871B04C50A007C9830 /* main.m */,
231 | );
232 | name = "Supporting Files";
233 | sourceTree = "";
234 | };
235 | /* End PBXGroup section */
236 |
237 | /* Begin PBXNativeTarget section */
238 | 81355A4A1B04C458007C9830 /* PixelPerfect */ = {
239 | isa = PBXNativeTarget;
240 | buildConfigurationList = 81355A6B1B04C459007C9830 /* Build configuration list for PBXNativeTarget "PixelPerfect" */;
241 | buildPhases = (
242 | 81355A471B04C458007C9830 /* Sources */,
243 | 81355A481B04C458007C9830 /* Frameworks */,
244 | 81355A491B04C458007C9830 /* Resources */,
245 | );
246 | buildRules = (
247 | );
248 | dependencies = (
249 | );
250 | name = PixelPerfect;
251 | productName = PixelPerfect;
252 | productReference = 81355A4B1B04C458007C9830 /* PixelPerfect.app */;
253 | productType = "com.apple.product-type.application";
254 | };
255 | 81355A621B04C458007C9830 /* PixelPerfectTests */ = {
256 | isa = PBXNativeTarget;
257 | buildConfigurationList = 81355A6E1B04C459007C9830 /* Build configuration list for PBXNativeTarget "PixelPerfectTests" */;
258 | buildPhases = (
259 | 81355A5F1B04C458007C9830 /* Sources */,
260 | 81355A601B04C458007C9830 /* Frameworks */,
261 | 81355A611B04C458007C9830 /* Resources */,
262 | );
263 | buildRules = (
264 | );
265 | dependencies = (
266 | 81355A651B04C458007C9830 /* PBXTargetDependency */,
267 | );
268 | name = PixelPerfectTests;
269 | productName = PixelPerfectTests;
270 | productReference = 81355A631B04C458007C9830 /* PixelPerfectTests.xctest */;
271 | productType = "com.apple.product-type.bundle.unit-test";
272 | };
273 | /* End PBXNativeTarget section */
274 |
275 | /* Begin PBXProject section */
276 | 8117763D1AF2A8E900D288A7 /* Project object */ = {
277 | isa = PBXProject;
278 | attributes = {
279 | LastUpgradeCheck = 0630;
280 | ORGANIZATIONNAME = "Yuri Kobets";
281 | TargetAttributes = {
282 | 81355A4A1B04C458007C9830 = {
283 | CreatedOnToolsVersion = 6.3.1;
284 | };
285 | 81355A621B04C458007C9830 = {
286 | CreatedOnToolsVersion = 6.3.1;
287 | TestTargetID = 81355A4A1B04C458007C9830;
288 | };
289 | };
290 | };
291 | buildConfigurationList = 811776401AF2A8E900D288A7 /* Build configuration list for PBXProject "PixelPerfect-Example" */;
292 | compatibilityVersion = "Xcode 3.2";
293 | developmentRegion = English;
294 | hasScannedForEncodings = 0;
295 | knownRegions = (
296 | en,
297 | Base,
298 | );
299 | mainGroup = 8117763C1AF2A8E900D288A7;
300 | productRefGroup = 811776461AF2A8E900D288A7 /* Products */;
301 | projectDirPath = "";
302 | projectRoot = "";
303 | targets = (
304 | 81355A4A1B04C458007C9830 /* PixelPerfect */,
305 | 81355A621B04C458007C9830 /* PixelPerfectTests */,
306 | );
307 | };
308 | /* End PBXProject section */
309 |
310 | /* Begin PBXResourcesBuildPhase section */
311 | 81355A491B04C458007C9830 /* Resources */ = {
312 | isa = PBXResourcesBuildPhase;
313 | buildActionMask = 2147483647;
314 | files = (
315 | 81355AAB1B04C50A007C9830 /* add-point-icon@2x.png in Resources */,
316 | 81355AAA1B04C50A007C9830 /* add-point-icon.png in Resources */,
317 | 81355AA71B04C50A007C9830 /* add-password-icon.png in Resources */,
318 | 81355AA61B04C50A007C9830 /* add-point.png in Resources */,
319 | 81355AAC1B04C50A007C9830 /* add-point-icon@3x.png in Resources */,
320 | 81355AAF1B04C50A007C9830 /* facebook-btn-normal@2x.png in Resources */,
321 | 81355AA81B04C50A007C9830 /* add-password-icon@2x.png in Resources */,
322 | 81355AA31B04C50A007C9830 /* Images.xcassets in Resources */,
323 | 81355AB01B04C50A007C9830 /* facebook-btn-normal@3x.png in Resources */,
324 | 81355AB21B04C50A007C9830 /* facebook-btn-selected@2x.png in Resources */,
325 | 81355AB31B04C50A007C9830 /* facebook-btn-selected@3x.png in Resources */,
326 | 81355AA91B04C50A007C9830 /* add-password-icon@3x.png in Resources */,
327 | 81355AA01B04C50A007C9830 /* LaunchScreen.xib in Resources */,
328 | 81355AAD1B04C50A007C9830 /* background@2x.png in Resources */,
329 | 81355AB11B04C50A007C9830 /* facebook-btn-selected.png in Resources */,
330 | 81355AA11B04C50A007C9830 /* Main.storyboard in Resources */,
331 | 81355AAE1B04C50A007C9830 /* facebook-btn-normal.png in Resources */,
332 | );
333 | runOnlyForDeploymentPostprocessing = 0;
334 | };
335 | 81355A611B04C458007C9830 /* Resources */ = {
336 | isa = PBXResourcesBuildPhase;
337 | buildActionMask = 2147483647;
338 | files = (
339 | );
340 | runOnlyForDeploymentPostprocessing = 0;
341 | };
342 | /* End PBXResourcesBuildPhase section */
343 |
344 | /* Begin PBXSourcesBuildPhase section */
345 | 81355A471B04C458007C9830 /* Sources */ = {
346 | isa = PBXSourcesBuildPhase;
347 | buildActionMask = 2147483647;
348 | files = (
349 | 81355A9E1B04C50A007C9830 /* UIImage+ColorInverse.m in Sources */,
350 | 81355A9B1B04C50A007C9830 /* PIXELPerfect.m in Sources */,
351 | 8190EA9D1B08913C0059465E /* PIXELSettingsViewController.m in Sources */,
352 | 81355A9D1B04C50A007C9830 /* PIXELWindow.m in Sources */,
353 | 81355AA21B04C50A007C9830 /* ExampleViewController.m in Sources */,
354 | 81355A9C1B04C50A007C9830 /* PIXELViewController.m in Sources */,
355 | 81355AA51B04C50A007C9830 /* main.m in Sources */,
356 | 81355A9F1B04C50A007C9830 /* AppDelegate.m in Sources */,
357 | );
358 | runOnlyForDeploymentPostprocessing = 0;
359 | };
360 | 81355A5F1B04C458007C9830 /* Sources */ = {
361 | isa = PBXSourcesBuildPhase;
362 | buildActionMask = 2147483647;
363 | files = (
364 | 81355A6A1B04C459007C9830 /* PixelPerfectTests.m in Sources */,
365 | );
366 | runOnlyForDeploymentPostprocessing = 0;
367 | };
368 | /* End PBXSourcesBuildPhase section */
369 |
370 | /* Begin PBXTargetDependency section */
371 | 81355A651B04C458007C9830 /* PBXTargetDependency */ = {
372 | isa = PBXTargetDependency;
373 | target = 81355A4A1B04C458007C9830 /* PixelPerfect */;
374 | targetProxy = 81355A641B04C458007C9830 /* PBXContainerItemProxy */;
375 | };
376 | /* End PBXTargetDependency section */
377 |
378 | /* Begin PBXVariantGroup section */
379 | 81355A7E1B04C50A007C9830 /* LaunchScreen.xib */ = {
380 | isa = PBXVariantGroup;
381 | children = (
382 | 81355A7F1B04C50A007C9830 /* Base */,
383 | );
384 | name = LaunchScreen.xib;
385 | sourceTree = "";
386 | };
387 | 81355A801B04C50A007C9830 /* Main.storyboard */ = {
388 | isa = PBXVariantGroup;
389 | children = (
390 | 81355A811B04C50A007C9830 /* Base */,
391 | );
392 | name = Main.storyboard;
393 | sourceTree = "";
394 | };
395 | /* End PBXVariantGroup section */
396 |
397 | /* Begin XCBuildConfiguration section */
398 | 811776661AF2A8EA00D288A7 /* Debug */ = {
399 | isa = XCBuildConfiguration;
400 | buildSettings = {
401 | ALWAYS_SEARCH_USER_PATHS = NO;
402 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
403 | CLANG_CXX_LIBRARY = "libc++";
404 | CLANG_ENABLE_MODULES = YES;
405 | CLANG_ENABLE_OBJC_ARC = YES;
406 | CLANG_WARN_BOOL_CONVERSION = YES;
407 | CLANG_WARN_CONSTANT_CONVERSION = YES;
408 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
409 | CLANG_WARN_EMPTY_BODY = YES;
410 | CLANG_WARN_ENUM_CONVERSION = YES;
411 | CLANG_WARN_INT_CONVERSION = YES;
412 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
413 | CLANG_WARN_UNREACHABLE_CODE = YES;
414 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
415 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
416 | COPY_PHASE_STRIP = NO;
417 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
418 | ENABLE_STRICT_OBJC_MSGSEND = YES;
419 | GCC_C_LANGUAGE_STANDARD = gnu99;
420 | GCC_DYNAMIC_NO_PIC = NO;
421 | GCC_NO_COMMON_BLOCKS = YES;
422 | GCC_OPTIMIZATION_LEVEL = 0;
423 | GCC_PREPROCESSOR_DEFINITIONS = (
424 | "DEBUG=1",
425 | "$(inherited)",
426 | );
427 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
428 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
429 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
430 | GCC_WARN_UNDECLARED_SELECTOR = YES;
431 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
432 | GCC_WARN_UNUSED_FUNCTION = YES;
433 | GCC_WARN_UNUSED_VARIABLE = YES;
434 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
435 | MTL_ENABLE_DEBUG_INFO = YES;
436 | ONLY_ACTIVE_ARCH = YES;
437 | SDKROOT = iphoneos;
438 | TARGETED_DEVICE_FAMILY = "1,2";
439 | };
440 | name = Debug;
441 | };
442 | 811776671AF2A8EA00D288A7 /* Release */ = {
443 | isa = XCBuildConfiguration;
444 | buildSettings = {
445 | ALWAYS_SEARCH_USER_PATHS = NO;
446 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
447 | CLANG_CXX_LIBRARY = "libc++";
448 | CLANG_ENABLE_MODULES = YES;
449 | CLANG_ENABLE_OBJC_ARC = YES;
450 | CLANG_WARN_BOOL_CONVERSION = YES;
451 | CLANG_WARN_CONSTANT_CONVERSION = YES;
452 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
453 | CLANG_WARN_EMPTY_BODY = YES;
454 | CLANG_WARN_ENUM_CONVERSION = YES;
455 | CLANG_WARN_INT_CONVERSION = YES;
456 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
457 | CLANG_WARN_UNREACHABLE_CODE = YES;
458 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
459 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
460 | COPY_PHASE_STRIP = NO;
461 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
462 | ENABLE_NS_ASSERTIONS = NO;
463 | ENABLE_STRICT_OBJC_MSGSEND = YES;
464 | GCC_C_LANGUAGE_STANDARD = gnu99;
465 | GCC_NO_COMMON_BLOCKS = YES;
466 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
467 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
468 | GCC_WARN_UNDECLARED_SELECTOR = YES;
469 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
470 | GCC_WARN_UNUSED_FUNCTION = YES;
471 | GCC_WARN_UNUSED_VARIABLE = YES;
472 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
473 | MTL_ENABLE_DEBUG_INFO = NO;
474 | SDKROOT = iphoneos;
475 | TARGETED_DEVICE_FAMILY = "1,2";
476 | VALIDATE_PRODUCT = YES;
477 | };
478 | name = Release;
479 | };
480 | 81355A6C1B04C459007C9830 /* Debug */ = {
481 | isa = XCBuildConfiguration;
482 | buildSettings = {
483 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
484 | GCC_PREPROCESSOR_DEFINITIONS = (
485 | "DEBUG=1",
486 | "$(inherited)",
487 | );
488 | INFOPLIST_FILE = "PixelPerfect-Example/Info.plist";
489 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
490 | PRODUCT_NAME = "$(TARGET_NAME)";
491 | };
492 | name = Debug;
493 | };
494 | 81355A6D1B04C459007C9830 /* Release */ = {
495 | isa = XCBuildConfiguration;
496 | buildSettings = {
497 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
498 | INFOPLIST_FILE = "PixelPerfect-Example/Info.plist";
499 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
500 | PRODUCT_NAME = "$(TARGET_NAME)";
501 | };
502 | name = Release;
503 | };
504 | 81355A6F1B04C459007C9830 /* Debug */ = {
505 | isa = XCBuildConfiguration;
506 | buildSettings = {
507 | BUNDLE_LOADER = "$(TEST_HOST)";
508 | FRAMEWORK_SEARCH_PATHS = (
509 | "$(SDKROOT)/Developer/Library/Frameworks",
510 | "$(inherited)",
511 | );
512 | GCC_PREPROCESSOR_DEFINITIONS = (
513 | "DEBUG=1",
514 | "$(inherited)",
515 | );
516 | INFOPLIST_FILE = PixelPerfectTests/Info.plist;
517 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
518 | PRODUCT_NAME = "$(TARGET_NAME)";
519 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PixelPerfect.app/PixelPerfect";
520 | };
521 | name = Debug;
522 | };
523 | 81355A701B04C459007C9830 /* Release */ = {
524 | isa = XCBuildConfiguration;
525 | buildSettings = {
526 | BUNDLE_LOADER = "$(TEST_HOST)";
527 | FRAMEWORK_SEARCH_PATHS = (
528 | "$(SDKROOT)/Developer/Library/Frameworks",
529 | "$(inherited)",
530 | );
531 | INFOPLIST_FILE = PixelPerfectTests/Info.plist;
532 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
533 | PRODUCT_NAME = "$(TARGET_NAME)";
534 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PixelPerfect.app/PixelPerfect";
535 | };
536 | name = Release;
537 | };
538 | /* End XCBuildConfiguration section */
539 |
540 | /* Begin XCConfigurationList section */
541 | 811776401AF2A8E900D288A7 /* Build configuration list for PBXProject "PixelPerfect-Example" */ = {
542 | isa = XCConfigurationList;
543 | buildConfigurations = (
544 | 811776661AF2A8EA00D288A7 /* Debug */,
545 | 811776671AF2A8EA00D288A7 /* Release */,
546 | );
547 | defaultConfigurationIsVisible = 0;
548 | defaultConfigurationName = Release;
549 | };
550 | 81355A6B1B04C459007C9830 /* Build configuration list for PBXNativeTarget "PixelPerfect" */ = {
551 | isa = XCConfigurationList;
552 | buildConfigurations = (
553 | 81355A6C1B04C459007C9830 /* Debug */,
554 | 81355A6D1B04C459007C9830 /* Release */,
555 | );
556 | defaultConfigurationIsVisible = 0;
557 | defaultConfigurationName = Release;
558 | };
559 | 81355A6E1B04C459007C9830 /* Build configuration list for PBXNativeTarget "PixelPerfectTests" */ = {
560 | isa = XCConfigurationList;
561 | buildConfigurations = (
562 | 81355A6F1B04C459007C9830 /* Debug */,
563 | 81355A701B04C459007C9830 /* Release */,
564 | );
565 | defaultConfigurationIsVisible = 0;
566 | defaultConfigurationName = Release;
567 | };
568 | /* End XCConfigurationList section */
569 | };
570 | rootObject = 8117763D1AF2A8E900D288A7 /* Project object */;
571 | }
572 |
--------------------------------------------------------------------------------