需求:

  1. textView 需要placeholder用来提示输入
  2. textView 要做字数限制
  3. textView 禁止表情符号的输入

思考:

因为需求比较通用,便想通过自定义SJTextView来实现:

  1. placeholder 通过在textView上添加一个透明的label,输入开始后隐藏实现。
  2. 字数限制可以在代理方法中实现,字数达到最大后禁止输入
  3. 表情符号禁止输入(这个不常用,因为我们服务器不接收,于是做了限制输入),用了github中 SearchEmojiOnString-iOS 关于表情的 NSString+EMOEmoji 可以很方便实现

问题:如果在自定义SJTextView时使用了UITextView的代理方法,如果在使用这个自定义的TextView中再使用代理方法,就会覆盖SJTextView中的代理方法。

解决:UITextVeiw 给了三种编辑状态 UITextViewTextDidBeginEditingNotification UITextViewTextDidChangeNotification UITextViewTextDidEndEditingNotification 可以通过监听 UITextViewTextDidChangeNotification 来对textView进行处理。

实现:

添加外部属性

/**
 占位字符串
 */
@property (nonatomic, strong) NSString *placeholder;

/**
 占位字符串颜色
 */
@property (nonatomic, strong) UIColor *placeholderColor;

/**
 字符串长度限制
 */
@property (nonatomic, assign) NSUInteger limitedLength;

/**
 是否机制字表情符号的输入
 */
@property (nonatomic, assign) BOOL emojiDisable;

添加方法

1. 添加占位字符label

/**
 占位字符串

 @param placeholder 占位字符串
 */
- (void)setPlaceholder:(NSString *)placeholder {
    if (placeholder) {
        _placeholder = placeholder;
        self.placeholderLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 8, self.frame.size.width - 10, 0)];
        self.placeholderLabel.numberOfLines = 0;
        self.placeholderLabel.text = placeholder;
        self.placeholderLabel.textColor = [UIColor lightGrayColor];
        self.placeholderLabel.font = [UIFont systemFontOfSize:13]; // UITextView 默认的字体大小为13
        [self adjustLabelFrameHeight:self.placeholderLabel]; // placeholder适应高度
        [self addSubview:self.placeholderLabel];
    }
}

2. 限制表情符号输入
/**
 限制表情符号的输入 需要引入 NSString+EMOEmoji 分类,也可以把方法复制过来
 */
- (void)disableEmoji {
    if([self.text emo_containsEmoji]) {

        //  emo_disableEmoji 方法是,在 NSString+EMOEmoji中改写了一个方法,具体看代码
        [self setText:[self.text emo_disableEmoji]];
    }
}

3. 添加字符长度限制
// 给SJTextView添加一个属性 记录上一次最后显示在textView中的字符串的内部属性, 是完成字符串长度限制的关键

// 最后一次显示在textView中的符合限制字符串
@property (nonatomic, strong) NSString *lastText;

// 初始化时,添加监听
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(textViewEditChanged) name:UITextViewTextDidChangeNotification object:self];

// 监听方法实现
- (void)textViewEditChanged {

    // ----- placeholderLabel 的显示与隐藏 -----
    if (self.text.length == 0) {
        [self.placeholderLabel setHidden:NO];
    }
    else {
        [self.placeholderLabel setHidden:YES];
    }

    // ----- 禁止输入表情符号 -----

    if (self.emojiDisable) {
        [self disableEmoji];
    }    

    // ----- 字数限制 -----

    // 获取高亮部分
    UITextRange *selectedRange = [self markedTextRange];

    UITextPosition *pos = [self positionFromPosition:selectedRange.start offset:0];

    // 如果输入的字还可以变化,就不做限制,self.lastText也不会记录还在变化状态的文字

    if (selectedRange && pos) {
        return;
    }

    if (self.text.length > self.lastText.length) {
        NSString  *newInputText = [self.text substringFromIndex:self.lastText.length];
        NSUInteger canInputLength = self.limitedLength - self.lastText.length;

        // 如果长度超出了可输入长度,还原为上次输入的字符串,也就是说如果你是复制的一大段文字,长度超过了可输入的长度,这段文字一个字都不会输入到TextView中(你要重新编辑好了再重新粘贴,输入一部分,还是要删除的)
        if (newInputText.length > canInputLength || canInputLength == 0) {
            [self setText:self.lastText];

            // 这里给出提示,输入超过了限制
            NSLog(@"%@",[NSString stringWithFormat:@"字数不能超过%lu个。",(unsigned long)self.limitedLength]);
        }
    }
    self.lastText = self.text;
}

iOS自定义视图- SJTextView的更多相关文章

  1. Xamarin iOS教程之自定义视图

    Xamarin iOS教程之自定义视图 Xamarin iOS自定义视图 工具栏中的视图在实际应用开发中用的很多,但是为了吸引用户的眼球,开发者可以做出一些自定义的视图. [示例2-33]以下将实现一 ...

  2. iOS自定义组与组之间的距离以及视图

    iOS自定义组与组之间的距离以及视图 //头视图高度 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(N ...

  3. iOS学习之自定义视图时,在屏幕发生旋转时触发重新布局方法

    如果要对自定义的视图在屏幕旋转时重新布局,则在自定义视图中定义以下触发方法: -(void)layoutSubviews { [super layoutSubviews]; //1.获取到屏幕旋转的方 ...

  4. UI基础:UI程序执行顺序(UIApplicationMain()函数),自定义视图 分类: iOS学习-UI 2015-07-02 22:09 68人阅读 评论(0) 收藏

    UI程序的一般执行顺序: 先进入main里面,执行函数UIApplicationMain(),通过该函数创建应用程序对象和指定其代理并实现监听,当执行函数UIApplicationMain()时还会做 ...

  5. 【iOS自定义键盘及键盘切换】详解

    [iOS自定义键盘]详解 实现效果展示: 一.实现的协议方法代码 #import <UIKit/UIKit.h> //创建自定义键盘协议 @protocol XFG_KeyBoardDel ...

  6. 自定义视图一:扩展现有的视图,添加新的XML属性

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! 简介 这个系列详细的介绍了如何穿件Android自定义视图.主要涉及的内容有如何绘制内容,layout和measure的原理,如何继承 ...

  7. iOS自定义的UISwitch按钮

    UISwitch开关控件 开关代替了点选框.开关是到目前为止用起来最简单的控件,不过仍然可以作一定程度的定制化. 一.创建 UISwitch* mySwitch = [[ UISwitchalloc] ...

  8. ##DAY3 自定义视图、视图控制器、视图控制器指定视图、loadView、 viewDidLoad、MVC、屏幕旋转、内存警告

    ##DAY3 自定义视图.视图控制器.视图控制器指定视图.loadView. viewDidLoad.MVC.屏幕旋转.内存警告 #pragma mark ———————自定义视图的步骤 —————— ...

  9. UI 自定义视图 ,视图管理器

    一>自定义label - textField 视图 自定义视图:系统标准UI之外,自己组合而出的新的视图 iOS 提供了很多UI组件 ,借助它们,我们可以做各种程序 尽管如此,实际开发中,我们还 ...

随机推荐

  1. Jboss 集群配置

    环境配置:CentOS 7 x64 * 3 IP:  172.24.0.100        172.24.0.101        172.24.0.102 服务器配置: 172.24.0.100 ...

  2. 一个很好玩的命令:stty

    stty命令修改终端命令行的相关设置.语法stty(选项)(参数)选项-a:以容易阅读的方式打印当前的所有配置:-g:以stty可读方式打印当前的所有配置.参数终端设置:指定终端命令行的设置选项.实例 ...

  3. (中等) HDU 4370 0 or 1,建模+Dijkstra。

    Description Given a n*n matrix C ij (1<=i,j<=n),We want to find a n*n matrix X ij (1<=i,j&l ...

  4. 鸽笼原理的运用HDU1205

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1205 题目解析:开始没看清题,WA了一发,以为只要最大的次大的差2就是NO,后来仔细看过之后才发现,, ...

  5. ListView与RadioButton组合——自定义单选列表

      标签: radiobuttonlistviewandroidlayout 2013-09-10 11:13 19396人阅读 评论(8) 收藏 举报  分类: Android(19)  版权声明: ...

  6. HTML5 - Canvas动画样例(谷歌弹跳球)

    1,样例说明 (1)在没有鼠标介入的情况下,这些球就像有磁性一样拼成"Google"字样. (2)在鼠标移动到其中后,小球像是受到了排斥,向画布的四周扩散,然后不规则地反弹回来. ...

  7. Android L(5.0)源码之图形与图像处理之动画——Frame、Tween、属性动画、SurfaceView

    工作中暂时还没涉及到,暂时先不总结

  8. 试水MongoDB

    1)安装好后启动mongodb 服务 1_1) 建立data/db     ,保证至少有3g大小的盘 1_2) 建立log 文件夹 1_3)配置文件 内容,指定数据存放位置.日志文件位置 dbpath ...

  9. Maven的安装环境配置

    一.Maven的安装 二.Maven的配置 Settings.xml可以用来定义本地仓库.远程仓库.联网代理 Settings.xml文件可以存在两个地方: 1.多用户情况 conf目录下 2.单用户 ...

  10. 【Xilinx-Petalinux学习】-01-开发环境搭建与PetaLinux的安装

    开发环境 VMware12, Ubuntu 16.04 64 bit 在VMware中安装Ubuntu,用户名:xilinx-arm 密码:root step1: VMware Tools问题 不知道 ...