├── README.md ├── test ├── Images.xcassets │ ├── first.imageset │ │ ├── first.pdf │ │ └── Contents.json │ ├── second.imageset │ │ ├── second.pdf │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── FirstViewController.h ├── SecondViewController.h ├── UILabel+ContentSize.h ├── AppDelegate.h ├── main.m ├── SecondViewController.m ├── Config.h ├── UILabel+ContentSize.m ├── UIViewAdditions.h ├── Info.plist ├── AppDelegate.m ├── UIColor-Expanded.h ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── UIViewAdditions.m ├── FirstViewController.m └── UIColor-Expanded.m ├── test.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── project.pbxproj ├── .gitignore ├── testTests ├── Info.plist └── testTests.m └── LICENSE /README.md: -------------------------------------------------------------------------------- 1 | # WalkRecord 2 | 可记录行走路程,支持熄屏后台记录,本地推送通知已行走路程 3 | -------------------------------------------------------------------------------- /test/Images.xcassets/first.imageset/first.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ming1016/WalkRecord/master/test/Images.xcassets/first.imageset/first.pdf -------------------------------------------------------------------------------- /test/Images.xcassets/second.imageset/second.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ming1016/WalkRecord/master/test/Images.xcassets/second.imageset/second.pdf -------------------------------------------------------------------------------- /test/FirstViewController.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #import 4 | #import 5 | 6 | @interface FirstViewController : UIViewController 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /test.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/Images.xcassets/first.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "first.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /test/Images.xcassets/second.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "second.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /test/SecondViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.h 3 | // test 4 | // 5 | // Created by ming on 15/6/16. 6 | // Copyright (c) 2015年 ming. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SecondViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /test/UILabel+ContentSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+ContentSize.h 3 | // test 4 | // 5 | // Created by ming on 15/6/19. 6 | // Copyright (c) 2015年 ming. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface UILabel (ContentSize) 13 | - (CGSize)contentSize; 14 | @end 15 | -------------------------------------------------------------------------------- /test/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // test 4 | // 5 | // Created by ming on 15/6/16. 6 | // Copyright (c) 2015年 ming. 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 | -------------------------------------------------------------------------------- /test/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // test 4 | // 5 | // Created by ming on 15/6/16. 6 | // Copyright (c) 2015年 ming. 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 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | #Pods/ 27 | -------------------------------------------------------------------------------- /test/SecondViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.m 3 | // test 4 | // 5 | // Created by ming on 15/6/16. 6 | // Copyright (c) 2015年 ming. All rights reserved. 7 | // 8 | 9 | #import "SecondViewController.h" 10 | 11 | @interface SecondViewController () 12 | 13 | @end 14 | 15 | @implementation SecondViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view, typically from a nib. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /test/Config.h: -------------------------------------------------------------------------------- 1 | // 2 | // TEConfig.h 3 | // test 4 | // 5 | // Created by ming on 15/6/19. 6 | // Copyright (c) 2015年 ming. All rights reserved. 7 | // 8 | 9 | #ifndef test_TEConfig_h 10 | #define test_TEConfig_h 11 | 12 | #define FONT_NORMAL [UIFont systemFontOfSize:12] 13 | 14 | #define IPHONE_SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width) 15 | #define IPHONE_SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height) 16 | #define kScreenHeight [UIScreen mainScreen].bounds.size.height 17 | #define kScreenWidth [UIScreen mainScreen].bounds.size.width 18 | 19 | #endif 20 | 21 | #import "UIViewAdditions.h" 22 | #import "UILabel+ContentSize.h" 23 | #import "UIColor-Expanded.h" 24 | -------------------------------------------------------------------------------- /testTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.starming.test.$(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 | -------------------------------------------------------------------------------- /testTests/testTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // testTests.m 3 | // testTests 4 | // 5 | // Created by ming on 15/6/16. 6 | // Copyright (c) 2015年 ming. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface testTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation testTests 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 戴铭 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 | -------------------------------------------------------------------------------- /test/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 | } -------------------------------------------------------------------------------- /test/UILabel+ContentSize.m: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+ContentSize.m 3 | // test 4 | // 5 | // Created by ming on 15/6/19. 6 | // Copyright (c) 2015年 ming. All rights reserved. 7 | // 8 | 9 | #import "UILabel+ContentSize.h" 10 | 11 | @implementation UILabel (ContentSize) 12 | 13 | - (CGSize)contentSize 14 | { 15 | CGSize contentSize; 16 | if([[[UIDevice currentDevice] systemVersion] floatValue]<= 7.0) 17 | { 18 | [self setNumberOfLines:0]; 19 | [self setLineBreakMode:NSLineBreakByWordWrapping]; 20 | 21 | CGSize maximumLabelSize = CGSizeMake(self.frame.size.width,9999); 22 | contentSize = [[self text] sizeWithFont:[self font] constrainedToSize:maximumLabelSize lineBreakMode:[self lineBreakMode]]; 23 | } 24 | else 25 | { 26 | NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 27 | paragraphStyle.lineBreakMode = self.lineBreakMode; 28 | paragraphStyle.alignment = self.textAlignment; 29 | NSDictionary * attributes = @{NSFontAttributeName : [UIFont systemFontOfSize:12],NSParagraphStyleAttributeName:paragraphStyle}; 30 | contentSize = [self.text boundingRectWithSize:CGSizeMake(300, 99999) 31 | options:NSStringDrawingUsesLineFragmentOrigin 32 | attributes:attributes 33 | context:nil].size; 34 | } 35 | return contentSize; 36 | } 37 | @end 38 | -------------------------------------------------------------------------------- /test/UIViewAdditions.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface UIView (TTCategory) 5 | 6 | @property(nonatomic) CGFloat left; 7 | @property(nonatomic) CGFloat top; 8 | @property(nonatomic) CGFloat right; 9 | @property(nonatomic) CGFloat bottom; 10 | 11 | @property(nonatomic) CGFloat width; 12 | @property(nonatomic) CGFloat height; 13 | 14 | @property(nonatomic) CGFloat centerX; 15 | @property(nonatomic) CGFloat centerY; 16 | 17 | @property(nonatomic,readonly) CGFloat screenX; 18 | @property(nonatomic,readonly) CGFloat screenY; 19 | @property(nonatomic,readonly) CGFloat screenViewX; 20 | @property(nonatomic,readonly) CGFloat screenViewY; 21 | @property(nonatomic,readonly) CGRect screenFrame; 22 | 23 | @property(nonatomic) CGPoint origin; 24 | @property(nonatomic) CGSize size; 25 | 26 | @property(nonatomic) BOOL visible; 27 | 28 | /** 29 | * Finds the first descendant view (including this view) that is a member of a particular class. 30 | */ 31 | - (UIView*)descendantOrSelfWithClass:(Class)cls; 32 | 33 | /** 34 | * Finds the first ancestor view (including this view) that is a member of a particular class. 35 | */ 36 | - (UIView*)ancestorOrSelfWithClass:(Class)cls; 37 | 38 | /** 39 | * Removes all subviews. 40 | */ 41 | - (void)removeAllSubviews; 42 | 43 | 44 | /** 45 | * Calculates the offset of this view from another view in screen coordinates. 46 | */ 47 | - (CGPoint)offsetFromView:(UIView*)otherView; 48 | 49 | 50 | /** 51 | * The view controller whose view contains this view. 52 | */ 53 | - (UIViewController*)viewController; 54 | 55 | 56 | - (void)addSubviews:(NSArray *)views; 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /test/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.starming.test.$(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 | UIBackgroundModes 26 | 27 | location 28 | 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UIStatusBarTintParameters 38 | 39 | UINavigationBar 40 | 41 | Style 42 | UIBarStyleDefault 43 | Translucent 44 | 45 | 46 | 47 | NSLocationWhenInUseUsageDescription 48 | 需要地理位置信息哦 49 | NSLocationAlwaysUsageDescription 50 | 需要地理位置信息哦 51 | UISupportedInterfaceOrientations 52 | 53 | UIInterfaceOrientationPortrait 54 | UIInterfaceOrientationLandscapeLeft 55 | UIInterfaceOrientationLandscapeRight 56 | 57 | UISupportedInterfaceOrientations~ipad 58 | 59 | UIInterfaceOrientationPortrait 60 | UIInterfaceOrientationPortraitUpsideDown 61 | UIInterfaceOrientationLandscapeLeft 62 | UIInterfaceOrientationLandscapeRight 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /test/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // test 4 | // 5 | // Created by ming on 15/6/16. 6 | // Copyright (c) 2015年 ming. 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 | [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]]; 21 | return YES; 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 throttle down OpenGL ES frame rates. Games should use this method to pause the game. 27 | } 28 | 29 | - (void)applicationDidEnterBackground:(UIApplication *)application { 30 | // 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. 31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 32 | } 33 | 34 | - (void)applicationWillEnterForeground:(UIApplication *)application { 35 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 36 | } 37 | 38 | - (void)applicationDidBecomeActive:(UIApplication *)application { 39 | // 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. 40 | } 41 | 42 | - (void)applicationWillTerminate:(UIApplication *)application { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { 47 | NSLog(@"receive local notification"); 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /test/UIColor-Expanded.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #define SUPPORTS_UNDOCUMENTED_API 0 4 | 5 | @interface UIColor (UIColor_Expanded) 6 | @property (nonatomic, readonly) CGColorSpaceModel colorSpaceModel; 7 | @property (nonatomic, readonly) BOOL canProvideRGBComponents; 8 | @property (nonatomic, readonly) CGFloat red; // Only valid if canProvideRGBComponents is YES 9 | @property (nonatomic, readonly) CGFloat green; // Only valid if canProvideRGBComponents is YES 10 | @property (nonatomic, readonly) CGFloat blue; // Only valid if canProvideRGBComponents is YES 11 | @property (nonatomic, readonly) CGFloat white; // Only valid if colorSpaceModel == kCGColorSpaceModelMonochrome 12 | @property (nonatomic, readonly) CGFloat alpha; 13 | @property (nonatomic, readonly) UInt32 rgbHex; 14 | 15 | - (NSString *)colorSpaceString; 16 | 17 | - (NSArray *)arrayFromRGBAComponents; 18 | 19 | - (BOOL)red:(CGFloat *)r green:(CGFloat *)g blue:(CGFloat *)b alpha:(CGFloat *)a; 20 | 21 | - (UIColor *)colorByLuminanceMapping; 22 | 23 | - (UIColor *)colorByMultiplyingByRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; 24 | - (UIColor *) colorByAddingRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; 25 | - (UIColor *) colorByLighteningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; 26 | - (UIColor *) colorByDarkeningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; 27 | 28 | - (UIColor *)colorByMultiplyingBy:(CGFloat)f; 29 | - (UIColor *) colorByAdding:(CGFloat)f; 30 | - (UIColor *) colorByLighteningTo:(CGFloat)f; 31 | - (UIColor *) colorByDarkeningTo:(CGFloat)f; 32 | 33 | - (UIColor *)colorByMultiplyingByColor:(UIColor *)color; 34 | - (UIColor *) colorByAddingColor:(UIColor *)color; 35 | - (UIColor *) colorByLighteningToColor:(UIColor *)color; 36 | - (UIColor *) colorByDarkeningToColor:(UIColor *)color; 37 | 38 | - (NSString *)stringFromColor; 39 | - (NSString *)hexStringFromColor; 40 | 41 | + (UIColor *)randomColor; 42 | + (UIColor *)colorWithString:(NSString *)stringToConvert; 43 | + (UIColor *)colorWithRGBHex:(UInt32)hex; 44 | 45 | + (UIColor *)colorWithHexString:(NSString *)stringToConvert; 46 | + (UIColor *) colorWithHex:(uint) hex; 47 | 48 | + (UIColor *)colorWithName:(NSString *)cssColorName; 49 | 50 | @end 51 | 52 | #if SUPPORTS_UNDOCUMENTED_API 53 | // UIColor_Undocumented_Expanded 54 | // Methods which rely on undocumented methods of UIColor 55 | @interface UIColor (UIColor_Undocumented_Expanded) 56 | - (NSString *)fetchStyleString; 57 | - (UIColor *)rgbColor; // Via Poltras 58 | @end 59 | #endif // SUPPORTS_UNDOCUMENTED_API 60 | -------------------------------------------------------------------------------- /test/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 | -------------------------------------------------------------------------------- /test/UIViewAdditions.m: -------------------------------------------------------------------------------- 1 | #import "UIViewAdditions.h" 2 | 3 | 4 | @implementation UIView (TTCategory) 5 | 6 | - (BOOL)visible{ 7 | return !self.hidden; 8 | } 9 | 10 | - (void)setVisible:(BOOL)visible{ 11 | self.hidden = !visible; 12 | } 13 | 14 | - (CGFloat)left { 15 | return self.frame.origin.x; 16 | } 17 | 18 | - (void)setLeft:(CGFloat)x { 19 | CGRect frame = self.frame; 20 | frame.origin.x = x; 21 | self.frame = frame; 22 | } 23 | 24 | - (CGFloat)top { 25 | return self.frame.origin.y; 26 | } 27 | 28 | - (void)setTop:(CGFloat)y { 29 | CGRect frame = self.frame; 30 | frame.origin.y = y; 31 | self.frame = frame; 32 | } 33 | 34 | - (CGFloat)right { 35 | return self.frame.origin.x + self.frame.size.width; 36 | } 37 | 38 | - (void)setRight:(CGFloat)right { 39 | CGRect frame = self.frame; 40 | frame.origin.x = right - frame.size.width; 41 | self.frame = frame; 42 | } 43 | 44 | - (CGFloat)bottom { 45 | return self.frame.origin.y + self.frame.size.height; 46 | } 47 | 48 | - (void)setBottom:(CGFloat)bottom { 49 | CGRect frame = self.frame; 50 | frame.origin.y = bottom - frame.size.height; 51 | self.frame = frame; 52 | } 53 | 54 | - (CGFloat)centerX { 55 | return self.center.x; 56 | } 57 | 58 | - (void)setCenterX:(CGFloat)centerX { 59 | self.center = CGPointMake(centerX, self.center.y); 60 | } 61 | 62 | - (CGFloat)centerY { 63 | return self.center.y; 64 | } 65 | 66 | - (void)setCenterY:(CGFloat)centerY { 67 | self.center = CGPointMake(self.center.x, centerY); 68 | } 69 | 70 | - (CGFloat)width { 71 | return self.frame.size.width; 72 | } 73 | 74 | - (void)setWidth:(CGFloat)width { 75 | CGRect frame = self.frame; 76 | frame.size.width = width; 77 | self.frame = frame; 78 | } 79 | 80 | - (CGFloat)height { 81 | return self.frame.size.height; 82 | } 83 | 84 | - (void)setHeight:(CGFloat)height { 85 | CGRect frame = self.frame; 86 | frame.size.height = height; 87 | self.frame = frame; 88 | } 89 | 90 | - (CGFloat)screenX { 91 | CGFloat x = 0; 92 | for (UIView* view = self; view; view = view.superview) { 93 | x += view.left; 94 | } 95 | return x; 96 | } 97 | 98 | - (CGFloat)screenY { 99 | CGFloat y = 0; 100 | for (UIView* view = self; view; view = view.superview) { 101 | y += view.top; 102 | } 103 | return y; 104 | } 105 | 106 | - (CGFloat)screenViewX { 107 | CGFloat x = 0; 108 | for (UIView* view = self; view; view = view.superview) { 109 | x += view.left; 110 | 111 | if ([view isKindOfClass:[UIScrollView class]]) { 112 | UIScrollView* scrollView = (UIScrollView*)view; 113 | x -= scrollView.contentOffset.x; 114 | } 115 | } 116 | 117 | return x; 118 | } 119 | 120 | - (CGFloat)screenViewY { 121 | CGFloat y = 0; 122 | for (UIView* view = self; view; view = view.superview) { 123 | y += view.top; 124 | 125 | if ([view isKindOfClass:[UIScrollView class]]) { 126 | UIScrollView* scrollView = (UIScrollView*)view; 127 | y -= scrollView.contentOffset.y; 128 | } 129 | } 130 | return y; 131 | } 132 | 133 | - (CGRect)screenFrame { 134 | return CGRectMake(self.screenViewX, self.screenViewY, self.width, self.height); 135 | } 136 | 137 | - (CGPoint)origin { 138 | return self.frame.origin; 139 | } 140 | 141 | - (void)setOrigin:(CGPoint)origin { 142 | CGRect frame = self.frame; 143 | frame.origin = origin; 144 | self.frame = frame; 145 | } 146 | 147 | - (CGSize)size { 148 | return self.frame.size; 149 | } 150 | 151 | - (void)setSize:(CGSize)size { 152 | CGRect frame = self.frame; 153 | frame.size = size; 154 | self.frame = frame; 155 | } 156 | 157 | - (CGPoint)offsetFromView:(UIView*)otherView { 158 | CGFloat x = 0, y = 0; 159 | for (UIView* view = self; view && view != otherView; view = view.superview) { 160 | x += view.left; 161 | y += view.top; 162 | } 163 | return CGPointMake(x, y); 164 | } 165 | /* 166 | - (CGFloat)orientationWidth { 167 | return UIInterfaceOrientationIsLandscape(TTInterfaceOrientation()) 168 | ? self.height : self.width; 169 | } 170 | 171 | - (CGFloat)orientationHeight { 172 | return UIInterfaceOrientationIsLandscape(TTInterfaceOrientation()) 173 | ? self.width : self.height; 174 | } 175 | */ 176 | - (UIView*)descendantOrSelfWithClass:(Class)cls { 177 | if ([self isKindOfClass:cls]) 178 | return self; 179 | 180 | for (UIView* child in self.subviews) { 181 | UIView* it = [child descendantOrSelfWithClass:cls]; 182 | if (it) 183 | return it; 184 | } 185 | 186 | return nil; 187 | } 188 | 189 | - (UIView*)ancestorOrSelfWithClass:(Class)cls { 190 | if ([self isKindOfClass:cls]) { 191 | return self; 192 | } else if (self.superview) { 193 | return [self.superview ancestorOrSelfWithClass:cls]; 194 | } else { 195 | return nil; 196 | } 197 | } 198 | 199 | - (void)removeAllSubviews { 200 | while (self.subviews.count) { 201 | UIView* child = self.subviews.lastObject; 202 | [child removeFromSuperview]; 203 | } 204 | } 205 | 206 | 207 | 208 | - (UIViewController*)viewController { 209 | for (UIView* next = [self superview]; next; next = next.superview) { 210 | UIResponder* nextResponder = [next nextResponder]; 211 | if ([nextResponder isKindOfClass:[UIViewController class]]) { 212 | return (UIViewController*)nextResponder; 213 | } 214 | } 215 | return nil; 216 | } 217 | 218 | 219 | - (void)addSubviews:(NSArray *)views 220 | { 221 | for (UIView* v in views) { 222 | [self addSubview:v]; 223 | } 224 | } 225 | 226 | @end 227 | -------------------------------------------------------------------------------- /test/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 29 | 38 | 47 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 100 | 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 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /test/FirstViewController.m: -------------------------------------------------------------------------------- 1 | 2 | #import "AppDelegate.h" 3 | #import "FirstViewController.h" 4 | #import "Config.h" 5 | 6 | @interface FirstViewController () 7 | 8 | @property (nonatomic, strong) CLLocationManager* locationManager; 9 | @property (nonatomic, strong) UILabel* lbLocationAndTime; 10 | @property (nonatomic, strong) UILabel* lbAlreadyWalked; 11 | @property (nonatomic, assign) double currentDistance; 12 | @property (nonatomic, assign) double mileStoneDistance; 13 | @property (nonatomic, assign) double howLongWayForNotification; 14 | @property (nonatomic, strong) CLLocation* startLocation; 15 | @property (nonatomic, strong) UILocalNotification* localNotification; 16 | 17 | @property (weak, nonatomic) IBOutlet UIButton* btReCount; 18 | @property (weak, nonatomic) IBOutlet UIButton* btBigWayNotification; 19 | @property (weak, nonatomic) IBOutlet UIButton* btNormalWayNotification; 20 | @property (weak, nonatomic) IBOutlet UIButton* btShortWayNotification; 21 | 22 | @property (nonatomic, strong) NSMutableDictionary* wayNotificationButtons; 23 | 24 | @property (nonatomic, strong) UIFont* fontOfLabel; 25 | @property (nonatomic, strong) UIFont* tinyFontOfLabel; 26 | @property (nonatomic, strong) UIFont* hugeFontOfLabel; 27 | 28 | @property (nonatomic, strong) UILabel* coordinateLabel; 29 | @property (nonatomic, strong) UILabel* altitudeLabel; 30 | @property (nonatomic, strong) UILabel* courseLabel; 31 | @property (nonatomic, strong) UILabel* speedLabel; 32 | @property (nonatomic, strong) UILabel* timestampLabel; 33 | @property (nonatomic, strong) UILabel* floorLabel; 34 | 35 | @property (nonatomic, strong) UILabel* walkedLabel; 36 | @property (nonatomic, strong) UILabel* notificationLabel; 37 | @property (nonatomic, strong) UILabel* calorieLabel; 38 | 39 | @end 40 | 41 | @implementation FirstViewController 42 | 43 | - (void)viewDidLoad 44 | { 45 | [super viewDidLoad]; 46 | _localNotification = [[UILocalNotification alloc]init]; 47 | 48 | //开始启用后台更新地理位置 49 | if ([[[UIDevice currentDevice] systemVersion] doubleValue] > 8.0) 50 | { 51 | //设置定位权限 仅ios8有意义 52 | [self.locationManager requestWhenInUseAuthorization];// 前台定位 53 | [self.locationManager requestAlwaysAuthorization];// 前后台同时定位 54 | } 55 | [self.locationManager startUpdatingLocation]; 56 | // start 57 | [self buildLabel]; 58 | 59 | 60 | //按钮 61 | self.wayNotificationButtons[@1000] = self.btBigWayNotification; 62 | self.wayNotificationButtons[@100] = self.btNormalWayNotification; 63 | self.wayNotificationButtons[@10] = self.btShortWayNotification; 64 | [self checkSelectedWayButton]; 65 | } 66 | 67 | - (void)buildLabel { 68 | //布局显示的位置 69 | CGFloat labelMarginLeftAndRight = 30; 70 | CGFloat labelMarginGap = 10; 71 | 72 | self.coordinateLabel.top = labelMarginGap + 22; 73 | self.coordinateLabel.left = labelMarginLeftAndRight; 74 | self.coordinateLabel.width = self.view.width - labelMarginLeftAndRight * 2; 75 | self.coordinateLabel.height = self.coordinateLabel.font.lineHeight; 76 | 77 | self.altitudeLabel.top = self.coordinateLabel.bottom + labelMarginGap; 78 | self.altitudeLabel.left = labelMarginLeftAndRight; 79 | self.altitudeLabel.width = self.view.width - labelMarginLeftAndRight * 2; 80 | self.altitudeLabel.height = self.altitudeLabel.font.lineHeight; 81 | 82 | self.courseLabel.top = self.altitudeLabel.bottom + labelMarginGap; 83 | self.courseLabel.left = labelMarginLeftAndRight; 84 | self.courseLabel.width = self.view.width - labelMarginLeftAndRight * 2; 85 | self.courseLabel.height = self.courseLabel.font.lineHeight; 86 | 87 | self.speedLabel.top = self.courseLabel.bottom + labelMarginGap; 88 | self.speedLabel.left = labelMarginLeftAndRight; 89 | self.speedLabel.width = self.view.width - labelMarginLeftAndRight * 2; 90 | self.speedLabel.height = self.speedLabel.font.lineHeight; 91 | 92 | self.timestampLabel.top = self.speedLabel.bottom + labelMarginGap; 93 | self.timestampLabel.left = labelMarginLeftAndRight; 94 | self.timestampLabel.width = self.view.width - labelMarginLeftAndRight * 2; 95 | self.timestampLabel.height = self.timestampLabel.font.lineHeight; 96 | 97 | self.floorLabel.top = self.timestampLabel.bottom + labelMarginGap; 98 | self.floorLabel.left = labelMarginLeftAndRight; 99 | self.floorLabel.width = self.view.width - labelMarginLeftAndRight * 2; 100 | self.floorLabel.height = self.floorLabel.font.lineHeight; 101 | 102 | self.walkedLabel.top = self.floorLabel.bottom + labelMarginGap; 103 | self.walkedLabel.left = labelMarginLeftAndRight; 104 | self.walkedLabel.width = self.view.width - labelMarginLeftAndRight * 2; 105 | self.walkedLabel.height = self.walkedLabel.font.lineHeight; 106 | 107 | self.notificationLabel.top = self.walkedLabel.bottom + labelMarginGap; 108 | self.notificationLabel.left = labelMarginLeftAndRight; 109 | self.notificationLabel.width = self.view.width - labelMarginLeftAndRight * 2; 110 | self.notificationLabel.height = self.notificationLabel.font.lineHeight; 111 | 112 | self.calorieLabel.top = self.notificationLabel.bottom + labelMarginGap; 113 | self.calorieLabel.left = labelMarginLeftAndRight; 114 | self.calorieLabel.width = self.view.width - labelMarginLeftAndRight * 2; 115 | self.calorieLabel.height = self.calorieLabel.font.lineHeight; 116 | 117 | 118 | } 119 | 120 | - (void)viewWillLayoutSubviews { 121 | 122 | } 123 | 124 | - (void)checkSelectedWayButton { 125 | NSArray* allKeys = self.wayNotificationButtons.allKeys; 126 | for (NSNumber* akey in allKeys) { 127 | UIButton *aButton = self.wayNotificationButtons[akey]; 128 | if (self.howLongWayForNotification == akey.doubleValue) { 129 | aButton.selected = YES; 130 | } else { 131 | aButton.selected = NO; 132 | } 133 | } 134 | } 135 | 136 | - (IBAction)clickReCountButton:(id)sender { 137 | [self resetData]; 138 | } 139 | - (IBAction)clickBigWayButton:(id)sender { 140 | _howLongWayForNotification = 1000; 141 | [self checkSelectedWayButton]; 142 | } 143 | - (IBAction)clickNormalWayButton:(id)sender { 144 | _howLongWayForNotification = 100; 145 | [self checkSelectedWayButton]; 146 | } 147 | - (IBAction)clickShortWayButton:(id)sender { 148 | _howLongWayForNotification = 10; 149 | [self checkSelectedWayButton]; 150 | } 151 | 152 | - (void)resetData { 153 | _currentDistance = 0; 154 | _mileStoneDistance = 0; 155 | } 156 | 157 | #pragma mark - CLLocationManagerDelegate 158 | - (void)locationManager:(CLLocationManager *)manager 159 | didUpdateToLocation:(CLLocation *)newLocation 160 | fromLocation:(CLLocation *)oldLocation 161 | { 162 | if (!_startLocation) { 163 | self.startLocation = [[CLLocation alloc]init]; 164 | self.startLocation = newLocation; 165 | } 166 | 167 | if (UIApplication.sharedApplication.applicationState == UIApplicationStateActive) 168 | { 169 | 170 | } 171 | else 172 | { 173 | 174 | // NSLog(@"in background"); 175 | } 176 | _currentDistance += [newLocation distanceFromLocation:_startLocation]; 177 | if (_currentDistance > _mileStoneDistance + self.howLongWayForNotification) { 178 | _mileStoneDistance = _currentDistance; 179 | //执行本地通知 180 | _localNotification.alertBody = [NSString stringWithFormat:@"你已经移动了%f米",_currentDistance]; 181 | UIApplication *app = [UIApplication sharedApplication]; 182 | [app presentLocalNotificationNow:_localNotification]; 183 | } 184 | 185 | _startLocation = newLocation; 186 | [self updateWithLocationChange:newLocation withDistance:_currentDistance]; 187 | } 188 | 189 | /*! 190 | * @brief 显示后端的更新 191 | * 192 | */ 193 | - (void)updateWithLocationChange:(CLLocation *)location withDistance:(CLLocationDistance)meters { 194 | 195 | double latitude = location.coordinate.latitude; 196 | double longitude = location.coordinate.longitude; 197 | [self.coordinateLabel setText:[NSString stringWithFormat:@"当前坐标为 纬度%.2f 经度%.2f", latitude, longitude]]; 198 | 199 | double altitude = location.altitude; 200 | [self.altitudeLabel setText:[NSString stringWithFormat:@"海拔 %.1f", altitude]]; 201 | 202 | double course = location.course; 203 | [self.courseLabel setText:[NSString stringWithFormat:@"偏北角度 %.2f", course]]; 204 | 205 | double speed = location.speed; 206 | [self.speedLabel setText:[NSString stringWithFormat:@"速度每秒 %.1f米", speed]]; 207 | 208 | 209 | NSString *timestamp = [location.timestamp description]; 210 | [self.timestampLabel setText:[NSString stringWithFormat:@"时间 %@", timestamp]]; 211 | 212 | NSUInteger floor = location.floor.level; 213 | [self.floorLabel setText:[NSString stringWithFormat:@"所在楼层 %d", (int)floor]]; 214 | 215 | [self.walkedLabel setText:[NSString stringWithFormat:@"这次一共走了%.1f米", meters]]; 216 | [self.notificationLabel setText:[NSString stringWithFormat:@"每走%.0f米会发送通知提醒一次", _howLongWayForNotification]]; 217 | [self.calorieLabel setText:[NSString stringWithFormat:@"消耗卡路里%.1f",meters * 0.07625]]; 218 | } 219 | 220 | #pragma mark - getter && setter 221 | - (NSMutableDictionary *)wayNotificationButtons { 222 | if (!_wayNotificationButtons) { 223 | return self.wayNotificationButtons = [NSMutableDictionary dictionary]; 224 | } 225 | return _wayNotificationButtons; 226 | } 227 | - (double)howLongWayForNotification { 228 | if (!_howLongWayForNotification) { 229 | self.howLongWayForNotification = 1000; 230 | } 231 | return _howLongWayForNotification; 232 | } 233 | - (double)currentDistance { 234 | if (!_currentDistance) { 235 | self.currentDistance = 0; 236 | } 237 | return _currentDistance; 238 | } 239 | - (double)mileStoneDistance { 240 | if (!_mileStoneDistance) { 241 | self.mileStoneDistance = 0; 242 | } 243 | return _mileStoneDistance; 244 | } 245 | - (UILabel *)lbLocationAndTime { 246 | if (!_lbLocationAndTime) { 247 | self.lbLocationAndTime = [[UILabel alloc] initWithFrame:CGRectZero]; 248 | } 249 | return _lbLocationAndTime; 250 | } 251 | - (CLLocationManager *)locationManager { 252 | if (!_locationManager) { 253 | self.locationManager = [[CLLocationManager alloc] init]; 254 | self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; 255 | self.locationManager.delegate = self; 256 | } 257 | return _locationManager; 258 | } 259 | //显示信息 260 | - (UIFont *)fontOfLabel { 261 | if (!_fontOfLabel) { 262 | self.fontOfLabel = [UIFont systemFontOfSize:15]; 263 | } 264 | return _fontOfLabel; 265 | } 266 | - (UIFont *)tinyFontOfLabel { 267 | if (!_tinyFontOfLabel) { 268 | self.tinyFontOfLabel = [UIFont systemFontOfSize:12]; 269 | } 270 | return _tinyFontOfLabel; 271 | } 272 | - (UIFont *)hugeFontOfLabel { 273 | if (!_hugeFontOfLabel) { 274 | self.hugeFontOfLabel = [UIFont systemFontOfSize:22]; 275 | } 276 | return _hugeFontOfLabel; 277 | } 278 | - (UILabel *)coordinateLabel { 279 | if (!_coordinateLabel) { 280 | self.coordinateLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 281 | [self.coordinateLabel setFont:self.fontOfLabel]; 282 | [self.coordinateLabel setTextColor:[UIColor grayColor]]; 283 | [self.view addSubview:self.coordinateLabel]; 284 | } 285 | return _coordinateLabel; 286 | } 287 | - (UILabel *)altitudeLabel { 288 | if (!_altitudeLabel) { 289 | self.altitudeLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 290 | [self.altitudeLabel setFont:self.tinyFontOfLabel]; 291 | [self.altitudeLabel setTextColor:[UIColor greenColor]]; 292 | [self.view addSubview:self.altitudeLabel]; 293 | } 294 | return _altitudeLabel; 295 | } 296 | - (UILabel *)courseLabel { 297 | if (!_courseLabel) { 298 | self.courseLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 299 | [self.courseLabel setFont:self.fontOfLabel]; 300 | [self.courseLabel setTextColor:[UIColor yellowColor]]; 301 | [self.view addSubview:self.courseLabel]; 302 | } 303 | return _courseLabel; 304 | } 305 | - (UILabel *)speedLabel { 306 | if (!_speedLabel) { 307 | self.speedLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 308 | [self.speedLabel setFont:self.hugeFontOfLabel]; 309 | [self.speedLabel setTextColor:[UIColor redColor]]; 310 | [self.view addSubview:self.speedLabel]; 311 | } 312 | return _speedLabel; 313 | } 314 | - (UILabel *)timestampLabel { 315 | if (!_timestampLabel) { 316 | self.timestampLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 317 | [self.timestampLabel setFont:self.tinyFontOfLabel]; 318 | [self.timestampLabel setTextColor:[UIColor blueColor]]; 319 | [self.view addSubview:self.timestampLabel]; 320 | } 321 | return _timestampLabel; 322 | } 323 | - (UILabel *)floorLabel { 324 | if (!_floorLabel) { 325 | self.floorLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 326 | [self.floorLabel setFont:self.tinyFontOfLabel]; 327 | [self.floorLabel setTextColor:[UIColor purpleColor]]; 328 | [self.view addSubview:self.floorLabel]; 329 | } 330 | return _floorLabel; 331 | } 332 | - (UILabel *)walkedLabel { 333 | if (!_walkedLabel) { 334 | self.walkedLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 335 | [self.walkedLabel setFont:self.hugeFontOfLabel]; 336 | [self.walkedLabel setTextColor:[UIColor redColor]]; 337 | [self.view addSubview:self.walkedLabel]; 338 | } 339 | return _walkedLabel; 340 | } 341 | - (UILabel *)notificationLabel { 342 | if (!_notificationLabel) { 343 | self.notificationLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 344 | [self.notificationLabel setFont:self.fontOfLabel]; 345 | [self.notificationLabel setTextColor:[UIColor blueColor]]; 346 | [self.view addSubview:self.notificationLabel]; 347 | } 348 | return _notificationLabel; 349 | } 350 | - (UILabel *)calorieLabel { 351 | if (!_calorieLabel) { 352 | self.calorieLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 353 | [self.calorieLabel setFont:self.hugeFontOfLabel]; 354 | [self.calorieLabel setTextColor:[UIColor redColor]]; 355 | [self.view addSubview:self.calorieLabel]; 356 | } 357 | return _calorieLabel; 358 | } 359 | 360 | @end 361 | -------------------------------------------------------------------------------- /test/UIColor-Expanded.m: -------------------------------------------------------------------------------- 1 | #import "UIColor-Expanded.h" 2 | 3 | /* 4 | FOR REFERENCE: Color Space Models: enum CGColorSpaceModel { 5 | kCGColorSpaceModelUnknown = -1, 6 | kCGColorSpaceModelMonochrome, 7 | kCGColorSpaceModelRGB, 8 | kCGColorSpaceModelCMYK, 9 | kCGColorSpaceModelLab, 10 | kCGColorSpaceModelDeviceN, 11 | kCGColorSpaceModelIndexed, 12 | kCGColorSpaceModelPattern 13 | }; 14 | */ 15 | 16 | // Static cache of looked up color names. Used with +colorWithName: 17 | static NSMutableDictionary *colorNameCache = nil; 18 | 19 | #if SUPPORTS_UNDOCUMENTED_API 20 | // UIColor_Undocumented 21 | // Undocumented methods of UIColor 22 | @interface UIColor (UIColor_Undocumented) 23 | - (NSString *)styleString; 24 | @end 25 | #endif // SUPPORTS_UNDOCUMENTED_API 26 | 27 | @interface UIColor (UIColor_Expanded_Support) 28 | + (UIColor *)searchForColorByName:(NSString *)cssColorName; 29 | @end 30 | 31 | #pragma mark - 32 | 33 | @implementation UIColor (UIColor_Expanded) 34 | 35 | - (CGColorSpaceModel)colorSpaceModel { 36 | return CGColorSpaceGetModel(CGColorGetColorSpace(self.CGColor)); 37 | } 38 | 39 | - (NSString *)colorSpaceString { 40 | switch (self.colorSpaceModel) { 41 | case kCGColorSpaceModelUnknown: 42 | return @"kCGColorSpaceModelUnknown"; 43 | case kCGColorSpaceModelMonochrome: 44 | return @"kCGColorSpaceModelMonochrome"; 45 | case kCGColorSpaceModelRGB: 46 | return @"kCGColorSpaceModelRGB"; 47 | case kCGColorSpaceModelCMYK: 48 | return @"kCGColorSpaceModelCMYK"; 49 | case kCGColorSpaceModelLab: 50 | return @"kCGColorSpaceModelLab"; 51 | case kCGColorSpaceModelDeviceN: 52 | return @"kCGColorSpaceModelDeviceN"; 53 | case kCGColorSpaceModelIndexed: 54 | return @"kCGColorSpaceModelIndexed"; 55 | case kCGColorSpaceModelPattern: 56 | return @"kCGColorSpaceModelPattern"; 57 | default: 58 | return @"Not a valid color space"; 59 | } 60 | } 61 | 62 | - (BOOL)canProvideRGBComponents { 63 | switch (self.colorSpaceModel) { 64 | case kCGColorSpaceModelRGB: 65 | case kCGColorSpaceModelMonochrome: 66 | return YES; 67 | default: 68 | return NO; 69 | } 70 | } 71 | 72 | - (NSArray *)arrayFromRGBAComponents { 73 | NSAssert(self.canProvideRGBComponents, @"Must be an RGB color to use -arrayFromRGBAComponents"); 74 | 75 | CGFloat r,g,b,a; 76 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 77 | 78 | return [NSArray arrayWithObjects: 79 | [NSNumber numberWithFloat:r], 80 | [NSNumber numberWithFloat:g], 81 | [NSNumber numberWithFloat:b], 82 | [NSNumber numberWithFloat:a], 83 | nil]; 84 | } 85 | 86 | - (BOOL)red:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha { 87 | const CGFloat *components = CGColorGetComponents(self.CGColor); 88 | 89 | CGFloat r,g,b,a; 90 | 91 | switch (self.colorSpaceModel) { 92 | case kCGColorSpaceModelMonochrome: 93 | r = g = b = components[0]; 94 | a = components[1]; 95 | break; 96 | case kCGColorSpaceModelRGB: 97 | r = components[0]; 98 | g = components[1]; 99 | b = components[2]; 100 | a = components[3]; 101 | break; 102 | default: // We don't know how to handle this model 103 | return NO; 104 | } 105 | 106 | if (red) *red = r; 107 | if (green) *green = g; 108 | if (blue) *blue = b; 109 | if (alpha) *alpha = a; 110 | 111 | return YES; 112 | } 113 | 114 | - (CGFloat)red { 115 | NSAssert(self.canProvideRGBComponents, @"Must be an RGB color to use -red"); 116 | const CGFloat *c = CGColorGetComponents(self.CGColor); 117 | return c[0]; 118 | } 119 | 120 | - (CGFloat)green { 121 | NSAssert(self.canProvideRGBComponents, @"Must be an RGB color to use -green"); 122 | const CGFloat *c = CGColorGetComponents(self.CGColor); 123 | if (self.colorSpaceModel == kCGColorSpaceModelMonochrome) return c[0]; 124 | return c[1]; 125 | } 126 | 127 | - (CGFloat)blue { 128 | NSAssert(self.canProvideRGBComponents, @"Must be an RGB color to use -blue"); 129 | const CGFloat *c = CGColorGetComponents(self.CGColor); 130 | if (self.colorSpaceModel == kCGColorSpaceModelMonochrome) return c[0]; 131 | return c[2]; 132 | } 133 | 134 | - (CGFloat)white { 135 | NSAssert(self.colorSpaceModel == kCGColorSpaceModelMonochrome, @"Must be a Monochrome color to use -white"); 136 | const CGFloat *c = CGColorGetComponents(self.CGColor); 137 | return c[0]; 138 | } 139 | 140 | - (CGFloat)alpha { 141 | return CGColorGetAlpha(self.CGColor); 142 | } 143 | 144 | - (UInt32)rgbHex { 145 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use rgbHex"); 146 | 147 | CGFloat r,g,b,a; 148 | if (![self red:&r green:&g blue:&b alpha:&a]) return 0; 149 | 150 | r = MIN(MAX(self.red, 0.0f), 1.0f); 151 | g = MIN(MAX(self.green, 0.0f), 1.0f); 152 | b = MIN(MAX(self.blue, 0.0f), 1.0f); 153 | 154 | return (((int)roundf(r * 255)) << 16) 155 | | (((int)roundf(g * 255)) << 8) 156 | | (((int)roundf(b * 255))); 157 | } 158 | 159 | #pragma mark Arithmetic operations 160 | 161 | - (UIColor *)colorByLuminanceMapping { 162 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 163 | 164 | CGFloat r,g,b,a; 165 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 166 | 167 | // http://en.wikipedia.org/wiki/Luma_(video) 168 | // Y = 0.2126 R + 0.7152 G + 0.0722 B 169 | return [UIColor colorWithWhite:r*0.2126f + g*0.7152f + b*0.0722f 170 | alpha:a]; 171 | 172 | } 173 | 174 | - (UIColor *)colorByMultiplyingByRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { 175 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 176 | 177 | CGFloat r,g,b,a; 178 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 179 | 180 | return [UIColor colorWithRed:MAX(0.0, MIN(1.0, r * red)) 181 | green:MAX(0.0, MIN(1.0, g * green)) 182 | blue:MAX(0.0, MIN(1.0, b * blue)) 183 | alpha:MAX(0.0, MIN(1.0, a * alpha))]; 184 | } 185 | 186 | - (UIColor *)colorByAddingRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { 187 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 188 | 189 | CGFloat r,g,b,a; 190 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 191 | 192 | return [UIColor colorWithRed:MAX(0.0, MIN(1.0, r + red)) 193 | green:MAX(0.0, MIN(1.0, g + green)) 194 | blue:MAX(0.0, MIN(1.0, b + blue)) 195 | alpha:MAX(0.0, MIN(1.0, a + alpha))]; 196 | } 197 | 198 | - (UIColor *)colorByLighteningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { 199 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 200 | 201 | CGFloat r,g,b,a; 202 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 203 | 204 | return [UIColor colorWithRed:MAX(r, red) 205 | green:MAX(g, green) 206 | blue:MAX(b, blue) 207 | alpha:MAX(a, alpha)]; 208 | } 209 | 210 | - (UIColor *)colorByDarkeningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { 211 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 212 | 213 | CGFloat r,g,b,a; 214 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 215 | 216 | return [UIColor colorWithRed:MIN(r, red) 217 | green:MIN(g, green) 218 | blue:MIN(b, blue) 219 | alpha:MIN(a, alpha)]; 220 | } 221 | 222 | - (UIColor *)colorByMultiplyingBy:(CGFloat)f { 223 | return [self colorByMultiplyingByRed:f green:f blue:f alpha:1.0f]; 224 | } 225 | 226 | - (UIColor *)colorByAdding:(CGFloat)f { 227 | return [self colorByMultiplyingByRed:f green:f blue:f alpha:0.0f]; 228 | } 229 | 230 | - (UIColor *)colorByLighteningTo:(CGFloat)f { 231 | return [self colorByLighteningToRed:f green:f blue:f alpha:0.0f]; 232 | } 233 | 234 | - (UIColor *)colorByDarkeningTo:(CGFloat)f { 235 | return [self colorByDarkeningToRed:f green:f blue:f alpha:1.0f]; 236 | } 237 | 238 | - (UIColor *)colorByMultiplyingByColor:(UIColor *)color { 239 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 240 | 241 | CGFloat r,g,b,a; 242 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 243 | 244 | return [self colorByMultiplyingByRed:r green:g blue:b alpha:1.0f]; 245 | } 246 | 247 | - (UIColor *)colorByAddingColor:(UIColor *)color { 248 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 249 | 250 | CGFloat r,g,b,a; 251 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 252 | 253 | return [self colorByAddingRed:r green:g blue:b alpha:0.0f]; 254 | } 255 | 256 | - (UIColor *)colorByLighteningToColor:(UIColor *)color { 257 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 258 | 259 | CGFloat r,g,b,a; 260 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 261 | 262 | return [self colorByLighteningToRed:r green:g blue:b alpha:0.0f]; 263 | } 264 | 265 | - (UIColor *)colorByDarkeningToColor:(UIColor *)color { 266 | NSAssert(self.canProvideRGBComponents, @"Must be a RGB color to use arithmatic operations"); 267 | 268 | CGFloat r,g,b,a; 269 | if (![self red:&r green:&g blue:&b alpha:&a]) return nil; 270 | 271 | return [self colorByDarkeningToRed:r green:g blue:b alpha:1.0f]; 272 | } 273 | 274 | #pragma mark String utilities 275 | 276 | - (NSString *)stringFromColor { 277 | NSAssert(self.canProvideRGBComponents, @"Must be an RGB color to use -stringFromColor"); 278 | NSString *result; 279 | switch (self.colorSpaceModel) { 280 | case kCGColorSpaceModelRGB: 281 | result = [NSString stringWithFormat:@"{%0.3f, %0.3f, %0.3f, %0.3f}", self.red, self.green, self.blue, self.alpha]; 282 | break; 283 | case kCGColorSpaceModelMonochrome: 284 | result = [NSString stringWithFormat:@"{%0.3f, %0.3f}", self.white, self.alpha]; 285 | break; 286 | default: 287 | result = nil; 288 | } 289 | return result; 290 | } 291 | 292 | - (NSString *)hexStringFromColor { 293 | return [NSString stringWithFormat:@"%0.6X", (unsigned int)self.rgbHex]; 294 | } 295 | 296 | + (UIColor *)colorWithString:(NSString *)stringToConvert { 297 | NSScanner *scanner = [NSScanner scannerWithString:stringToConvert]; 298 | if (![scanner scanString:@"{" intoString:NULL]) return nil; 299 | const NSUInteger kMaxComponents = 4; 300 | float c[kMaxComponents]; 301 | NSUInteger i = 0; 302 | if (![scanner scanFloat:&c[i++]]) return nil; 303 | while (1) { 304 | if ([scanner scanString:@"}" intoString:NULL]) break; 305 | if (i >= kMaxComponents) return nil; 306 | if ([scanner scanString:@"," intoString:NULL]) { 307 | if (![scanner scanFloat:&c[i++]]) return nil; 308 | } else { 309 | // either we're at the end of there's an unexpected character here 310 | // both cases are error conditions 311 | return nil; 312 | } 313 | } 314 | if (![scanner isAtEnd]) return nil; 315 | UIColor *color; 316 | switch (i) { 317 | case 2: // monochrome 318 | color = [UIColor colorWithWhite:c[0] alpha:c[1]]; 319 | break; 320 | case 4: // RGB 321 | color = [UIColor colorWithRed:c[0] green:c[1] blue:c[2] alpha:c[3]]; 322 | break; 323 | default: 324 | color = nil; 325 | } 326 | return color; 327 | } 328 | 329 | #pragma mark Class methods 330 | 331 | + (UIColor *)randomColor { 332 | return [UIColor colorWithRed:(CGFloat)RAND_MAX / random() 333 | green:(CGFloat)RAND_MAX / random() 334 | blue:(CGFloat)RAND_MAX / random() 335 | alpha:1.0f]; 336 | } 337 | 338 | + (UIColor *)colorWithRGBHex:(UInt32)hex { 339 | int r = (hex >> 16) & 0xFF; 340 | int g = (hex >> 8) & 0xFF; 341 | int b = (hex) & 0xFF; 342 | 343 | return [UIColor colorWithRed:r / 255.0f 344 | green:g / 255.0f 345 | blue:b / 255.0f 346 | alpha:1.0f]; 347 | } 348 | 349 | // Returns a UIColor by scanning the string for a hex number and passing that to +[UIColor colorWithRGBHex:] 350 | // Skips any leading whitespace and ignores any trailing characters 351 | + (UIColor *)colorWithHexString:(NSString *)stringToConvert { 352 | NSScanner *scanner = [NSScanner scannerWithString:stringToConvert]; 353 | unsigned hexNum; 354 | if (![scanner scanHexInt:&hexNum]) return nil; 355 | return [UIColor colorWithRGBHex:hexNum]; 356 | } 357 | 358 | 359 | + (UIColor *) colorWithHex:(uint) hex 360 | { 361 | int red, green, blue, alpha; 362 | 363 | blue = hex & 0x000000FF; 364 | green = ((hex & 0x0000FF00) >> 8); 365 | red = ((hex & 0x00FF0000) >> 16); 366 | alpha = ((hex & 0xFF000000) >> 24); 367 | 368 | return [UIColor colorWithRed:red/255.0f 369 | green:green/255.0f 370 | blue:blue/255.0f 371 | alpha:alpha/255.f]; 372 | } 373 | 374 | // Lookup a color using css 3/svg color name 375 | + (UIColor *)colorWithName:(NSString *)cssColorName { 376 | UIColor *color; 377 | @synchronized(colorNameCache) { 378 | // Look for the color in the cache 379 | color = [colorNameCache objectForKey:cssColorName]; 380 | 381 | if ((id)color == [NSNull null]) { 382 | // If it wasn't there previously, it's still not there now 383 | color = nil; 384 | } else if (!color) { 385 | // Color not in cache, so search for it now 386 | color = [self searchForColorByName:cssColorName]; 387 | 388 | // Set the value in cache, storing NSNull on failure 389 | [colorNameCache setObject:(color ?: (id)[NSNull null]) 390 | forKey:cssColorName]; 391 | } 392 | } 393 | 394 | return color; 395 | } 396 | 397 | #pragma mark UIColor_Expanded initialization 398 | 399 | + (void)load { 400 | colorNameCache = [[NSMutableDictionary alloc] init]; 401 | } 402 | 403 | @end 404 | 405 | #pragma mark - 406 | 407 | #if SUPPORTS_UNDOCUMENTED_API 408 | @implementation UIColor (UIColor_Undocumented_Expanded) 409 | - (NSString *)fetchStyleString { 410 | return [self styleString]; 411 | } 412 | 413 | // Convert a color into RGB Color space, courtesy of Poltras 414 | // via http://ofcodeandmen.poltras.com/2009/01/22/convert-a-cgcolorref-to-another-cgcolorspaceref/ 415 | // 416 | - (UIColor *)rgbColor { 417 | // Call to undocumented method "styleString". 418 | NSString *style = [self styleString]; 419 | NSScanner *scanner = [NSScanner scannerWithString:style]; 420 | CGFloat red, green, blue; 421 | if (![scanner scanString:@"rgb(" intoString:NULL]) return nil; 422 | if (![scanner scanFloat:&red]) return nil; 423 | if (![scanner scanString:@"," intoString:NULL]) return nil; 424 | if (![scanner scanFloat:&green]) return nil; 425 | if (![scanner scanString:@"," intoString:NULL]) return nil; 426 | if (![scanner scanFloat:&blue]) return nil; 427 | if (![scanner scanString:@")" intoString:NULL]) return nil; 428 | if (![scanner isAtEnd]) return nil; 429 | 430 | return [UIColor colorWithRed:red green:green blue:blue alpha:self.alpha]; 431 | } 432 | @end 433 | #endif // SUPPORTS_UNDOCUMENTED_API 434 | 435 | @implementation UIColor (UIColor_Expanded_Support) 436 | /* 437 | * Database of color names and hex rgb values, derived 438 | * from the css 3 color spec: 439 | * http://www.w3.org/TR/css3-color/ 440 | * 441 | * We think this is a very compact way of storing 442 | * this information, and relatively cheap to lookup. 443 | * 444 | * Note that we search for color names starting with ',' 445 | * and terminated by '#', so that we don't get false matches. 446 | * For this reason, the database begins with ','. 447 | */ 448 | static const char *colorNameDB = "," 449 | "aliceblue#f0f8ff,antiquewhite#faebd7,aqua#00ffff,aquamarine#7fffd4,azure#f0ffff," 450 | "beige#f5f5dc,bisque#ffe4c4,black#000000,blanchedalmond#ffebcd,blue#0000ff," 451 | "blueviolet#8a2be2,brown#a52a2a,burlywood#deb887,cadetblue#5f9ea0,chartreuse#7fff00," 452 | "chocolate#d2691e,coral#ff7f50,cornflowerblue#6495ed,cornsilk#fff8dc,crimson#dc143c," 453 | "cyan#00ffff,darkblue#00008b,darkcyan#008b8b,darkgoldenrod#b8860b,darkgray#a9a9a9," 454 | "darkgreen#006400,darkgrey#a9a9a9,darkkhaki#bdb76b,darkmagenta#8b008b," 455 | "darkolivegreen#556b2f,darkorange#ff8c00,darkorchid#9932cc,darkred#8b0000," 456 | "darksalmon#e9967a,darkseagreen#8fbc8f,darkslateblue#483d8b,darkslategray#2f4f4f," 457 | "darkslategrey#2f4f4f,darkturquoise#00ced1,darkviolet#9400d3,deeppink#ff1493," 458 | "deepskyblue#00bfff,dimgray#696969,dimgrey#696969,dodgerblue#1e90ff," 459 | "firebrick#b22222,floralwhite#fffaf0,forestgreen#228b22,fuchsia#ff00ff," 460 | "gainsboro#dcdcdc,ghostwhite#f8f8ff,gold#ffd700,goldenrod#daa520,gray#808080," 461 | "green#008000,greenyellow#adff2f,grey#808080,honeydew#f0fff0,hotpink#ff69b4," 462 | "indianred#cd5c5c,indigo#4b0082,ivory#fffff0,khaki#f0e68c,lavender#e6e6fa," 463 | "lavenderblush#fff0f5,lawngreen#7cfc00,lemonchiffon#fffacd,lightblue#add8e6," 464 | "lightcoral#f08080,lightcyan#e0ffff,lightgoldenrodyellow#fafad2,lightgray#d3d3d3," 465 | "lightgreen#90ee90,lightgrey#d3d3d3,lightpink#ffb6c1,lightsalmon#ffa07a," 466 | "lightseagreen#20b2aa,lightskyblue#87cefa,lightslategray#778899," 467 | "lightslategrey#778899,lightsteelblue#b0c4de,lightyellow#ffffe0,lime#00ff00," 468 | "limegreen#32cd32,linen#faf0e6,magenta#ff00ff,maroon#800000,mediumaquamarine#66cdaa," 469 | "mediumblue#0000cd,mediumorchid#ba55d3,mediumpurple#9370db,mediumseagreen#3cb371," 470 | "mediumslateblue#7b68ee,mediumspringgreen#00fa9a,mediumturquoise#48d1cc," 471 | "mediumvioletred#c71585,midnightblue#191970,mintcream#f5fffa,mistyrose#ffe4e1," 472 | "moccasin#ffe4b5,navajowhite#ffdead,navy#000080,oldlace#fdf5e6,olive#808000," 473 | "olivedrab#6b8e23,orange#ffa500,orangered#ff4500,orchid#da70d6,palegoldenrod#eee8aa," 474 | "palegreen#98fb98,paleturquoise#afeeee,palevioletred#db7093,papayawhip#ffefd5," 475 | "peachpuff#ffdab9,peru#cd853f,pink#ffc0cb,plum#dda0dd,powderblue#b0e0e6," 476 | "purple#800080,red#ff0000,rosybrown#bc8f8f,royalblue#4169e1,saddlebrown#8b4513," 477 | "salmon#fa8072,sandybrown#f4a460,seagreen#2e8b57,seashell#fff5ee,sienna#a0522d," 478 | "silver#c0c0c0,skyblue#87ceeb,slateblue#6a5acd,slategray#708090,slategrey#708090," 479 | "snow#fffafa,springgreen#00ff7f,steelblue#4682b4,tan#d2b48c,teal#008080," 480 | "thistle#d8bfd8,tomato#ff6347,turquoise#40e0d0,violet#ee82ee,wheat#f5deb3," 481 | "white#ffffff,whitesmoke#f5f5f5,yellow#ffff00,yellowgreen#9acd32"; 482 | 483 | + (UIColor *)searchForColorByName:(NSString *)cssColorName { 484 | UIColor *result = nil; 485 | 486 | // Compile the string we'll use to search against the database 487 | // We search for ",#" to avoid false matches 488 | const char *searchString = [[NSString stringWithFormat:@",%@#", cssColorName] UTF8String]; 489 | 490 | // Search for the color name 491 | const char *found = strstr(colorNameDB, searchString); 492 | 493 | // If found, step past the search string and grab the hex representation 494 | if (found) { 495 | const char *after = found + strlen(searchString); 496 | int hex; 497 | if (sscanf(after, "%x", &hex) == 1) { 498 | result = [self colorWithRGBHex:hex]; 499 | } 500 | } 501 | 502 | return result; 503 | } 504 | @end 505 | -------------------------------------------------------------------------------- /test.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3AB0AA871B392CA900128BA6 /* UIColor-Expanded.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AB0AA861B392CA900128BA6 /* UIColor-Expanded.m */; }; 11 | 3AE6B1BD1B32F0B7000CBE6C /* UIViewAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AE6B1BC1B32F0B7000CBE6C /* UIViewAdditions.m */; }; 12 | 3AE6B1C11B33B1EF000CBE6C /* UILabel+ContentSize.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AE6B1C01B33B1EF000CBE6C /* UILabel+ContentSize.m */; }; 13 | 3AF87E331B2FC28800CE1EBB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AF87E321B2FC28800CE1EBB /* main.m */; }; 14 | 3AF87E361B2FC28800CE1EBB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AF87E351B2FC28800CE1EBB /* AppDelegate.m */; }; 15 | 3AF87E391B2FC28800CE1EBB /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AF87E381B2FC28800CE1EBB /* FirstViewController.m */; }; 16 | 3AF87E3C1B2FC28800CE1EBB /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AF87E3B1B2FC28800CE1EBB /* SecondViewController.m */; }; 17 | 3AF87E3F1B2FC28800CE1EBB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3AF87E3D1B2FC28800CE1EBB /* Main.storyboard */; }; 18 | 3AF87E411B2FC28800CE1EBB /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3AF87E401B2FC28800CE1EBB /* Images.xcassets */; }; 19 | 3AF87E441B2FC28800CE1EBB /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3AF87E421B2FC28800CE1EBB /* LaunchScreen.xib */; }; 20 | 3AF87E501B2FC28800CE1EBB /* testTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AF87E4F1B2FC28800CE1EBB /* testTests.m */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXContainerItemProxy section */ 24 | 3AF87E4A1B2FC28800CE1EBB /* PBXContainerItemProxy */ = { 25 | isa = PBXContainerItemProxy; 26 | containerPortal = 3AF87E251B2FC28800CE1EBB /* Project object */; 27 | proxyType = 1; 28 | remoteGlobalIDString = 3AF87E2C1B2FC28800CE1EBB; 29 | remoteInfo = test; 30 | }; 31 | /* End PBXContainerItemProxy section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 3AB0AA851B392CA900128BA6 /* UIColor-Expanded.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor-Expanded.h"; sourceTree = ""; }; 35 | 3AB0AA861B392CA900128BA6 /* UIColor-Expanded.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor-Expanded.m"; sourceTree = ""; }; 36 | 3AE6B1BB1B32F0B7000CBE6C /* UIViewAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIViewAdditions.h; sourceTree = ""; }; 37 | 3AE6B1BC1B32F0B7000CBE6C /* UIViewAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIViewAdditions.m; sourceTree = ""; }; 38 | 3AE6B1BF1B33B1EF000CBE6C /* UILabel+ContentSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UILabel+ContentSize.h"; sourceTree = ""; }; 39 | 3AE6B1C01B33B1EF000CBE6C /* UILabel+ContentSize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UILabel+ContentSize.m"; sourceTree = ""; }; 40 | 3AE6B1C21B33BC23000CBE6C /* Config.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; 41 | 3AF87E2D1B2FC28800CE1EBB /* test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = test.app; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | 3AF87E311B2FC28800CE1EBB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43 | 3AF87E321B2FC28800CE1EBB /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 44 | 3AF87E341B2FC28800CE1EBB /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 45 | 3AF87E351B2FC28800CE1EBB /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 46 | 3AF87E371B2FC28800CE1EBB /* FirstViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; }; 47 | 3AF87E381B2FC28800CE1EBB /* FirstViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; }; 48 | 3AF87E3A1B2FC28800CE1EBB /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; }; 49 | 3AF87E3B1B2FC28800CE1EBB /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; 50 | 3AF87E3E1B2FC28800CE1EBB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | 3AF87E401B2FC28800CE1EBB /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 52 | 3AF87E431B2FC28800CE1EBB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 53 | 3AF87E491B2FC28800CE1EBB /* testTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = testTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 3AF87E4E1B2FC28800CE1EBB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | 3AF87E4F1B2FC28800CE1EBB /* testTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = testTests.m; sourceTree = ""; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | 3AF87E2A1B2FC28800CE1EBB /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | 3AF87E461B2FC28800CE1EBB /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | /* End PBXFrameworksBuildPhase section */ 74 | 75 | /* Begin PBXGroup section */ 76 | 3AB0AA4E1B38D4AE00128BA6 /* base */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 3AB0AA851B392CA900128BA6 /* UIColor-Expanded.h */, 80 | 3AB0AA861B392CA900128BA6 /* UIColor-Expanded.m */, 81 | 3AE6B1BB1B32F0B7000CBE6C /* UIViewAdditions.h */, 82 | 3AE6B1BC1B32F0B7000CBE6C /* UIViewAdditions.m */, 83 | 3AE6B1BF1B33B1EF000CBE6C /* UILabel+ContentSize.h */, 84 | 3AE6B1C01B33B1EF000CBE6C /* UILabel+ContentSize.m */, 85 | ); 86 | name = base; 87 | sourceTree = ""; 88 | }; 89 | 3AF87E241B2FC28700CE1EBB = { 90 | isa = PBXGroup; 91 | children = ( 92 | 3AF87E2F1B2FC28800CE1EBB /* test */, 93 | 3AF87E4C1B2FC28800CE1EBB /* testTests */, 94 | 3AF87E2E1B2FC28800CE1EBB /* Products */, 95 | ); 96 | sourceTree = ""; 97 | }; 98 | 3AF87E2E1B2FC28800CE1EBB /* Products */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 3AF87E2D1B2FC28800CE1EBB /* test.app */, 102 | 3AF87E491B2FC28800CE1EBB /* testTests.xctest */, 103 | ); 104 | name = Products; 105 | sourceTree = ""; 106 | }; 107 | 3AF87E2F1B2FC28800CE1EBB /* test */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 3AF87E341B2FC28800CE1EBB /* AppDelegate.h */, 111 | 3AF87E351B2FC28800CE1EBB /* AppDelegate.m */, 112 | 3AF87E371B2FC28800CE1EBB /* FirstViewController.h */, 113 | 3AF87E381B2FC28800CE1EBB /* FirstViewController.m */, 114 | 3AF87E3A1B2FC28800CE1EBB /* SecondViewController.h */, 115 | 3AF87E3B1B2FC28800CE1EBB /* SecondViewController.m */, 116 | 3AE6B1C21B33BC23000CBE6C /* Config.h */, 117 | 3AB0AA4E1B38D4AE00128BA6 /* base */, 118 | 3AF87E3D1B2FC28800CE1EBB /* Main.storyboard */, 119 | 3AF87E401B2FC28800CE1EBB /* Images.xcassets */, 120 | 3AF87E421B2FC28800CE1EBB /* LaunchScreen.xib */, 121 | 3AF87E301B2FC28800CE1EBB /* Supporting Files */, 122 | ); 123 | path = test; 124 | sourceTree = ""; 125 | }; 126 | 3AF87E301B2FC28800CE1EBB /* Supporting Files */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 3AF87E311B2FC28800CE1EBB /* Info.plist */, 130 | 3AF87E321B2FC28800CE1EBB /* main.m */, 131 | ); 132 | name = "Supporting Files"; 133 | sourceTree = ""; 134 | }; 135 | 3AF87E4C1B2FC28800CE1EBB /* testTests */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 3AF87E4F1B2FC28800CE1EBB /* testTests.m */, 139 | 3AF87E4D1B2FC28800CE1EBB /* Supporting Files */, 140 | ); 141 | path = testTests; 142 | sourceTree = ""; 143 | }; 144 | 3AF87E4D1B2FC28800CE1EBB /* Supporting Files */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 3AF87E4E1B2FC28800CE1EBB /* Info.plist */, 148 | ); 149 | name = "Supporting Files"; 150 | sourceTree = ""; 151 | }; 152 | /* End PBXGroup section */ 153 | 154 | /* Begin PBXNativeTarget section */ 155 | 3AF87E2C1B2FC28800CE1EBB /* test */ = { 156 | isa = PBXNativeTarget; 157 | buildConfigurationList = 3AF87E531B2FC28800CE1EBB /* Build configuration list for PBXNativeTarget "test" */; 158 | buildPhases = ( 159 | 3AF87E291B2FC28800CE1EBB /* Sources */, 160 | 3AF87E2A1B2FC28800CE1EBB /* Frameworks */, 161 | 3AF87E2B1B2FC28800CE1EBB /* Resources */, 162 | ); 163 | buildRules = ( 164 | ); 165 | dependencies = ( 166 | ); 167 | name = test; 168 | productName = test; 169 | productReference = 3AF87E2D1B2FC28800CE1EBB /* test.app */; 170 | productType = "com.apple.product-type.application"; 171 | }; 172 | 3AF87E481B2FC28800CE1EBB /* testTests */ = { 173 | isa = PBXNativeTarget; 174 | buildConfigurationList = 3AF87E561B2FC28800CE1EBB /* Build configuration list for PBXNativeTarget "testTests" */; 175 | buildPhases = ( 176 | 3AF87E451B2FC28800CE1EBB /* Sources */, 177 | 3AF87E461B2FC28800CE1EBB /* Frameworks */, 178 | 3AF87E471B2FC28800CE1EBB /* Resources */, 179 | ); 180 | buildRules = ( 181 | ); 182 | dependencies = ( 183 | 3AF87E4B1B2FC28800CE1EBB /* PBXTargetDependency */, 184 | ); 185 | name = testTests; 186 | productName = testTests; 187 | productReference = 3AF87E491B2FC28800CE1EBB /* testTests.xctest */; 188 | productType = "com.apple.product-type.bundle.unit-test"; 189 | }; 190 | /* End PBXNativeTarget section */ 191 | 192 | /* Begin PBXProject section */ 193 | 3AF87E251B2FC28800CE1EBB /* Project object */ = { 194 | isa = PBXProject; 195 | attributes = { 196 | LastUpgradeCheck = 0630; 197 | ORGANIZATIONNAME = ming; 198 | TargetAttributes = { 199 | 3AF87E2C1B2FC28800CE1EBB = { 200 | CreatedOnToolsVersion = 6.3.2; 201 | SystemCapabilities = { 202 | com.apple.BackgroundModes = { 203 | enabled = 1; 204 | }; 205 | }; 206 | }; 207 | 3AF87E481B2FC28800CE1EBB = { 208 | CreatedOnToolsVersion = 6.3.2; 209 | TestTargetID = 3AF87E2C1B2FC28800CE1EBB; 210 | }; 211 | }; 212 | }; 213 | buildConfigurationList = 3AF87E281B2FC28800CE1EBB /* Build configuration list for PBXProject "test" */; 214 | compatibilityVersion = "Xcode 3.2"; 215 | developmentRegion = English; 216 | hasScannedForEncodings = 0; 217 | knownRegions = ( 218 | en, 219 | Base, 220 | ); 221 | mainGroup = 3AF87E241B2FC28700CE1EBB; 222 | productRefGroup = 3AF87E2E1B2FC28800CE1EBB /* Products */; 223 | projectDirPath = ""; 224 | projectRoot = ""; 225 | targets = ( 226 | 3AF87E2C1B2FC28800CE1EBB /* test */, 227 | 3AF87E481B2FC28800CE1EBB /* testTests */, 228 | ); 229 | }; 230 | /* End PBXProject section */ 231 | 232 | /* Begin PBXResourcesBuildPhase section */ 233 | 3AF87E2B1B2FC28800CE1EBB /* Resources */ = { 234 | isa = PBXResourcesBuildPhase; 235 | buildActionMask = 2147483647; 236 | files = ( 237 | 3AF87E3F1B2FC28800CE1EBB /* Main.storyboard in Resources */, 238 | 3AF87E441B2FC28800CE1EBB /* LaunchScreen.xib in Resources */, 239 | 3AF87E411B2FC28800CE1EBB /* Images.xcassets in Resources */, 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | }; 243 | 3AF87E471B2FC28800CE1EBB /* Resources */ = { 244 | isa = PBXResourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | ); 248 | runOnlyForDeploymentPostprocessing = 0; 249 | }; 250 | /* End PBXResourcesBuildPhase section */ 251 | 252 | /* Begin PBXSourcesBuildPhase section */ 253 | 3AF87E291B2FC28800CE1EBB /* Sources */ = { 254 | isa = PBXSourcesBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | 3AF87E3C1B2FC28800CE1EBB /* SecondViewController.m in Sources */, 258 | 3AE6B1C11B33B1EF000CBE6C /* UILabel+ContentSize.m in Sources */, 259 | 3AE6B1BD1B32F0B7000CBE6C /* UIViewAdditions.m in Sources */, 260 | 3AF87E361B2FC28800CE1EBB /* AppDelegate.m in Sources */, 261 | 3AF87E391B2FC28800CE1EBB /* FirstViewController.m in Sources */, 262 | 3AB0AA871B392CA900128BA6 /* UIColor-Expanded.m in Sources */, 263 | 3AF87E331B2FC28800CE1EBB /* main.m in Sources */, 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | 3AF87E451B2FC28800CE1EBB /* Sources */ = { 268 | isa = PBXSourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | 3AF87E501B2FC28800CE1EBB /* testTests.m in Sources */, 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | }; 275 | /* End PBXSourcesBuildPhase section */ 276 | 277 | /* Begin PBXTargetDependency section */ 278 | 3AF87E4B1B2FC28800CE1EBB /* PBXTargetDependency */ = { 279 | isa = PBXTargetDependency; 280 | target = 3AF87E2C1B2FC28800CE1EBB /* test */; 281 | targetProxy = 3AF87E4A1B2FC28800CE1EBB /* PBXContainerItemProxy */; 282 | }; 283 | /* End PBXTargetDependency section */ 284 | 285 | /* Begin PBXVariantGroup section */ 286 | 3AF87E3D1B2FC28800CE1EBB /* Main.storyboard */ = { 287 | isa = PBXVariantGroup; 288 | children = ( 289 | 3AF87E3E1B2FC28800CE1EBB /* Base */, 290 | ); 291 | name = Main.storyboard; 292 | sourceTree = ""; 293 | }; 294 | 3AF87E421B2FC28800CE1EBB /* LaunchScreen.xib */ = { 295 | isa = PBXVariantGroup; 296 | children = ( 297 | 3AF87E431B2FC28800CE1EBB /* Base */, 298 | ); 299 | name = LaunchScreen.xib; 300 | sourceTree = ""; 301 | }; 302 | /* End PBXVariantGroup section */ 303 | 304 | /* Begin XCBuildConfiguration section */ 305 | 3AF87E511B2FC28800CE1EBB /* Debug */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ALWAYS_SEARCH_USER_PATHS = NO; 309 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 310 | CLANG_CXX_LIBRARY = "libc++"; 311 | CLANG_ENABLE_MODULES = YES; 312 | CLANG_ENABLE_OBJC_ARC = YES; 313 | CLANG_WARN_BOOL_CONVERSION = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 316 | CLANG_WARN_EMPTY_BODY = YES; 317 | CLANG_WARN_ENUM_CONVERSION = YES; 318 | CLANG_WARN_INT_CONVERSION = YES; 319 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 320 | CLANG_WARN_UNREACHABLE_CODE = YES; 321 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 322 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 323 | COPY_PHASE_STRIP = NO; 324 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 325 | ENABLE_STRICT_OBJC_MSGSEND = YES; 326 | GCC_C_LANGUAGE_STANDARD = gnu99; 327 | GCC_DYNAMIC_NO_PIC = NO; 328 | GCC_NO_COMMON_BLOCKS = YES; 329 | GCC_OPTIMIZATION_LEVEL = 0; 330 | GCC_PREPROCESSOR_DEFINITIONS = ( 331 | "DEBUG=1", 332 | "$(inherited)", 333 | ); 334 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 335 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 336 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 337 | GCC_WARN_UNDECLARED_SELECTOR = YES; 338 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 339 | GCC_WARN_UNUSED_FUNCTION = YES; 340 | GCC_WARN_UNUSED_VARIABLE = YES; 341 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 342 | MTL_ENABLE_DEBUG_INFO = YES; 343 | ONLY_ACTIVE_ARCH = YES; 344 | SDKROOT = iphoneos; 345 | TARGETED_DEVICE_FAMILY = "1,2"; 346 | }; 347 | name = Debug; 348 | }; 349 | 3AF87E521B2FC28800CE1EBB /* Release */ = { 350 | isa = XCBuildConfiguration; 351 | buildSettings = { 352 | ALWAYS_SEARCH_USER_PATHS = NO; 353 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 354 | CLANG_CXX_LIBRARY = "libc++"; 355 | CLANG_ENABLE_MODULES = YES; 356 | CLANG_ENABLE_OBJC_ARC = YES; 357 | CLANG_WARN_BOOL_CONVERSION = YES; 358 | CLANG_WARN_CONSTANT_CONVERSION = YES; 359 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 360 | CLANG_WARN_EMPTY_BODY = YES; 361 | CLANG_WARN_ENUM_CONVERSION = YES; 362 | CLANG_WARN_INT_CONVERSION = YES; 363 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 364 | CLANG_WARN_UNREACHABLE_CODE = YES; 365 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 366 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 367 | COPY_PHASE_STRIP = NO; 368 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 369 | ENABLE_NS_ASSERTIONS = NO; 370 | ENABLE_STRICT_OBJC_MSGSEND = YES; 371 | GCC_C_LANGUAGE_STANDARD = gnu99; 372 | GCC_NO_COMMON_BLOCKS = YES; 373 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 374 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 375 | GCC_WARN_UNDECLARED_SELECTOR = YES; 376 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 377 | GCC_WARN_UNUSED_FUNCTION = YES; 378 | GCC_WARN_UNUSED_VARIABLE = YES; 379 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 380 | MTL_ENABLE_DEBUG_INFO = NO; 381 | SDKROOT = iphoneos; 382 | TARGETED_DEVICE_FAMILY = "1,2"; 383 | VALIDATE_PRODUCT = YES; 384 | }; 385 | name = Release; 386 | }; 387 | 3AF87E541B2FC28800CE1EBB /* Debug */ = { 388 | isa = XCBuildConfiguration; 389 | buildSettings = { 390 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 391 | INFOPLIST_FILE = test/Info.plist; 392 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 393 | PRODUCT_NAME = "$(TARGET_NAME)"; 394 | }; 395 | name = Debug; 396 | }; 397 | 3AF87E551B2FC28800CE1EBB /* Release */ = { 398 | isa = XCBuildConfiguration; 399 | buildSettings = { 400 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 401 | INFOPLIST_FILE = test/Info.plist; 402 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 403 | PRODUCT_NAME = "$(TARGET_NAME)"; 404 | }; 405 | name = Release; 406 | }; 407 | 3AF87E571B2FC28800CE1EBB /* Debug */ = { 408 | isa = XCBuildConfiguration; 409 | buildSettings = { 410 | BUNDLE_LOADER = "$(TEST_HOST)"; 411 | FRAMEWORK_SEARCH_PATHS = ( 412 | "$(SDKROOT)/Developer/Library/Frameworks", 413 | "$(inherited)", 414 | ); 415 | GCC_PREPROCESSOR_DEFINITIONS = ( 416 | "DEBUG=1", 417 | "$(inherited)", 418 | ); 419 | INFOPLIST_FILE = testTests/Info.plist; 420 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 421 | PRODUCT_NAME = "$(TARGET_NAME)"; 422 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/test.app/test"; 423 | }; 424 | name = Debug; 425 | }; 426 | 3AF87E581B2FC28800CE1EBB /* Release */ = { 427 | isa = XCBuildConfiguration; 428 | buildSettings = { 429 | BUNDLE_LOADER = "$(TEST_HOST)"; 430 | FRAMEWORK_SEARCH_PATHS = ( 431 | "$(SDKROOT)/Developer/Library/Frameworks", 432 | "$(inherited)", 433 | ); 434 | INFOPLIST_FILE = testTests/Info.plist; 435 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 436 | PRODUCT_NAME = "$(TARGET_NAME)"; 437 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/test.app/test"; 438 | }; 439 | name = Release; 440 | }; 441 | /* End XCBuildConfiguration section */ 442 | 443 | /* Begin XCConfigurationList section */ 444 | 3AF87E281B2FC28800CE1EBB /* Build configuration list for PBXProject "test" */ = { 445 | isa = XCConfigurationList; 446 | buildConfigurations = ( 447 | 3AF87E511B2FC28800CE1EBB /* Debug */, 448 | 3AF87E521B2FC28800CE1EBB /* Release */, 449 | ); 450 | defaultConfigurationIsVisible = 0; 451 | defaultConfigurationName = Release; 452 | }; 453 | 3AF87E531B2FC28800CE1EBB /* Build configuration list for PBXNativeTarget "test" */ = { 454 | isa = XCConfigurationList; 455 | buildConfigurations = ( 456 | 3AF87E541B2FC28800CE1EBB /* Debug */, 457 | 3AF87E551B2FC28800CE1EBB /* Release */, 458 | ); 459 | defaultConfigurationIsVisible = 0; 460 | defaultConfigurationName = Release; 461 | }; 462 | 3AF87E561B2FC28800CE1EBB /* Build configuration list for PBXNativeTarget "testTests" */ = { 463 | isa = XCConfigurationList; 464 | buildConfigurations = ( 465 | 3AF87E571B2FC28800CE1EBB /* Debug */, 466 | 3AF87E581B2FC28800CE1EBB /* Release */, 467 | ); 468 | defaultConfigurationIsVisible = 0; 469 | defaultConfigurationName = Release; 470 | }; 471 | /* End XCConfigurationList section */ 472 | }; 473 | rootObject = 3AF87E251B2FC28800CE1EBB /* Project object */; 474 | } 475 | --------------------------------------------------------------------------------