├── .DS_Store ├── CodeView.gif ├── CodeView.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ ├── my.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ ├── limingmeng.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ └── mengliming.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ ├── limingmeng.xcuserdatad │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ ├── mengliming.xcuserdatad │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── my.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── CodeView.xcscheme └── project.pbxproj ├── CodeView ├── ViewController.h ├── AppDelegate.h ├── main.m ├── CodeView │ ├── NSString+Category.h │ ├── CodeView.h │ ├── NSString+Category.m │ └── CodeView.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── Base.lproj │ ├── Main.storyboard │ └── LaunchScreen.storyboard ├── AppDelegate.m └── ViewController.m ├── README.md ├── CodeViewTests ├── Info.plist └── CodeViewTests.m └── CodeViewUITests ├── Info.plist └── CodeViewUITests.m /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/CodeView/HEAD/.DS_Store -------------------------------------------------------------------------------- /CodeView.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/CodeView/HEAD/CodeView.gif -------------------------------------------------------------------------------- /CodeView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CodeView.xcodeproj/project.xcworkspace/xcuserdata/my.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/CodeView/HEAD/CodeView.xcodeproj/project.xcworkspace/xcuserdata/my.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /CodeView.xcodeproj/project.xcworkspace/xcuserdata/limingmeng.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/CodeView/HEAD/CodeView.xcodeproj/project.xcworkspace/xcuserdata/limingmeng.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /CodeView.xcodeproj/project.xcworkspace/xcuserdata/mengliming.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/CodeView/HEAD/CodeView.xcodeproj/project.xcworkspace/xcuserdata/mengliming.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /CodeView/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // CodeView 4 | // 5 | // Created by my on 16/5/18. 6 | // Copyright © 2016年 MS. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeView 2 | 验证码输入,密码输入框封装 3 | 4 | 5 | ###增加下划线动画 6 | 7 | 增加下划线动画,提示正在输入 8 | 9 | ###增加多次输入功能 10 | 11 | 输入完成后,清空,重新输入 12 | 13 | 14 | ###修复双击造成的错误 15 | 16 | 双击导致观察者添加了两次 17 | 18 | ![image](https://github.com/MengLiMing/CodeView/blob/master/CodeView.gif) 19 | -------------------------------------------------------------------------------- /CodeView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CodeView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // CodeView 4 | // 5 | // Created by my on 16/5/18. 6 | // Copyright © 2016年 MS. 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 | -------------------------------------------------------------------------------- /CodeView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CodeView 4 | // 5 | // Created by my on 16/5/18. 6 | // Copyright © 2016年 MS. 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 | -------------------------------------------------------------------------------- /CodeView.xcodeproj/xcuserdata/limingmeng.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CodeView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /CodeView.xcodeproj/xcuserdata/mengliming.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CodeView.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /CodeView.xcodeproj/xcuserdata/my.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /CodeView/CodeView/NSString+Category.h: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | * * EaseMob CONFIDENTIAL 3 | * __________________ 4 | * Copyright (C) 2013-2014 EaseMob Technologies. All rights reserved. 5 | * 6 | * NOTICE: All information contained herein is, and remains 7 | * the property of EaseMob Technologies. 8 | * Dissemination of this information or reproduction of this material 9 | * is strictly forbidden unless prior written permission is obtained 10 | * from EaseMob Technologies. 11 | */ 12 | 13 | #import 14 | #import 15 | 16 | @interface NSString (Category) 17 | 18 | - (CGSize)stringSizeWithFont:(UIFont *)font Size:(CGSize)size; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /CodeViewTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /CodeViewUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /CodeView.xcodeproj/xcuserdata/my.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CodeView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 0F1D1DCA1CEC5D3E008FC24B 16 | 17 | primary 18 | 19 | 20 | 0F1D1DE31CEC5D3E008FC24B 21 | 22 | primary 23 | 24 | 25 | 0F1D1DEE1CEC5D3E008FC24B 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /CodeViewTests/CodeViewTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CodeViewTests.m 3 | // CodeViewTests 4 | // 5 | // Created by my on 16/5/18. 6 | // Copyright © 2016年 MS. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CodeViewTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation CodeViewTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /CodeViewUITests/CodeViewUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CodeViewUITests.m 3 | // CodeViewUITests 4 | // 5 | // Created by my on 16/5/18. 6 | // Copyright © 2016年 MS. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CodeViewUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation CodeViewUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /CodeView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "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 | } -------------------------------------------------------------------------------- /CodeView/CodeView/CodeView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CodeView.h 3 | // BaseProject 4 | // 5 | // Created by my on 16/3/24. 6 | // Copyright © 2016年 base. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger,CodeViewType) { 12 | CodeViewTypeCustom,//普通样式 13 | CodeViewTypeSecret//密码风格 14 | }; 15 | 16 | @interface CodeView : UIView 17 | 18 | //输入完成回调 19 | @property (nonatomic, copy) void(^EndEditBlcok)(NSString *text); 20 | @property (nonatomic, copy) void(^changeEditBlock)(); 21 | 22 | //样式 23 | @property (nonatomic, assign) CodeViewType codeType; 24 | 25 | //是否需要分隔符 26 | @property (nonatomic, assign) BOOL hasSpaceLine; 27 | //是否有下标线 28 | @property (nonatomic, assign) BOOL hasUnderLine; 29 | 30 | //是否需要输入之后清空,再次输入使用,默认为NO 31 | @property (nonatomic, assign) BOOL emptyEditEnd; 32 | 33 | 34 | //是否添加下划线的动画,默认NO 35 | @property (nonatomic, assign) BOOL underLineAnimation; 36 | 37 | 38 | //在underLineAnimation为YES时,未输入状态下是否闪烁,YES为闪烁 NO不闪烁 39 | @property (nonatomic, assign) BOOL noInputAni;; 40 | 41 | 42 | //下划线中心点 43 | @property (nonatomic, assign) CGFloat underLine_center_y; 44 | 45 | @property (nonatomic, strong) NSString *text; 46 | 47 | 48 | - (instancetype)initWithFrame:(CGRect)frame 49 | num:(NSInteger)num 50 | lineColor:(UIColor *)lColor 51 | textFont:(CGFloat)font; 52 | 53 | - (void)beginEdit; 54 | - (void)endEdit; 55 | - (void)emptyCodeView; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /CodeView/CodeView/NSString+Category.m: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | * * EaseMob CONFIDENTIAL 3 | * __________________ 4 | * Copyright (C) 2013-2014 EaseMob Technologies. All rights reserved. 5 | * 6 | * NOTICE: All information contained herein is, and remains 7 | * the property of EaseMob Technologies. 8 | * Dissemination of this information or reproduction of this material 9 | * is strictly forbidden unless prior written permission is obtained 10 | * from EaseMob Technologies. 11 | */ 12 | 13 | #import "NSString+Category.h" 14 | 15 | @implementation NSString (Category) 16 | 17 | //根据字符串的字体和size(此处size设置为字符串宽和MAXFLOAT)返回多行显示时的字符串size 18 | - (CGSize)stringSizeWithFont:(UIFont *)font Size:(CGSize)size { 19 | 20 | CGSize resultSize; 21 | if ([[UIDevice currentDevice].systemVersion floatValue] >= 7) { 22 | //段落样式 23 | NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; 24 | style.lineBreakMode = NSLineBreakByWordWrapping; 25 | 26 | //字体大小,换行模式 27 | NSDictionary *attributes = @{NSFontAttributeName : font , NSParagraphStyleAttributeName : style}; 28 | resultSize = [self boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size; 29 | } else { 30 | //计算正文的高度 31 | resultSize = [self sizeWithFont:font constrainedToSize:size lineBreakMode:NSLineBreakByWordWrapping]; 32 | } 33 | return resultSize; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /CodeView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | 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 | -------------------------------------------------------------------------------- /CodeView/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 | -------------------------------------------------------------------------------- /CodeView/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /CodeView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // CodeView 4 | // 5 | // Created by my on 16/5/18. 6 | // Copyright © 2016年 MS. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // 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. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // 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. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /CodeView/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // CodeView 4 | // 5 | // Created by my on 16/5/18. 6 | // Copyright © 2016年 MS. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "CodeView.h" 11 | 12 | @interface ViewController () 13 | 14 | @end 15 | 16 | @implementation ViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | 21 | [self addView]; 22 | } 23 | 24 | 25 | - (void)addView { 26 | 27 | NSArray *arr = @[@"普通,下划线 分割线", 28 | @"普通,下划线", 29 | @"密码", 30 | @"密码,分割线"]; 31 | for (NSInteger i = 0; i < arr.count; i ++) { 32 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 40 + 80 * i, self.view.frame.size.width, 20)]; 33 | label.textAlignment = NSTextAlignmentCenter; 34 | label.text = arr[i]; 35 | [self.view addSubview:label]; 36 | 37 | CodeView *v = [[CodeView alloc] initWithFrame:CGRectMake(0, 60 + 80 * i, self.view.frame.size.width - 10, 60) 38 | num:6 39 | lineColor:[UIColor blackColor] 40 | textFont:50]; 41 | 42 | switch (i) { 43 | case 0: 44 | { 45 | // //下划线 46 | // v.hasUnderLine = YES; 47 | //分割线 48 | v.hasSpaceLine = YES; 49 | //输入之后置空 50 | v.emptyEditEnd = YES; 51 | v.underLineAnimation = YES; 52 | //输入风格 53 | v.codeType = CodeViewTypeCustom; 54 | } 55 | break; 56 | case 1: 57 | { 58 | //下划线 59 | v.hasUnderLine = YES; 60 | //分割线 61 | v.hasSpaceLine = NO; 62 | 63 | //输入风格 64 | v.codeType = CodeViewTypeCustom; 65 | } 66 | break; 67 | case 2: 68 | { 69 | //下划线 70 | v.hasUnderLine = NO; 71 | //分割线 72 | v.hasSpaceLine = NO; 73 | 74 | //输入风格 75 | v.codeType = CodeViewTypeSecret; 76 | } 77 | break; 78 | case 3: 79 | { 80 | //下划线 81 | v.hasUnderLine = NO; 82 | //分割线 83 | v.hasSpaceLine = YES; 84 | 85 | //输入风格 86 | v.codeType = CodeViewTypeSecret; 87 | } 88 | break; 89 | default: 90 | break; 91 | } 92 | 93 | 94 | v.EndEditBlcok = ^(NSString *str) { 95 | NSLog(@"%@",str); 96 | }; 97 | [self.view addSubview:v]; 98 | } 99 | } 100 | 101 | 102 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 103 | [self.view endEditing:YES]; 104 | } 105 | - (void)didReceiveMemoryWarning { 106 | [super didReceiveMemoryWarning]; 107 | // Dispose of any resources that can be recreated. 108 | } 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /CodeView.xcodeproj/xcuserdata/my.xcuserdatad/xcschemes/CodeView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /CodeView/CodeView/CodeView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CodeView.m 3 | // BaseProject 4 | // 5 | // Created by my on 16/3/24. 6 | // Copyright © 2016年 base. All rights reserved. 7 | // 8 | 9 | #import "CodeView.h" 10 | #import "NSString+Category.h" 11 | 12 | #define Space 5 13 | #define LineWidth (self.frame.size.width - lineNum * 2 * Space)/lineNum 14 | #define LineHeight 2 15 | 16 | //下标线距离底部高度 17 | #define LineBottomHeight 5 18 | 19 | //密码风格 圆点半径 20 | #define RADIUS 5 21 | 22 | @interface CodeView () 23 | { 24 | NSMutableArray *textArray; 25 | 26 | //线的条数 27 | NSInteger lineNum; 28 | 29 | UIColor *linecolor; 30 | UIColor *textcolor; 31 | UIFont *textFont; 32 | 33 | } 34 | @property (nonatomic, strong) NSMutableArray *underlineArr; 35 | @end 36 | 37 | @implementation CodeView 38 | 39 | - (instancetype)initWithFrame:(CGRect)frame 40 | num:(NSInteger)num 41 | lineColor:(UIColor *)lColor 42 | textFont:(CGFloat)font { 43 | 44 | self = [super initWithFrame:frame]; 45 | if (self) { 46 | self.frame = frame; 47 | self.backgroundColor = [UIColor whiteColor]; 48 | textArray = [NSMutableArray arrayWithCapacity:num]; 49 | 50 | lineNum = num; 51 | //数字样式是的颜色和线条颜色相同 52 | linecolor = textcolor = lColor; 53 | 54 | self.layer.borderWidth = 1; 55 | self.layer.borderColor = lColor.CGColor; 56 | 57 | textFont = [UIFont boldSystemFontOfSize:font]; 58 | 59 | _text = @""; 60 | _underLine_center_y = frame.size.height - LineBottomHeight - LineHeight/2; 61 | 62 | 63 | _underLineAnimation = NO; 64 | _emptyEditEnd = NO; 65 | //设置的字体高度小于self的高 66 | NSAssert(textFont.lineHeight < self.frame.size.height, @"设置的字体高度应该小于self的高"); 67 | } 68 | 69 | return self; 70 | } 71 | 72 | - (void)setUnderLineAnimation:(BOOL)underLineAnimation { 73 | _underLineAnimation = underLineAnimation; 74 | if (underLineAnimation && !_hasUnderLine) { 75 | self.hasUnderLine = YES; 76 | } 77 | } 78 | 79 | 80 | - (void)setHasSpaceLine:(BOOL)hasSpaceLine { 81 | _hasSpaceLine = hasSpaceLine; 82 | if (hasSpaceLine) { 83 | [self addSpaceLine]; 84 | } 85 | } 86 | 87 | - (void)setHasUnderLine:(BOOL)hasUnderLine { 88 | _hasUnderLine = hasUnderLine; 89 | if (hasUnderLine) { 90 | [self addUnderLine]; 91 | } 92 | } 93 | 94 | 95 | 96 | - (void)setText:(NSString *)text { 97 | textArray = [[self charArray:text] mutableCopy]; 98 | _text = [textArray componentsJoinedByString:@""]; 99 | 100 | //标记为需要重绘 101 | [self setNeedsDisplay]; 102 | [self underLineHidden]; 103 | [self addUnderLineAnimation]; 104 | 105 | if (textArray.count < lineNum) { 106 | if (self.changeEditBlock) { 107 | self.changeEditBlock(); 108 | } 109 | } else if (textArray.count == lineNum) { 110 | if (self.EndEditBlcok) { 111 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 112 | self.EndEditBlcok(_text); 113 | }); 114 | } 115 | } 116 | } 117 | 118 | 119 | - (NSArray *)charArray:(NSString *)text { 120 | NSMutableArray *array = [NSMutableArray array]; 121 | 122 | NSInteger max = MIN(text.length, lineNum); 123 | for (NSInteger i = 0; i < max; i ++) { 124 | NSString *str = [text substringWithRange:NSMakeRange(i, 1)]; 125 | [array addObject:str]; 126 | } 127 | return array; 128 | } 129 | 130 | //置空 重绘 131 | - (void)emptyAndDisplay { 132 | _text = @""; 133 | [textArray removeAllObjects]; 134 | if (_emptyEditEnd) { 135 | [self setNeedsDisplay]; 136 | [self underLineHidden]; 137 | } 138 | 139 | if (_noInputAni) { 140 | [self addUnderLineAnimation]; 141 | } 142 | 143 | } 144 | 145 | - (void)emptyCodeView { 146 | _text = @""; 147 | [textArray removeAllObjects]; 148 | [self setNeedsDisplay]; 149 | [self underLineHidden]; 150 | 151 | if (_noInputAni) { 152 | [self addUnderLineAnimation]; 153 | } 154 | } 155 | 156 | #pragma mark - 下划线是否隐藏 157 | - (void)underLineHidden { 158 | if (_hasUnderLine) { 159 | //判断底部的view隐藏还是显示 160 | for (NSInteger i = 0; i < lineNum; i ++) { 161 | CAShapeLayer *obj = [_underlineArr objectAtIndex:i]; 162 | obj.hidden = i < textArray.count; 163 | } 164 | } 165 | } 166 | 167 | 168 | //键盘弹出 169 | - (void)beginEdit { 170 | [self addUnderLineAnimation]; 171 | 172 | } 173 | 174 | 175 | - (void)endEdit { 176 | [_underlineArr makeObjectsPerformSelector:@selector(removeAnimationForKey:) withObject:@"kOpacityAnimation"]; 177 | } 178 | 179 | 180 | 181 | - (void)setUnderLine_center_y:(CGFloat)underLine_center_y { 182 | _underLine_center_y = underLine_center_y; 183 | for (CAShapeLayer *layer in _underlineArr) { 184 | layer.frame = CGRectMake(CGRectGetMinX(layer.frame), 185 | _underLine_center_y - LineHeight/2, 186 | LineWidth, 187 | LineHeight); 188 | } 189 | 190 | } 191 | 192 | 193 | //添加下划线 194 | - (void)addUnderLine { 195 | [self.underlineArr removeAllObjects]; 196 | for (NSInteger i = 0; i < lineNum; i ++) { 197 | CAShapeLayer *line = [CAShapeLayer layer]; 198 | line.frame = CGRectMake(Space * (2 *i + 1) + i * LineWidth, _underLine_center_y - LineHeight/2, LineWidth, LineHeight); 199 | line.fillColor = linecolor.CGColor; 200 | UIBezierPath *path = [UIBezierPath bezierPathWithRect:line.bounds]; 201 | line.path = path.CGPath; 202 | line.hidden = textArray.count > i; 203 | [self.layer addSublayer:line]; 204 | [self.underlineArr addObject:line]; 205 | } 206 | 207 | if (!_noInputAni) { 208 | [self addUnderLineAnimation]; 209 | } 210 | 211 | } 212 | 213 | //添加分割线 214 | - (void)addSpaceLine { 215 | for (NSInteger i = 0; i < lineNum - 1; i ++) { 216 | CAShapeLayer *line = [CAShapeLayer layer]; 217 | line.fillColor = linecolor.CGColor; 218 | UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(self.frame.size.width/lineNum * (i + 1), 1, .5, self.frame.size.height - 1)]; 219 | line.path = path.CGPath; 220 | line.hidden = NO; 221 | [self.layer addSublayer:line]; 222 | } 223 | } 224 | 225 | 226 | #pragma mark - 懒加载 227 | - (NSMutableArray *)underlineArr{ 228 | if (_underlineArr == nil) { 229 | _underlineArr = [NSMutableArray array]; 230 | } 231 | return _underlineArr; 232 | } 233 | // Only override drawRect: if you perform custom drawing. 234 | // An empty implementation adversely affects performance during animation. 235 | 236 | - (void)drawRect:(CGRect)rect { 237 | // Drawing code 238 | switch (_codeType) { 239 | case CodeViewTypeCustom: 240 | { 241 | //画字 242 | //字的起点 243 | 244 | CGContextRef context = UIGraphicsGetCurrentContext(); 245 | for (NSInteger i = 0; i < textArray.count; i ++) { 246 | NSString *num = textArray[i]; 247 | CGFloat wordWidth = [num stringSizeWithFont:textFont Size:CGSizeMake(MAXFLOAT, textFont.lineHeight)].width; 248 | //起点 249 | CGFloat startX = self.frame.size.width/lineNum * i + (self.frame.size.width/lineNum - wordWidth)/2; 250 | 251 | [num drawInRect:CGRectMake(startX, (self.frame.size.height - textFont.lineHeight - LineBottomHeight - LineHeight)/2, wordWidth, textFont.lineHeight + 5) withAttributes:@{NSFontAttributeName:textFont,NSForegroundColorAttributeName:textcolor}]; 252 | } 253 | CGContextDrawPath(context, kCGPathFill); 254 | } 255 | break; 256 | case CodeViewTypeSecret: 257 | { 258 | //画圆 259 | CGContextRef context = UIGraphicsGetCurrentContext(); 260 | for (NSInteger i = 0; i < textArray.count; i ++) { 261 | //圆点 262 | CGFloat pointX = self.frame.size.width/lineNum/2 * (2 * i + 1); 263 | CGFloat pointY = self.frame.size.height/2; 264 | CGContextAddArc(context, pointX, pointY, RADIUS, 0, 2*M_PI, 0);//添加一个圆 265 | CGContextDrawPath(context, kCGPathFill);//绘制填充 266 | } 267 | CGContextDrawPath(context, kCGPathFill); 268 | 269 | } 270 | break; 271 | default: 272 | break; 273 | } 274 | 275 | } 276 | 277 | #pragma mark - 有下划线时,下划线的动画 278 | - (void)addUnderLineAnimation { 279 | if (_underLineAnimation) { 280 | if (textArray.count >= lineNum) { 281 | return; 282 | } 283 | for (NSInteger i = 0; i < _underlineArr.count; i ++) { 284 | CAShapeLayer *line = _underlineArr[i]; 285 | if (i == textArray.count) { 286 | [line addAnimation:[self opacityAnimation] forKey:@"kOpacityAnimation"]; 287 | } else { 288 | [line removeAnimationForKey:@"kOpacityAnimation"]; 289 | } 290 | } 291 | } 292 | } 293 | 294 | 295 | - (CABasicAnimation *)opacityAnimation { 296 | CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 297 | opacityAnimation.fromValue = @(1.0); 298 | opacityAnimation.toValue = @(0.0); 299 | opacityAnimation.duration = .8; 300 | opacityAnimation.repeatCount = HUGE_VALF; 301 | opacityAnimation.removedOnCompletion = NO; 302 | opacityAnimation.fillMode = kCAFillModeForwards; 303 | opacityAnimation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 304 | return opacityAnimation; 305 | } 306 | 307 | 308 | @end 309 | -------------------------------------------------------------------------------- /CodeView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0F1D1DD01CEC5D3E008FC24B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F1D1DCF1CEC5D3E008FC24B /* main.m */; }; 11 | 0F1D1DD31CEC5D3E008FC24B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F1D1DD21CEC5D3E008FC24B /* AppDelegate.m */; }; 12 | 0F1D1DD61CEC5D3E008FC24B /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F1D1DD51CEC5D3E008FC24B /* ViewController.m */; }; 13 | 0F1D1DD91CEC5D3E008FC24B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0F1D1DD71CEC5D3E008FC24B /* Main.storyboard */; }; 14 | 0F1D1DDB1CEC5D3E008FC24B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0F1D1DDA1CEC5D3E008FC24B /* Assets.xcassets */; }; 15 | 0F1D1DDE1CEC5D3E008FC24B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0F1D1DDC1CEC5D3E008FC24B /* LaunchScreen.storyboard */; }; 16 | 0F1D1DE91CEC5D3E008FC24B /* CodeViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F1D1DE81CEC5D3E008FC24B /* CodeViewTests.m */; }; 17 | 0F1D1DF41CEC5D3E008FC24B /* CodeViewUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F1D1DF31CEC5D3E008FC24B /* CodeViewUITests.m */; }; 18 | 0F1D1E041CEC5D71008FC24B /* CodeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F1D1E031CEC5D71008FC24B /* CodeView.m */; }; 19 | 0F2662131D0BC31800778A07 /* NSString+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F2662121D0BC31800778A07 /* NSString+Category.m */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 0F1D1DE51CEC5D3E008FC24B /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 0F1D1DC31CEC5D3E008FC24B /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 0F1D1DCA1CEC5D3E008FC24B; 28 | remoteInfo = CodeView; 29 | }; 30 | 0F1D1DF01CEC5D3E008FC24B /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 0F1D1DC31CEC5D3E008FC24B /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 0F1D1DCA1CEC5D3E008FC24B; 35 | remoteInfo = CodeView; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 0F1D1DCB1CEC5D3E008FC24B /* CodeView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CodeView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 0F1D1DCF1CEC5D3E008FC24B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 42 | 0F1D1DD11CEC5D3E008FC24B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 43 | 0F1D1DD21CEC5D3E008FC24B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 44 | 0F1D1DD41CEC5D3E008FC24B /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 45 | 0F1D1DD51CEC5D3E008FC24B /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 46 | 0F1D1DD81CEC5D3E008FC24B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 47 | 0F1D1DDA1CEC5D3E008FC24B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 48 | 0F1D1DDD1CEC5D3E008FC24B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 49 | 0F1D1DDF1CEC5D3E008FC24B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | 0F1D1DE41CEC5D3E008FC24B /* CodeViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 0F1D1DE81CEC5D3E008FC24B /* CodeViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CodeViewTests.m; sourceTree = ""; }; 52 | 0F1D1DEA1CEC5D3E008FC24B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53 | 0F1D1DEF1CEC5D3E008FC24B /* CodeViewUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeViewUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 0F1D1DF31CEC5D3E008FC24B /* CodeViewUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CodeViewUITests.m; sourceTree = ""; }; 55 | 0F1D1DF51CEC5D3E008FC24B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 56 | 0F1D1E021CEC5D71008FC24B /* CodeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeView.h; sourceTree = ""; }; 57 | 0F1D1E031CEC5D71008FC24B /* CodeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodeView.m; sourceTree = ""; }; 58 | 0F2662111D0BC31800778A07 /* NSString+Category.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Category.h"; sourceTree = ""; }; 59 | 0F2662121D0BC31800778A07 /* NSString+Category.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Category.m"; sourceTree = ""; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | 0F1D1DC81CEC5D3E008FC24B /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | 0F1D1DE11CEC5D3E008FC24B /* Frameworks */ = { 71 | isa = PBXFrameworksBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | 0F1D1DEC1CEC5D3E008FC24B /* Frameworks */ = { 78 | isa = PBXFrameworksBuildPhase; 79 | buildActionMask = 2147483647; 80 | files = ( 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | /* End PBXFrameworksBuildPhase section */ 85 | 86 | /* Begin PBXGroup section */ 87 | 0F1D1DC21CEC5D3E008FC24B = { 88 | isa = PBXGroup; 89 | children = ( 90 | 0F1D1DCD1CEC5D3E008FC24B /* CodeView */, 91 | 0F1D1DE71CEC5D3E008FC24B /* CodeViewTests */, 92 | 0F1D1DF21CEC5D3E008FC24B /* CodeViewUITests */, 93 | 0F1D1DCC1CEC5D3E008FC24B /* Products */, 94 | ); 95 | sourceTree = ""; 96 | }; 97 | 0F1D1DCC1CEC5D3E008FC24B /* Products */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 0F1D1DCB1CEC5D3E008FC24B /* CodeView.app */, 101 | 0F1D1DE41CEC5D3E008FC24B /* CodeViewTests.xctest */, 102 | 0F1D1DEF1CEC5D3E008FC24B /* CodeViewUITests.xctest */, 103 | ); 104 | name = Products; 105 | sourceTree = ""; 106 | }; 107 | 0F1D1DCD1CEC5D3E008FC24B /* CodeView */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 0F1D1E011CEC5D71008FC24B /* CodeView */, 111 | 0F1D1DD11CEC5D3E008FC24B /* AppDelegate.h */, 112 | 0F1D1DD21CEC5D3E008FC24B /* AppDelegate.m */, 113 | 0F1D1DD41CEC5D3E008FC24B /* ViewController.h */, 114 | 0F1D1DD51CEC5D3E008FC24B /* ViewController.m */, 115 | 0F1D1DD71CEC5D3E008FC24B /* Main.storyboard */, 116 | 0F1D1DDA1CEC5D3E008FC24B /* Assets.xcassets */, 117 | 0F1D1DDC1CEC5D3E008FC24B /* LaunchScreen.storyboard */, 118 | 0F1D1DDF1CEC5D3E008FC24B /* Info.plist */, 119 | 0F1D1DCE1CEC5D3E008FC24B /* Supporting Files */, 120 | ); 121 | path = CodeView; 122 | sourceTree = ""; 123 | }; 124 | 0F1D1DCE1CEC5D3E008FC24B /* Supporting Files */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 0F1D1DCF1CEC5D3E008FC24B /* main.m */, 128 | ); 129 | name = "Supporting Files"; 130 | sourceTree = ""; 131 | }; 132 | 0F1D1DE71CEC5D3E008FC24B /* CodeViewTests */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 0F1D1DE81CEC5D3E008FC24B /* CodeViewTests.m */, 136 | 0F1D1DEA1CEC5D3E008FC24B /* Info.plist */, 137 | ); 138 | path = CodeViewTests; 139 | sourceTree = ""; 140 | }; 141 | 0F1D1DF21CEC5D3E008FC24B /* CodeViewUITests */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 0F1D1DF31CEC5D3E008FC24B /* CodeViewUITests.m */, 145 | 0F1D1DF51CEC5D3E008FC24B /* Info.plist */, 146 | ); 147 | path = CodeViewUITests; 148 | sourceTree = ""; 149 | }; 150 | 0F1D1E011CEC5D71008FC24B /* CodeView */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 0F2662111D0BC31800778A07 /* NSString+Category.h */, 154 | 0F2662121D0BC31800778A07 /* NSString+Category.m */, 155 | 0F1D1E021CEC5D71008FC24B /* CodeView.h */, 156 | 0F1D1E031CEC5D71008FC24B /* CodeView.m */, 157 | ); 158 | path = CodeView; 159 | sourceTree = ""; 160 | }; 161 | /* End PBXGroup section */ 162 | 163 | /* Begin PBXNativeTarget section */ 164 | 0F1D1DCA1CEC5D3E008FC24B /* CodeView */ = { 165 | isa = PBXNativeTarget; 166 | buildConfigurationList = 0F1D1DF81CEC5D3E008FC24B /* Build configuration list for PBXNativeTarget "CodeView" */; 167 | buildPhases = ( 168 | 0F1D1DC71CEC5D3E008FC24B /* Sources */, 169 | 0F1D1DC81CEC5D3E008FC24B /* Frameworks */, 170 | 0F1D1DC91CEC5D3E008FC24B /* Resources */, 171 | ); 172 | buildRules = ( 173 | ); 174 | dependencies = ( 175 | ); 176 | name = CodeView; 177 | productName = CodeView; 178 | productReference = 0F1D1DCB1CEC5D3E008FC24B /* CodeView.app */; 179 | productType = "com.apple.product-type.application"; 180 | }; 181 | 0F1D1DE31CEC5D3E008FC24B /* CodeViewTests */ = { 182 | isa = PBXNativeTarget; 183 | buildConfigurationList = 0F1D1DFB1CEC5D3E008FC24B /* Build configuration list for PBXNativeTarget "CodeViewTests" */; 184 | buildPhases = ( 185 | 0F1D1DE01CEC5D3E008FC24B /* Sources */, 186 | 0F1D1DE11CEC5D3E008FC24B /* Frameworks */, 187 | 0F1D1DE21CEC5D3E008FC24B /* Resources */, 188 | ); 189 | buildRules = ( 190 | ); 191 | dependencies = ( 192 | 0F1D1DE61CEC5D3E008FC24B /* PBXTargetDependency */, 193 | ); 194 | name = CodeViewTests; 195 | productName = CodeViewTests; 196 | productReference = 0F1D1DE41CEC5D3E008FC24B /* CodeViewTests.xctest */; 197 | productType = "com.apple.product-type.bundle.unit-test"; 198 | }; 199 | 0F1D1DEE1CEC5D3E008FC24B /* CodeViewUITests */ = { 200 | isa = PBXNativeTarget; 201 | buildConfigurationList = 0F1D1DFE1CEC5D3E008FC24B /* Build configuration list for PBXNativeTarget "CodeViewUITests" */; 202 | buildPhases = ( 203 | 0F1D1DEB1CEC5D3E008FC24B /* Sources */, 204 | 0F1D1DEC1CEC5D3E008FC24B /* Frameworks */, 205 | 0F1D1DED1CEC5D3E008FC24B /* Resources */, 206 | ); 207 | buildRules = ( 208 | ); 209 | dependencies = ( 210 | 0F1D1DF11CEC5D3E008FC24B /* PBXTargetDependency */, 211 | ); 212 | name = CodeViewUITests; 213 | productName = CodeViewUITests; 214 | productReference = 0F1D1DEF1CEC5D3E008FC24B /* CodeViewUITests.xctest */; 215 | productType = "com.apple.product-type.bundle.ui-testing"; 216 | }; 217 | /* End PBXNativeTarget section */ 218 | 219 | /* Begin PBXProject section */ 220 | 0F1D1DC31CEC5D3E008FC24B /* Project object */ = { 221 | isa = PBXProject; 222 | attributes = { 223 | LastUpgradeCheck = 0720; 224 | ORGANIZATIONNAME = MS; 225 | TargetAttributes = { 226 | 0F1D1DCA1CEC5D3E008FC24B = { 227 | CreatedOnToolsVersion = 7.2.1; 228 | DevelopmentTeam = 5MEUQ98276; 229 | }; 230 | 0F1D1DE31CEC5D3E008FC24B = { 231 | CreatedOnToolsVersion = 7.2.1; 232 | TestTargetID = 0F1D1DCA1CEC5D3E008FC24B; 233 | }; 234 | 0F1D1DEE1CEC5D3E008FC24B = { 235 | CreatedOnToolsVersion = 7.2.1; 236 | TestTargetID = 0F1D1DCA1CEC5D3E008FC24B; 237 | }; 238 | }; 239 | }; 240 | buildConfigurationList = 0F1D1DC61CEC5D3E008FC24B /* Build configuration list for PBXProject "CodeView" */; 241 | compatibilityVersion = "Xcode 3.2"; 242 | developmentRegion = English; 243 | hasScannedForEncodings = 0; 244 | knownRegions = ( 245 | en, 246 | Base, 247 | ); 248 | mainGroup = 0F1D1DC21CEC5D3E008FC24B; 249 | productRefGroup = 0F1D1DCC1CEC5D3E008FC24B /* Products */; 250 | projectDirPath = ""; 251 | projectRoot = ""; 252 | targets = ( 253 | 0F1D1DCA1CEC5D3E008FC24B /* CodeView */, 254 | 0F1D1DE31CEC5D3E008FC24B /* CodeViewTests */, 255 | 0F1D1DEE1CEC5D3E008FC24B /* CodeViewUITests */, 256 | ); 257 | }; 258 | /* End PBXProject section */ 259 | 260 | /* Begin PBXResourcesBuildPhase section */ 261 | 0F1D1DC91CEC5D3E008FC24B /* Resources */ = { 262 | isa = PBXResourcesBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | 0F1D1DDE1CEC5D3E008FC24B /* LaunchScreen.storyboard in Resources */, 266 | 0F1D1DDB1CEC5D3E008FC24B /* Assets.xcassets in Resources */, 267 | 0F1D1DD91CEC5D3E008FC24B /* Main.storyboard in Resources */, 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | }; 271 | 0F1D1DE21CEC5D3E008FC24B /* Resources */ = { 272 | isa = PBXResourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | 0F1D1DED1CEC5D3E008FC24B /* Resources */ = { 279 | isa = PBXResourcesBuildPhase; 280 | buildActionMask = 2147483647; 281 | files = ( 282 | ); 283 | runOnlyForDeploymentPostprocessing = 0; 284 | }; 285 | /* End PBXResourcesBuildPhase section */ 286 | 287 | /* Begin PBXSourcesBuildPhase section */ 288 | 0F1D1DC71CEC5D3E008FC24B /* Sources */ = { 289 | isa = PBXSourcesBuildPhase; 290 | buildActionMask = 2147483647; 291 | files = ( 292 | 0F1D1DD61CEC5D3E008FC24B /* ViewController.m in Sources */, 293 | 0F2662131D0BC31800778A07 /* NSString+Category.m in Sources */, 294 | 0F1D1DD31CEC5D3E008FC24B /* AppDelegate.m in Sources */, 295 | 0F1D1DD01CEC5D3E008FC24B /* main.m in Sources */, 296 | 0F1D1E041CEC5D71008FC24B /* CodeView.m in Sources */, 297 | ); 298 | runOnlyForDeploymentPostprocessing = 0; 299 | }; 300 | 0F1D1DE01CEC5D3E008FC24B /* Sources */ = { 301 | isa = PBXSourcesBuildPhase; 302 | buildActionMask = 2147483647; 303 | files = ( 304 | 0F1D1DE91CEC5D3E008FC24B /* CodeViewTests.m in Sources */, 305 | ); 306 | runOnlyForDeploymentPostprocessing = 0; 307 | }; 308 | 0F1D1DEB1CEC5D3E008FC24B /* Sources */ = { 309 | isa = PBXSourcesBuildPhase; 310 | buildActionMask = 2147483647; 311 | files = ( 312 | 0F1D1DF41CEC5D3E008FC24B /* CodeViewUITests.m in Sources */, 313 | ); 314 | runOnlyForDeploymentPostprocessing = 0; 315 | }; 316 | /* End PBXSourcesBuildPhase section */ 317 | 318 | /* Begin PBXTargetDependency section */ 319 | 0F1D1DE61CEC5D3E008FC24B /* PBXTargetDependency */ = { 320 | isa = PBXTargetDependency; 321 | target = 0F1D1DCA1CEC5D3E008FC24B /* CodeView */; 322 | targetProxy = 0F1D1DE51CEC5D3E008FC24B /* PBXContainerItemProxy */; 323 | }; 324 | 0F1D1DF11CEC5D3E008FC24B /* PBXTargetDependency */ = { 325 | isa = PBXTargetDependency; 326 | target = 0F1D1DCA1CEC5D3E008FC24B /* CodeView */; 327 | targetProxy = 0F1D1DF01CEC5D3E008FC24B /* PBXContainerItemProxy */; 328 | }; 329 | /* End PBXTargetDependency section */ 330 | 331 | /* Begin PBXVariantGroup section */ 332 | 0F1D1DD71CEC5D3E008FC24B /* Main.storyboard */ = { 333 | isa = PBXVariantGroup; 334 | children = ( 335 | 0F1D1DD81CEC5D3E008FC24B /* Base */, 336 | ); 337 | name = Main.storyboard; 338 | sourceTree = ""; 339 | }; 340 | 0F1D1DDC1CEC5D3E008FC24B /* LaunchScreen.storyboard */ = { 341 | isa = PBXVariantGroup; 342 | children = ( 343 | 0F1D1DDD1CEC5D3E008FC24B /* Base */, 344 | ); 345 | name = LaunchScreen.storyboard; 346 | sourceTree = ""; 347 | }; 348 | /* End PBXVariantGroup section */ 349 | 350 | /* Begin XCBuildConfiguration section */ 351 | 0F1D1DF61CEC5D3E008FC24B /* Debug */ = { 352 | isa = XCBuildConfiguration; 353 | buildSettings = { 354 | ALWAYS_SEARCH_USER_PATHS = NO; 355 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 356 | CLANG_CXX_LIBRARY = "libc++"; 357 | CLANG_ENABLE_MODULES = YES; 358 | CLANG_ENABLE_OBJC_ARC = YES; 359 | CLANG_WARN_BOOL_CONVERSION = YES; 360 | CLANG_WARN_CONSTANT_CONVERSION = YES; 361 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 362 | CLANG_WARN_EMPTY_BODY = YES; 363 | CLANG_WARN_ENUM_CONVERSION = YES; 364 | CLANG_WARN_INT_CONVERSION = YES; 365 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 366 | CLANG_WARN_UNREACHABLE_CODE = YES; 367 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 368 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 369 | COPY_PHASE_STRIP = NO; 370 | DEBUG_INFORMATION_FORMAT = dwarf; 371 | ENABLE_STRICT_OBJC_MSGSEND = YES; 372 | ENABLE_TESTABILITY = YES; 373 | GCC_C_LANGUAGE_STANDARD = gnu99; 374 | GCC_DYNAMIC_NO_PIC = NO; 375 | GCC_NO_COMMON_BLOCKS = YES; 376 | GCC_OPTIMIZATION_LEVEL = 0; 377 | GCC_PREPROCESSOR_DEFINITIONS = ( 378 | "DEBUG=1", 379 | "$(inherited)", 380 | ); 381 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 382 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 383 | GCC_WARN_UNDECLARED_SELECTOR = YES; 384 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 385 | GCC_WARN_UNUSED_FUNCTION = YES; 386 | GCC_WARN_UNUSED_VARIABLE = YES; 387 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 388 | MTL_ENABLE_DEBUG_INFO = YES; 389 | ONLY_ACTIVE_ARCH = YES; 390 | SDKROOT = iphoneos; 391 | TARGETED_DEVICE_FAMILY = "1,2"; 392 | }; 393 | name = Debug; 394 | }; 395 | 0F1D1DF71CEC5D3E008FC24B /* Release */ = { 396 | isa = XCBuildConfiguration; 397 | buildSettings = { 398 | ALWAYS_SEARCH_USER_PATHS = NO; 399 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 400 | CLANG_CXX_LIBRARY = "libc++"; 401 | CLANG_ENABLE_MODULES = YES; 402 | CLANG_ENABLE_OBJC_ARC = YES; 403 | CLANG_WARN_BOOL_CONVERSION = YES; 404 | CLANG_WARN_CONSTANT_CONVERSION = YES; 405 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 406 | CLANG_WARN_EMPTY_BODY = YES; 407 | CLANG_WARN_ENUM_CONVERSION = YES; 408 | CLANG_WARN_INT_CONVERSION = YES; 409 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 410 | CLANG_WARN_UNREACHABLE_CODE = YES; 411 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 412 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 413 | COPY_PHASE_STRIP = NO; 414 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 415 | ENABLE_NS_ASSERTIONS = NO; 416 | ENABLE_STRICT_OBJC_MSGSEND = YES; 417 | GCC_C_LANGUAGE_STANDARD = gnu99; 418 | GCC_NO_COMMON_BLOCKS = YES; 419 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 420 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 421 | GCC_WARN_UNDECLARED_SELECTOR = YES; 422 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 423 | GCC_WARN_UNUSED_FUNCTION = YES; 424 | GCC_WARN_UNUSED_VARIABLE = YES; 425 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 426 | MTL_ENABLE_DEBUG_INFO = NO; 427 | SDKROOT = iphoneos; 428 | TARGETED_DEVICE_FAMILY = "1,2"; 429 | VALIDATE_PRODUCT = YES; 430 | }; 431 | name = Release; 432 | }; 433 | 0F1D1DF91CEC5D3E008FC24B /* Debug */ = { 434 | isa = XCBuildConfiguration; 435 | buildSettings = { 436 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 437 | DEVELOPMENT_TEAM = 5MEUQ98276; 438 | INFOPLIST_FILE = CodeView/Info.plist; 439 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 440 | PRODUCT_BUNDLE_IDENTIFIER = com.MLM.CodeView; 441 | PRODUCT_NAME = "$(TARGET_NAME)"; 442 | }; 443 | name = Debug; 444 | }; 445 | 0F1D1DFA1CEC5D3E008FC24B /* Release */ = { 446 | isa = XCBuildConfiguration; 447 | buildSettings = { 448 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 449 | DEVELOPMENT_TEAM = 5MEUQ98276; 450 | INFOPLIST_FILE = CodeView/Info.plist; 451 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 452 | PRODUCT_BUNDLE_IDENTIFIER = com.MLM.CodeView; 453 | PRODUCT_NAME = "$(TARGET_NAME)"; 454 | }; 455 | name = Release; 456 | }; 457 | 0F1D1DFC1CEC5D3E008FC24B /* Debug */ = { 458 | isa = XCBuildConfiguration; 459 | buildSettings = { 460 | BUNDLE_LOADER = "$(TEST_HOST)"; 461 | INFOPLIST_FILE = CodeViewTests/Info.plist; 462 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 463 | PRODUCT_BUNDLE_IDENTIFIER = com.MLM.CodeViewTests; 464 | PRODUCT_NAME = "$(TARGET_NAME)"; 465 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CodeView.app/CodeView"; 466 | }; 467 | name = Debug; 468 | }; 469 | 0F1D1DFD1CEC5D3E008FC24B /* Release */ = { 470 | isa = XCBuildConfiguration; 471 | buildSettings = { 472 | BUNDLE_LOADER = "$(TEST_HOST)"; 473 | INFOPLIST_FILE = CodeViewTests/Info.plist; 474 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 475 | PRODUCT_BUNDLE_IDENTIFIER = com.MLM.CodeViewTests; 476 | PRODUCT_NAME = "$(TARGET_NAME)"; 477 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CodeView.app/CodeView"; 478 | }; 479 | name = Release; 480 | }; 481 | 0F1D1DFF1CEC5D3E008FC24B /* Debug */ = { 482 | isa = XCBuildConfiguration; 483 | buildSettings = { 484 | INFOPLIST_FILE = CodeViewUITests/Info.plist; 485 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 486 | PRODUCT_BUNDLE_IDENTIFIER = com.MLM.CodeViewUITests; 487 | PRODUCT_NAME = "$(TARGET_NAME)"; 488 | TEST_TARGET_NAME = CodeView; 489 | USES_XCTRUNNER = YES; 490 | }; 491 | name = Debug; 492 | }; 493 | 0F1D1E001CEC5D3E008FC24B /* Release */ = { 494 | isa = XCBuildConfiguration; 495 | buildSettings = { 496 | INFOPLIST_FILE = CodeViewUITests/Info.plist; 497 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 498 | PRODUCT_BUNDLE_IDENTIFIER = com.MLM.CodeViewUITests; 499 | PRODUCT_NAME = "$(TARGET_NAME)"; 500 | TEST_TARGET_NAME = CodeView; 501 | USES_XCTRUNNER = YES; 502 | }; 503 | name = Release; 504 | }; 505 | /* End XCBuildConfiguration section */ 506 | 507 | /* Begin XCConfigurationList section */ 508 | 0F1D1DC61CEC5D3E008FC24B /* Build configuration list for PBXProject "CodeView" */ = { 509 | isa = XCConfigurationList; 510 | buildConfigurations = ( 511 | 0F1D1DF61CEC5D3E008FC24B /* Debug */, 512 | 0F1D1DF71CEC5D3E008FC24B /* Release */, 513 | ); 514 | defaultConfigurationIsVisible = 0; 515 | defaultConfigurationName = Release; 516 | }; 517 | 0F1D1DF81CEC5D3E008FC24B /* Build configuration list for PBXNativeTarget "CodeView" */ = { 518 | isa = XCConfigurationList; 519 | buildConfigurations = ( 520 | 0F1D1DF91CEC5D3E008FC24B /* Debug */, 521 | 0F1D1DFA1CEC5D3E008FC24B /* Release */, 522 | ); 523 | defaultConfigurationIsVisible = 0; 524 | defaultConfigurationName = Release; 525 | }; 526 | 0F1D1DFB1CEC5D3E008FC24B /* Build configuration list for PBXNativeTarget "CodeViewTests" */ = { 527 | isa = XCConfigurationList; 528 | buildConfigurations = ( 529 | 0F1D1DFC1CEC5D3E008FC24B /* Debug */, 530 | 0F1D1DFD1CEC5D3E008FC24B /* Release */, 531 | ); 532 | defaultConfigurationIsVisible = 0; 533 | defaultConfigurationName = Release; 534 | }; 535 | 0F1D1DFE1CEC5D3E008FC24B /* Build configuration list for PBXNativeTarget "CodeViewUITests" */ = { 536 | isa = XCConfigurationList; 537 | buildConfigurations = ( 538 | 0F1D1DFF1CEC5D3E008FC24B /* Debug */, 539 | 0F1D1E001CEC5D3E008FC24B /* Release */, 540 | ); 541 | defaultConfigurationIsVisible = 0; 542 | defaultConfigurationName = Release; 543 | }; 544 | /* End XCConfigurationList section */ 545 | }; 546 | rootObject = 0F1D1DC31CEC5D3E008FC24B /* Project object */; 547 | } 548 | --------------------------------------------------------------------------------