├── README.md
├── Demo
├── FSTextView.xcodeproj
│ ├── xcuserdata
│ │ ├── Steven.xcuserdatad
│ │ │ ├── xcdebugger
│ │ │ │ └── Breakpoints_v2.xcbkptlist
│ │ │ └── xcschemes
│ │ │ │ ├── xcschememanagement.plist
│ │ │ │ └── FSTextView.xcscheme
│ │ ├── sheng.xcuserdatad
│ │ │ ├── xcdebugger
│ │ │ │ └── Breakpoints_v2.xcbkptlist
│ │ │ └── xcschemes
│ │ │ │ └── xcschememanagement.plist
│ │ ├── fusheng.xcuserdatad
│ │ │ └── xcschemes
│ │ │ │ └── xcschememanagement.plist
│ │ └── Allen.xcuserdatad
│ │ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── FSTextView.xcscheme
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ ├── Allen.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ │ ├── Steven.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ │ ├── sheng.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ │ └── fusheng.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── project.pbxproj
└── FSTextView
│ ├── ViewController.h
│ ├── RootViewController.h
│ ├── AppDelegate.h
│ ├── main.m
│ ├── RootViewController.m
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── AppDelegate.m
│ └── ViewController.m
├── FSTextView.podspec
├── LICENSE
└── FSTextView
├── FSTextView.h
└── FSTextView.m
/README.md:
--------------------------------------------------------------------------------
1 | > This repository has been deprecated, use [FSUIKit/FSTextView](https://github.com/lifution/FSUIKit/tree/main/Sources/Classes/Controls/FSTextView) instead.
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/xcuserdata/Steven.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/xcuserdata/sheng.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/project.xcworkspace/xcuserdata/Allen.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lifution/FSTextView/HEAD/Demo/FSTextView.xcodeproj/project.xcworkspace/xcuserdata/Allen.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/project.xcworkspace/xcuserdata/Steven.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lifution/FSTextView/HEAD/Demo/FSTextView.xcodeproj/project.xcworkspace/xcuserdata/Steven.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/project.xcworkspace/xcuserdata/sheng.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lifution/FSTextView/HEAD/Demo/FSTextView.xcodeproj/project.xcworkspace/xcuserdata/sheng.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/project.xcworkspace/xcuserdata/fusheng.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lifution/FSTextView/HEAD/Demo/FSTextView.xcodeproj/project.xcworkspace/xcuserdata/fusheng.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Demo/FSTextView/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // FSTextView
4 | //
5 | // Created by Sheng on 2016/9/27.
6 | // Copyright © 2016年 Sheng. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 | @end
14 |
15 |
--------------------------------------------------------------------------------
/Demo/FSTextView/RootViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // RootViewController.h
3 | // FSTextView
4 | //
5 | // Created by Sheng on 2018/11/10.
6 | // Copyright © 2018年 Sheng. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RootViewController : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Demo/FSTextView/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // FSTextView
4 | //
5 | // Created by Sheng on 2016/9/27.
6 | // Copyright © 2016年 Sheng. 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 |
--------------------------------------------------------------------------------
/Demo/FSTextView/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // FSTextView
4 | //
5 | // Created by Sheng on 2016/9/27.
6 | // Copyright © 2016年 Sheng. 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 |
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/xcuserdata/fusheng.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | FSTextView.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/xcuserdata/sheng.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | FSTextView.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/FSTextView.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "FSTextView"
3 | s.version = "1.8"
4 | s.summary = "Subclass of UITextView with Placeholder."
5 | s.license = { :type => "MIT", :file => "LICENSE" }
6 | s.homepage = "https://github.com/lifution/FSTextView"
7 | s.author = { "fusheng" => "lifution@icloud.com" }
8 | s.source = { :git => "https://github.com/lifution/FSTextView.git", :tag => "1.8" }
9 | s.requires_arc = true
10 | s.platform = :ios, "6.0"
11 | s.source_files = "FSTextView/*", "*.{h,m}"
12 | end
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/xcuserdata/Allen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/xcuserdata/Allen.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | FSTextView.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | B0D793C61D9A9CC000DCF067
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/xcuserdata/Steven.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | FSTextView.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | B0D793C61D9A9CC000DCF067
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Demo/FSTextView/RootViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // RootViewController.m
3 | // FSTextView
4 | //
5 | // Created by Sheng on 2018/11/10.
6 | // Copyright © 2018年 Sheng. All rights reserved.
7 | //
8 |
9 | #import "RootViewController.h"
10 |
11 | @interface RootViewController ()
12 |
13 | @end
14 |
15 | @implementation RootViewController
16 |
17 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
18 | {
19 | return 10.0;
20 | }
21 |
22 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
23 | {
24 | return nil;
25 | }
26 |
27 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
28 | {
29 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/Demo/FSTextView/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 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 FSTextView (https://github.com/lifution)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Demo/FSTextView/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 |
40 |
41 |
--------------------------------------------------------------------------------
/Demo/FSTextView/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 |
--------------------------------------------------------------------------------
/FSTextView/FSTextView.h:
--------------------------------------------------------------------------------
1 | //
2 | // FSTextView.h
3 | // FSTextView
4 | //
5 | // Created by Sheng on 2016/9/27.
6 | // Copyright © 2016年 Sheng. All rights reserved.
7 | //
8 |
9 | #import
10 | @class FSTextView;
11 |
12 | typedef void(^FSTextViewHandler)(FSTextView *textView);
13 |
14 | IB_DESIGNABLE
15 |
16 | @interface FSTextView : UITextView
17 |
18 | /**
19 | 便利构造器.
20 | */
21 | + (instancetype)textView;
22 |
23 | /**
24 | 设定文本改变Block回调. (切记弱化引用, 以免造成内存泄露.)
25 | */
26 | - (void)addTextDidChangeHandler:(FSTextViewHandler)eventHandler;
27 |
28 | /**
29 | 设定达到最大长度Block回调. (切记弱化引用, 以免造成内存泄露.)
30 | */
31 | - (void)addTextLengthDidMaxHandler:(FSTextViewHandler)maxHandler;
32 |
33 | /**
34 | 最大限制文本长度, 默认为无穷大, 即不限制, 如果被设为 0 也同样表示不限制字符数.
35 | */
36 | @property (nonatomic, assign) IBInspectable NSUInteger maxLength;
37 |
38 | /**
39 | 圆角半径.
40 | */
41 | @property (nonatomic, assign) IBInspectable CGFloat cornerRadius;
42 |
43 | /**
44 | 边框宽度.
45 | */
46 | @property (nonatomic, assign) IBInspectable CGFloat borderWidth;
47 |
48 | /**
49 | 边框颜色.
50 | */
51 | @property (nonatomic, strong) IBInspectable UIColor *borderColor;
52 |
53 | /**
54 | placeholder, 会自适应TextView宽高以及横竖屏切换, 字体默认和TextView一致.
55 | */
56 | @property (nonatomic, copy) IBInspectable NSString *placeholder;
57 |
58 | /**
59 | placeholder文本颜色, 默认为#C7C7CD.
60 | */
61 | @property (nonatomic, strong) IBInspectable UIColor *placeholderColor;
62 |
63 | /**
64 | placeholder文本字体, 默认为UITextView的默认字体.
65 | */
66 | @property (nonatomic, strong) UIFont *placeholderFont;
67 |
68 | /**
69 | 是否允许长按弹出UIMenuController, 默认为YES.
70 | */
71 | @property (nonatomic, assign, getter=isCanPerformAction) BOOL canPerformAction;
72 |
73 | /**
74 | 该属性返回一个经过处理的 `self.text` 的值, 去除了首位的空格和换行.
75 | */
76 | @property (nonatomic, readonly) NSString *formatText;
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/Demo/FSTextView/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // FSTextView
4 | //
5 | // Created by Sheng on 2016/9/27.
6 | // Copyright © 2016年 Sheng. 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 |
--------------------------------------------------------------------------------
/Demo/FSTextView/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // FSTextView
4 | //
5 | // Created by Sheng on 2016/9/27.
6 | // Copyright © 2016年 Sheng. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "FSTextView.h"
11 |
12 | @interface ViewController ()
13 |
14 | @end
15 |
16 | @implementation ViewController
17 |
18 | - (void)viewDidLoad
19 | {
20 | [super viewDidLoad];
21 |
22 | // 达到最大限制时提示的Label
23 | UILabel *noticeLabel = [[UILabel alloc] init];
24 | noticeLabel.font = [UIFont systemFontOfSize:14.f];
25 | noticeLabel.textColor = UIColor.redColor;
26 | [self.view addSubview:noticeLabel];
27 |
28 | // FSTextView
29 | FSTextView *textView = [FSTextView textView];
30 | textView.placeholder = @"这是一个继承于UITextView的带Placeholder的自定义TextView, 可以设定限制字符长度, 以Block形式回调, 简单直观!";
31 | textView.borderWidth = 1.f;
32 | textView.borderColor = UIColor.lightGrayColor;
33 | textView.cornerRadius = 5.f;
34 | textView.canPerformAction = NO;
35 | [self.view addSubview:textView];
36 | // 限制输入最大字符数.
37 | textView.maxLength = 10;
38 | // 添加输入改变Block回调.
39 | [textView addTextDidChangeHandler:^(FSTextView *textView) {
40 | noticeLabel.hidden = (textView.text.length < textView.maxLength);
41 | }];
42 | // 添加到达最大限制Block回调.
43 | [textView addTextLengthDidMaxHandler:^(FSTextView *textView) {
44 | noticeLabel.text = [NSString stringWithFormat:@"最多限制输入%zi个字符", textView.maxLength];
45 | noticeLabel.hidden = NO;
46 | }];
47 |
48 | // constraint
49 | textView.translatesAutoresizingMaskIntoConstraints = NO;
50 | noticeLabel.translatesAutoresizingMaskIntoConstraints = NO;
51 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-30-[textView]-30-|"
52 | options:kNilOptions
53 | metrics:nil
54 | views:NSDictionaryOfVariableBindings(textView)]];
55 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[textView(==100)]-8-[noticeLabel]"
56 | options:kNilOptions
57 | metrics:nil
58 | views:NSDictionaryOfVariableBindings(textView, noticeLabel)]];
59 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:noticeLabel
60 | attribute:NSLayoutAttributeCenterX
61 | relatedBy:NSLayoutRelationEqual
62 | toItem:self.view
63 | attribute:NSLayoutAttributeCenterX
64 | multiplier:1.f
65 | constant:0.f]];
66 | }
67 |
68 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
69 | {
70 | [super touchesBegan:touches withEvent:event];
71 | [self.view endEditing:YES];
72 | }
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/xcuserdata/Steven.xcuserdatad/xcschemes/FSTextView.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/xcuserdata/Allen.xcuserdatad/xcschemes/FSTextView.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
69 |
70 |
71 |
72 |
78 |
80 |
86 |
87 |
88 |
89 |
91 |
92 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/FSTextView/FSTextView.m:
--------------------------------------------------------------------------------
1 | //
2 | // FSTextView.m
3 | // FSTextView
4 | //
5 | // Created by Sheng on 2016/9/27.
6 | // Copyright © 2016年 Sheng. All rights reserved.
7 | //
8 |
9 | #import "FSTextView.h"
10 |
11 | CGFloat const kFSTextViewPlaceholderVerticalMargin = 8.0; ///< placeholder垂直方向边距
12 | CGFloat const kFSTextViewPlaceholderHorizontalMargin = 6.0; ///< placeholder水平方向边距
13 |
14 | @interface FSTextView ()
15 |
16 | @property (nonatomic, copy) FSTextViewHandler changeHandler; ///< 文本改变Block
17 | @property (nonatomic, copy) FSTextViewHandler maxHandler; ///< 达到最大限制字符数Block
18 | @property (nonatomic, strong) UILabel *placeholderLabel; ///< placeholderLabel
19 |
20 | @end
21 |
22 | @implementation FSTextView
23 |
24 | #pragma mark - Override
25 |
26 | - (void)dealloc
27 | {
28 | [[NSNotificationCenter defaultCenter] removeObserver:self];
29 | _changeHandler = NULL;
30 | _maxHandler = NULL;
31 | }
32 |
33 | - (instancetype)initWithCoder:(NSCoder *)aDecoder
34 | {
35 | if (!(self = [super initWithCoder:aDecoder])) return nil;
36 |
37 | if ([[[UIDevice currentDevice] systemVersion] compare:@"10.0" options:NSNumericSearch] != NSOrderedAscending) {
38 |
39 | [self layoutIfNeeded];
40 | }
41 |
42 | [self initialize];
43 |
44 | return self;
45 | }
46 |
47 | - (instancetype)initWithFrame:(CGRect)frame
48 | {
49 | if (!(self = [super initWithFrame:frame])) return nil;
50 |
51 | [self initialize];
52 |
53 | return self;
54 | }
55 |
56 | - (BOOL)becomeFirstResponder
57 | {
58 | BOOL become = [super becomeFirstResponder];
59 |
60 | // 成为第一响应者时注册通知监听文本变化
61 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange:) name:UITextViewTextDidChangeNotification object:nil];
62 |
63 | return become;
64 | }
65 |
66 | - (BOOL)resignFirstResponder
67 | {
68 | BOOL resign = [super resignFirstResponder];
69 |
70 | // 注销第一响应者时移除文本变化的通知, 以免影响其它的`UITextView`对象.
71 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:nil];
72 |
73 | return resign;
74 | }
75 |
76 | - (BOOL)canPerformAction:(SEL)action withSender:(id)sender
77 | {
78 | BOOL result = [super canPerformAction:action withSender:sender];
79 |
80 | if (result) {
81 | if (![self respondsToSelector:action]) {
82 | result = NO;
83 | } else {
84 | result = _canPerformAction;
85 | }
86 | }
87 |
88 | return result;
89 | }
90 |
91 | #pragma mark - Private
92 |
93 | - (void)initialize
94 | {
95 | // 基本配置 (需判断是否在Storyboard中设置了值)
96 | _canPerformAction = YES;
97 |
98 | if (_maxLength == 0 || _maxLength == NSNotFound) {
99 |
100 | _maxLength = NSUIntegerMax;
101 | }
102 |
103 | if (!_placeholderColor) {
104 |
105 | _placeholderColor = [UIColor colorWithRed:0.780 green:0.780 blue:0.804 alpha:1.000];
106 | }
107 |
108 | // 基本设定 (需判断是否在Storyboard中设置了值)
109 | if (!self.backgroundColor) {
110 |
111 | self.backgroundColor = [UIColor whiteColor];
112 | }
113 |
114 | if (!self.font) {
115 |
116 | self.font = [UIFont systemFontOfSize:15.f];
117 | }
118 |
119 | // placeholderLabel
120 | self.placeholderLabel.font = self.font;
121 | self.placeholderLabel.text = _placeholder; // 可能在Storyboard中设置了Placeholder
122 | self.placeholderLabel.textColor = _placeholderColor;
123 | [self addSubview:self.placeholderLabel];
124 |
125 | // constraint
126 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.placeholderLabel
127 | attribute:NSLayoutAttributeTop
128 | relatedBy:NSLayoutRelationEqual
129 | toItem:self
130 | attribute:NSLayoutAttributeTop
131 | multiplier:1.0
132 | constant:kFSTextViewPlaceholderVerticalMargin]];
133 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.placeholderLabel
134 | attribute:NSLayoutAttributeLeft
135 | relatedBy:NSLayoutRelationEqual
136 | toItem:self
137 | attribute:NSLayoutAttributeLeft
138 | multiplier:1.0
139 | constant:kFSTextViewPlaceholderHorizontalMargin]];
140 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.placeholderLabel
141 | attribute:NSLayoutAttributeWidth
142 | relatedBy:NSLayoutRelationLessThanOrEqual
143 | toItem:self
144 | attribute:NSLayoutAttributeWidth
145 | multiplier:1.0
146 | constant:-kFSTextViewPlaceholderHorizontalMargin*2]];
147 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.placeholderLabel
148 | attribute:NSLayoutAttributeHeight
149 | relatedBy:NSLayoutRelationLessThanOrEqual
150 | toItem:self
151 | attribute:NSLayoutAttributeHeight
152 | multiplier:1.0
153 | constant:-kFSTextViewPlaceholderVerticalMargin*2]];
154 | }
155 |
156 | #pragma mark - Getter
157 | /// 返回一个经过处理的 `self.text` 的值, 去除了首位的空格和换行.
158 | - (NSString *)formatText
159 | {
160 | return [[super text] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; // 去除首尾的空格和换行.
161 | }
162 |
163 | - (UILabel *)placeholderLabel
164 | {
165 | if (!_placeholderLabel) {
166 |
167 | _placeholderLabel = [[UILabel alloc] init];
168 | _placeholderLabel.numberOfLines = 0;
169 | _placeholderLabel.translatesAutoresizingMaskIntoConstraints = NO;
170 | }
171 |
172 | return _placeholderLabel;
173 | }
174 |
175 | #pragma mark - Setter
176 |
177 | - (void)setText:(NSString *)text
178 | {
179 | [super setText:text];
180 |
181 | self.placeholderLabel.hidden = [@(text.length) boolValue];
182 | // 手动模拟触发通知
183 | NSNotification *notification = [NSNotification notificationWithName:UITextViewTextDidChangeNotification object:self];
184 | [self textDidChange:notification];
185 | }
186 |
187 | - (void)setFont:(UIFont *)font
188 | {
189 | [super setFont:font];
190 |
191 | self.placeholderLabel.font = font;
192 | }
193 |
194 | - (void)setMaxLength:(NSUInteger)maxLength
195 | {
196 | _maxLength = fmax(0, maxLength);
197 | self.text = self.text;
198 | }
199 |
200 | - (void)setCornerRadius:(CGFloat)cornerRadius
201 | {
202 | _cornerRadius = cornerRadius;
203 | self.layer.cornerRadius = _cornerRadius;
204 | }
205 |
206 | - (void)setBorderColor:(UIColor *)borderColor
207 | {
208 | if (!borderColor) return;
209 |
210 | _borderColor = borderColor;
211 | self.layer.borderColor = _borderColor.CGColor;
212 | }
213 |
214 | - (void)setBorderWidth:(CGFloat)borderWidth
215 | {
216 | _borderWidth = borderWidth;
217 | self.layer.borderWidth = _borderWidth;
218 | }
219 |
220 | - (void)setPlaceholder:(NSString *)placeholder
221 | {
222 | if (!placeholder) return;
223 |
224 | _placeholder = [placeholder copy];
225 |
226 | if (_placeholder.length > 0) {
227 |
228 | self.placeholderLabel.text = _placeholder;
229 | }
230 | }
231 |
232 | - (void)setPlaceholderColor:(UIColor *)placeholderColor
233 | {
234 | if (!placeholderColor) return;
235 |
236 | _placeholderColor = placeholderColor;
237 |
238 | self.placeholderLabel.textColor = _placeholderColor;
239 | }
240 |
241 | - (void)setPlaceholderFont:(UIFont *)placeholderFont
242 | {
243 | if (!placeholderFont) return;
244 |
245 | _placeholderFont = placeholderFont;
246 |
247 | self.placeholderLabel.font = _placeholderFont;
248 | }
249 |
250 | #pragma mark - NSNotification
251 | - (void)textDidChange:(NSNotification *)notification
252 | {
253 | // 通知回调的实例的不是当前实例的话直接返回
254 | if (notification.object != self) return;
255 |
256 | // 根据字符数量显示或者隐藏 `placeholderLabel`
257 | self.placeholderLabel.hidden = [@(self.text.length) boolValue];
258 |
259 | // 禁止第一个字符输入空格或者换行
260 | if (self.text.length == 1) {
261 |
262 | if ([self.text isEqualToString:@" "] || [self.text isEqualToString:@"\n"]) {
263 |
264 | self.text = @"";
265 | }
266 | }
267 |
268 | // 只有当maxLength字段的值不为无穷大整型也不为0时才计算限制字符数.
269 | if (_maxLength != NSUIntegerMax && _maxLength != 0 && self.text.length > 0) {
270 |
271 | if (!self.markedTextRange && self.text.length > _maxLength) {
272 |
273 | !_maxHandler ?: _maxHandler(self); // 回调达到最大限制的Block.
274 | self.text = [self.text substringToIndex:_maxLength]; // 截取最大限制字符数.
275 | [self.undoManager removeAllActions]; // 达到最大字符数后清空所有 undoaction, 以免 undo 操作造成crash.
276 | }
277 | }
278 |
279 | // 回调文本改变的Block.
280 | !_changeHandler ?: _changeHandler(self);
281 | }
282 |
283 | #pragma mark - Public
284 |
285 | + (instancetype)textView
286 | {
287 | return [[self alloc] init];
288 | }
289 |
290 | - (void)addTextDidChangeHandler:(FSTextViewHandler)changeHandler
291 | {
292 | _changeHandler = [changeHandler copy];
293 | }
294 |
295 | - (void)addTextLengthDidMaxHandler:(FSTextViewHandler)maxHandler
296 | {
297 | _maxHandler = [maxHandler copy];
298 | }
299 |
300 | @end
301 |
--------------------------------------------------------------------------------
/Demo/FSTextView/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
--------------------------------------------------------------------------------
/Demo/FSTextView.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 0407437721972EFD0047D718 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0407437621972EFD0047D718 /* RootViewController.m */; };
11 | B0D793CC1D9A9CC000DCF067 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D793CB1D9A9CC000DCF067 /* main.m */; };
12 | B0D793CF1D9A9CC000DCF067 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D793CE1D9A9CC000DCF067 /* AppDelegate.m */; };
13 | B0D793D21D9A9CC000DCF067 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D793D11D9A9CC000DCF067 /* ViewController.m */; };
14 | B0D793D51D9A9CC000DCF067 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B0D793D31D9A9CC000DCF067 /* Main.storyboard */; };
15 | B0D793D71D9A9CC000DCF067 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B0D793D61D9A9CC000DCF067 /* Assets.xcassets */; };
16 | B0D793DA1D9A9CC000DCF067 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B0D793D81D9A9CC000DCF067 /* LaunchScreen.storyboard */; };
17 | B0D793E41D9A9D7E00DCF067 /* FSTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D793E31D9A9D7E00DCF067 /* FSTextView.m */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXFileReference section */
21 | 0407437521972EFD0047D718 /* RootViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; };
22 | 0407437621972EFD0047D718 /* RootViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; };
23 | B0D793C71D9A9CC000DCF067 /* FSTextView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FSTextView.app; sourceTree = BUILT_PRODUCTS_DIR; };
24 | B0D793CB1D9A9CC000DCF067 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
25 | B0D793CD1D9A9CC000DCF067 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
26 | B0D793CE1D9A9CC000DCF067 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
27 | B0D793D01D9A9CC000DCF067 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
28 | B0D793D11D9A9CC000DCF067 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
29 | B0D793D41D9A9CC000DCF067 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
30 | B0D793D61D9A9CC000DCF067 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
31 | B0D793D91D9A9CC000DCF067 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
32 | B0D793DB1D9A9CC000DCF067 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
33 | B0D793E21D9A9D7E00DCF067 /* FSTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSTextView.h; sourceTree = ""; };
34 | B0D793E31D9A9D7E00DCF067 /* FSTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSTextView.m; sourceTree = ""; };
35 | /* End PBXFileReference section */
36 |
37 | /* Begin PBXFrameworksBuildPhase section */
38 | B0D793C41D9A9CC000DCF067 /* Frameworks */ = {
39 | isa = PBXFrameworksBuildPhase;
40 | buildActionMask = 2147483647;
41 | files = (
42 | );
43 | runOnlyForDeploymentPostprocessing = 0;
44 | };
45 | /* End PBXFrameworksBuildPhase section */
46 |
47 | /* Begin PBXGroup section */
48 | B0D793BE1D9A9CC000DCF067 = {
49 | isa = PBXGroup;
50 | children = (
51 | B0D793C91D9A9CC000DCF067 /* FSTextView */,
52 | B0D793C81D9A9CC000DCF067 /* Products */,
53 | );
54 | sourceTree = "";
55 | };
56 | B0D793C81D9A9CC000DCF067 /* Products */ = {
57 | isa = PBXGroup;
58 | children = (
59 | B0D793C71D9A9CC000DCF067 /* FSTextView.app */,
60 | );
61 | name = Products;
62 | sourceTree = "";
63 | };
64 | B0D793C91D9A9CC000DCF067 /* FSTextView */ = {
65 | isa = PBXGroup;
66 | children = (
67 | B0D793E11D9A9D6700DCF067 /* FSTextView */,
68 | B0D793CD1D9A9CC000DCF067 /* AppDelegate.h */,
69 | B0D793CE1D9A9CC000DCF067 /* AppDelegate.m */,
70 | 0407437521972EFD0047D718 /* RootViewController.h */,
71 | 0407437621972EFD0047D718 /* RootViewController.m */,
72 | B0D793D01D9A9CC000DCF067 /* ViewController.h */,
73 | B0D793D11D9A9CC000DCF067 /* ViewController.m */,
74 | B0D793D31D9A9CC000DCF067 /* Main.storyboard */,
75 | B0D793D61D9A9CC000DCF067 /* Assets.xcassets */,
76 | B0D793D81D9A9CC000DCF067 /* LaunchScreen.storyboard */,
77 | B0D793DB1D9A9CC000DCF067 /* Info.plist */,
78 | B0D793CA1D9A9CC000DCF067 /* Supporting Files */,
79 | );
80 | path = FSTextView;
81 | sourceTree = "";
82 | };
83 | B0D793CA1D9A9CC000DCF067 /* Supporting Files */ = {
84 | isa = PBXGroup;
85 | children = (
86 | B0D793CB1D9A9CC000DCF067 /* main.m */,
87 | );
88 | name = "Supporting Files";
89 | sourceTree = "";
90 | };
91 | B0D793E11D9A9D6700DCF067 /* FSTextView */ = {
92 | isa = PBXGroup;
93 | children = (
94 | B0D793E21D9A9D7E00DCF067 /* FSTextView.h */,
95 | B0D793E31D9A9D7E00DCF067 /* FSTextView.m */,
96 | );
97 | name = FSTextView;
98 | path = ../../FSTextView;
99 | sourceTree = "";
100 | };
101 | /* End PBXGroup section */
102 |
103 | /* Begin PBXNativeTarget section */
104 | B0D793C61D9A9CC000DCF067 /* FSTextView */ = {
105 | isa = PBXNativeTarget;
106 | buildConfigurationList = B0D793DE1D9A9CC000DCF067 /* Build configuration list for PBXNativeTarget "FSTextView" */;
107 | buildPhases = (
108 | B0D793C31D9A9CC000DCF067 /* Sources */,
109 | B0D793C41D9A9CC000DCF067 /* Frameworks */,
110 | B0D793C51D9A9CC000DCF067 /* Resources */,
111 | );
112 | buildRules = (
113 | );
114 | dependencies = (
115 | );
116 | name = FSTextView;
117 | productName = FSTextView;
118 | productReference = B0D793C71D9A9CC000DCF067 /* FSTextView.app */;
119 | productType = "com.apple.product-type.application";
120 | };
121 | /* End PBXNativeTarget section */
122 |
123 | /* Begin PBXProject section */
124 | B0D793BF1D9A9CC000DCF067 /* Project object */ = {
125 | isa = PBXProject;
126 | attributes = {
127 | CLASSPREFIX = FS;
128 | LastUpgradeCheck = 0910;
129 | ORGANIZATIONNAME = Sheng;
130 | TargetAttributes = {
131 | B0D793C61D9A9CC000DCF067 = {
132 | CreatedOnToolsVersion = 7.3.1;
133 | DevelopmentTeam = Q5668NKEBD;
134 | ProvisioningStyle = Automatic;
135 | };
136 | };
137 | };
138 | buildConfigurationList = B0D793C21D9A9CC000DCF067 /* Build configuration list for PBXProject "FSTextView" */;
139 | compatibilityVersion = "Xcode 3.2";
140 | developmentRegion = English;
141 | hasScannedForEncodings = 0;
142 | knownRegions = (
143 | en,
144 | Base,
145 | );
146 | mainGroup = B0D793BE1D9A9CC000DCF067;
147 | productRefGroup = B0D793C81D9A9CC000DCF067 /* Products */;
148 | projectDirPath = "";
149 | projectRoot = "";
150 | targets = (
151 | B0D793C61D9A9CC000DCF067 /* FSTextView */,
152 | );
153 | };
154 | /* End PBXProject section */
155 |
156 | /* Begin PBXResourcesBuildPhase section */
157 | B0D793C51D9A9CC000DCF067 /* Resources */ = {
158 | isa = PBXResourcesBuildPhase;
159 | buildActionMask = 2147483647;
160 | files = (
161 | B0D793DA1D9A9CC000DCF067 /* LaunchScreen.storyboard in Resources */,
162 | B0D793D71D9A9CC000DCF067 /* Assets.xcassets in Resources */,
163 | B0D793D51D9A9CC000DCF067 /* Main.storyboard in Resources */,
164 | );
165 | runOnlyForDeploymentPostprocessing = 0;
166 | };
167 | /* End PBXResourcesBuildPhase section */
168 |
169 | /* Begin PBXSourcesBuildPhase section */
170 | B0D793C31D9A9CC000DCF067 /* Sources */ = {
171 | isa = PBXSourcesBuildPhase;
172 | buildActionMask = 2147483647;
173 | files = (
174 | B0D793E41D9A9D7E00DCF067 /* FSTextView.m in Sources */,
175 | B0D793D21D9A9CC000DCF067 /* ViewController.m in Sources */,
176 | B0D793CF1D9A9CC000DCF067 /* AppDelegate.m in Sources */,
177 | B0D793CC1D9A9CC000DCF067 /* main.m in Sources */,
178 | 0407437721972EFD0047D718 /* RootViewController.m in Sources */,
179 | );
180 | runOnlyForDeploymentPostprocessing = 0;
181 | };
182 | /* End PBXSourcesBuildPhase section */
183 |
184 | /* Begin PBXVariantGroup section */
185 | B0D793D31D9A9CC000DCF067 /* Main.storyboard */ = {
186 | isa = PBXVariantGroup;
187 | children = (
188 | B0D793D41D9A9CC000DCF067 /* Base */,
189 | );
190 | name = Main.storyboard;
191 | sourceTree = "";
192 | };
193 | B0D793D81D9A9CC000DCF067 /* LaunchScreen.storyboard */ = {
194 | isa = PBXVariantGroup;
195 | children = (
196 | B0D793D91D9A9CC000DCF067 /* Base */,
197 | );
198 | name = LaunchScreen.storyboard;
199 | sourceTree = "";
200 | };
201 | /* End PBXVariantGroup section */
202 |
203 | /* Begin XCBuildConfiguration section */
204 | B0D793DC1D9A9CC000DCF067 /* Debug */ = {
205 | isa = XCBuildConfiguration;
206 | buildSettings = {
207 | ALWAYS_SEARCH_USER_PATHS = NO;
208 | CLANG_ANALYZER_NONNULL = YES;
209 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
210 | CLANG_CXX_LIBRARY = "libc++";
211 | CLANG_ENABLE_MODULES = YES;
212 | CLANG_ENABLE_OBJC_ARC = YES;
213 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
214 | CLANG_WARN_BOOL_CONVERSION = YES;
215 | CLANG_WARN_COMMA = YES;
216 | CLANG_WARN_CONSTANT_CONVERSION = YES;
217 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
218 | CLANG_WARN_EMPTY_BODY = YES;
219 | CLANG_WARN_ENUM_CONVERSION = YES;
220 | CLANG_WARN_INFINITE_RECURSION = YES;
221 | CLANG_WARN_INT_CONVERSION = YES;
222 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
223 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
224 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
225 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
226 | CLANG_WARN_STRICT_PROTOTYPES = YES;
227 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
228 | CLANG_WARN_UNREACHABLE_CODE = YES;
229 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
230 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
231 | COPY_PHASE_STRIP = NO;
232 | DEBUG_INFORMATION_FORMAT = dwarf;
233 | ENABLE_STRICT_OBJC_MSGSEND = YES;
234 | ENABLE_TESTABILITY = YES;
235 | GCC_C_LANGUAGE_STANDARD = gnu99;
236 | GCC_DYNAMIC_NO_PIC = NO;
237 | GCC_NO_COMMON_BLOCKS = YES;
238 | GCC_OPTIMIZATION_LEVEL = 0;
239 | GCC_PREPROCESSOR_DEFINITIONS = (
240 | "DEBUG=1",
241 | "$(inherited)",
242 | );
243 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
244 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
245 | GCC_WARN_UNDECLARED_SELECTOR = YES;
246 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
247 | GCC_WARN_UNUSED_FUNCTION = YES;
248 | GCC_WARN_UNUSED_VARIABLE = YES;
249 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
250 | MTL_ENABLE_DEBUG_INFO = YES;
251 | ONLY_ACTIVE_ARCH = YES;
252 | SDKROOT = iphoneos;
253 | };
254 | name = Debug;
255 | };
256 | B0D793DD1D9A9CC000DCF067 /* Release */ = {
257 | isa = XCBuildConfiguration;
258 | buildSettings = {
259 | ALWAYS_SEARCH_USER_PATHS = NO;
260 | CLANG_ANALYZER_NONNULL = YES;
261 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
262 | CLANG_CXX_LIBRARY = "libc++";
263 | CLANG_ENABLE_MODULES = YES;
264 | CLANG_ENABLE_OBJC_ARC = YES;
265 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
266 | CLANG_WARN_BOOL_CONVERSION = YES;
267 | CLANG_WARN_COMMA = YES;
268 | CLANG_WARN_CONSTANT_CONVERSION = YES;
269 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
270 | CLANG_WARN_EMPTY_BODY = YES;
271 | CLANG_WARN_ENUM_CONVERSION = YES;
272 | CLANG_WARN_INFINITE_RECURSION = YES;
273 | CLANG_WARN_INT_CONVERSION = YES;
274 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
275 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
276 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
277 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
278 | CLANG_WARN_STRICT_PROTOTYPES = YES;
279 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
280 | CLANG_WARN_UNREACHABLE_CODE = YES;
281 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
282 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
283 | COPY_PHASE_STRIP = NO;
284 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
285 | ENABLE_NS_ASSERTIONS = NO;
286 | ENABLE_STRICT_OBJC_MSGSEND = YES;
287 | GCC_C_LANGUAGE_STANDARD = gnu99;
288 | GCC_NO_COMMON_BLOCKS = YES;
289 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
290 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
291 | GCC_WARN_UNDECLARED_SELECTOR = YES;
292 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
293 | GCC_WARN_UNUSED_FUNCTION = YES;
294 | GCC_WARN_UNUSED_VARIABLE = YES;
295 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
296 | MTL_ENABLE_DEBUG_INFO = NO;
297 | SDKROOT = iphoneos;
298 | VALIDATE_PRODUCT = YES;
299 | };
300 | name = Release;
301 | };
302 | B0D793DF1D9A9CC000DCF067 /* Debug */ = {
303 | isa = XCBuildConfiguration;
304 | buildSettings = {
305 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
306 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
307 | CODE_SIGN_STYLE = Automatic;
308 | DEVELOPMENT_TEAM = Q5668NKEBD;
309 | INFOPLIST_FILE = FSTextView/Info.plist;
310 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
311 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
312 | PRODUCT_BUNDLE_IDENTIFIER = com.trustdream.FSTextView;
313 | PRODUCT_NAME = "$(TARGET_NAME)";
314 | PROVISIONING_PROFILE_SPECIFIER = "";
315 | };
316 | name = Debug;
317 | };
318 | B0D793E01D9A9CC000DCF067 /* Release */ = {
319 | isa = XCBuildConfiguration;
320 | buildSettings = {
321 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
322 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
323 | CODE_SIGN_STYLE = Automatic;
324 | DEVELOPMENT_TEAM = Q5668NKEBD;
325 | INFOPLIST_FILE = FSTextView/Info.plist;
326 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
327 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
328 | PRODUCT_BUNDLE_IDENTIFIER = com.trustdream.FSTextView;
329 | PRODUCT_NAME = "$(TARGET_NAME)";
330 | PROVISIONING_PROFILE_SPECIFIER = "";
331 | };
332 | name = Release;
333 | };
334 | /* End XCBuildConfiguration section */
335 |
336 | /* Begin XCConfigurationList section */
337 | B0D793C21D9A9CC000DCF067 /* Build configuration list for PBXProject "FSTextView" */ = {
338 | isa = XCConfigurationList;
339 | buildConfigurations = (
340 | B0D793DC1D9A9CC000DCF067 /* Debug */,
341 | B0D793DD1D9A9CC000DCF067 /* Release */,
342 | );
343 | defaultConfigurationIsVisible = 0;
344 | defaultConfigurationName = Release;
345 | };
346 | B0D793DE1D9A9CC000DCF067 /* Build configuration list for PBXNativeTarget "FSTextView" */ = {
347 | isa = XCConfigurationList;
348 | buildConfigurations = (
349 | B0D793DF1D9A9CC000DCF067 /* Debug */,
350 | B0D793E01D9A9CC000DCF067 /* Release */,
351 | );
352 | defaultConfigurationIsVisible = 0;
353 | defaultConfigurationName = Release;
354 | };
355 | /* End XCConfigurationList section */
356 | };
357 | rootObject = B0D793BF1D9A9CC000DCF067 /* Project object */;
358 | }
359 |
--------------------------------------------------------------------------------