├── .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 | 
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 |
--------------------------------------------------------------------------------