drawRect的工作原理:
首先苹果是不推荐我们直接使用drawRect进行工作的,直接调用他也是没有任何效果的。苹果要求我们调用UIView类中的setNeedsDisplay方法,则程序会自动调用drawRect方法进行重绘。(调用setNeedsDisplay会自动调用drawRect)。

在UIView中,重写drawRect: (CGRect) aRect方法,可以自己定义想要画的图案.且此方法一般情况下只会画一次.也就是说这个drawRect方法一般情况下只会被调用一次。
当某些情况下想要手动重画这个View,只需要掉用[self setNeedsDisplay]方法即可.
drawRect调用是在Controller->loadView, Controller->viewDidLoad 两方法被调用之后调用的.所以不用担心在控制器中,这些View的drawRect就开始画了.这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量值).

1.如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。
2.该方法在调用sizeThatFits后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。
3.通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。
4.直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0.
以上1,2推荐;而3,4不提倡

1.首先是可以多行输入的输入框(继承于UITextView,效果如下)

#pragma mark -- 初始化时调用 --
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
/**
* 初始化的时候为属性设置默认值
*/
self.placeholder = @"请输入文字";
self.placeholderColor = [UIColor lightGrayColor];
self.placeholderFont = [UIFont systemFontOfSize:]; /**
* 用textVeiw添加通知,当textView发生变化的时候会调用textChanged方法
*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil];
}
return self;
} #pragma mark -- 重绘(为textVeiw加上placeholder) --
- (void)drawRect:(CGRect)rect {
//如果文字消失了就会绘制placeholder
if (self.text.length == ) {
CGRect placeholderRect = CGRectZero;
placeholderRect.origin.x = ;
placeholderRect.origin.y = ;
placeholderRect.size.width = self.frame.size.width-;
placeholderRect.size.height = self.frame.size.height-;
[self.placeholder drawInRect:placeholderRect withAttributes:@{
NSFontAttributeName:_placeholderFont,
NSForegroundColorAttributeName:_placeholderColor
}];
}
[super drawRect:rect];
} #pragma mark -- 文字改变的时候会调用该方法
- (void)textChanged:(NSNotification *)notification {
/**
* 在文字改变的时候就重绘
*/
[self setNeedsDisplay];
} #pragma mark -- 移除通知
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

如果想自定义更多样式,可以给attribute多加一些属性就可以了!!!

2.自定义符合要求的输入框(继承于UITextField,效果如下)

上面左视图只有两个圆角而且离上下左都有1px的间距,并且placeholder是在右边的。

- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
/**
* 初始化属性,设置默认值
*/
_placeholderFont = [UIFont systemFontOfSize:];
_placeholderColor = [UIColor lightGrayColor]; CGFloat height = frame.size.height;
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(, , height-, height-)];
leftView.backgroundColor = [UIColor redColor]; UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Icon"]];
imageView.frame = CGRectMake(, , height-, height-);
[leftView addSubview:imageView]; //利用这个方法可以使左视图只有两个圆角
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:leftView.bounds byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerTopLeft cornerRadii:CGSizeMake(, )];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = leftView.bounds;
maskLayer.path = maskPath.CGPath;
leftView.layer.mask = maskLayer;
self.leftView = leftView;
self.leftViewMode = UITextFieldViewModeAlways; NSLog(@"%s",__func__);
}
return self;
}
//这两个方法我也不知道有什么用,如果有知道的可以联系我告诉我一下
/*
#pragma mark -- 重置边界区域
- (CGRect)borderRectForBounds:(CGRect)bounds {
CGRect borderRect = [super borderRectForBounds:bounds]; return borderRect;
} #pragma mark -- 重置文字区域
- (CGRect)textRectForBounds:(CGRect)bounds {
CGRect textRect = [super textRectForBounds:bounds]; return textRect;
}
*/ #pragma mark -- 重置placeholder
- (CGRect)placeholderRectForBounds:(CGRect)bounds {
CGRect placeholderRect = [super placeholderRectForBounds:bounds];
/**
* 使placeholder居右
*/
CGFloat placeholderWidth = [self.placeholder boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:_placeholderFont} context:nil].size.width;
placeholderRect.origin.x += placeholderRect.size.width-placeholderWidth-;
return placeholderRect;
} #pragma mark -- 重置编辑区域
- (CGRect)editingRectForBounds:(CGRect)bounds {
CGRect editingRect = [super editingRectForBounds:bounds];
return editingRect;
} #pragma mark -- 重置删除按钮区域
- (CGRect)clearButtonRectForBounds:(CGRect)bounds {
CGRect clearButtonRect = [super clearButtonRectForBounds:bounds]; return clearButtonRect;
} #pragma mark -- 重置左视图区域
- (CGRect)leftViewRectForBounds:(CGRect)bounds {
CGRect leftViewRect = [super leftViewRectForBounds:bounds];
leftViewRect.origin.x += ;
return leftViewRect;
} #pragma mark -- 重置右视图区域
- (CGRect)rightViewRectForBounds:(CGRect)bounds {
CGRect rightViewRect = [super rightViewRectForBounds:bounds]; return rightViewRect;
} #pragma mark -- 重绘文字(这个方法他成为第一响应者之后才调用的)
- (void)drawTextInRect:(CGRect)rect {
[super drawTextInRect:rect];
self.textColor = [UIColor purpleColor];
} #pragma mark -- 重绘placeholder
- (void)drawPlaceholderInRect:(CGRect)rect {
[super drawPlaceholderInRect:rect];
/**
* 调用kvo修改系统的_placeholderLabel的属性
*/
[self setValue:_placeholderColor forKeyPath:@"_placeholderLabel.textColor"];
[self setValue:_placeholderFont forKeyPath:@"_placeholderLabel.font"];
}

iOS开发之自定义输入框(利用UITextField及UITextView)的更多相关文章

  1. IOS开发之自定义系统弹出键盘上方的view(转载)

    这篇文章解决的一个开发中的实际问题就是:当弹出键盘时,自定义键盘上方的view.目前就我的经验来看,有两种解决方法.一个就是利用UITextField或者UITextView的inputAccesso ...

  2. iOS开发之自定义表情键盘(组件封装与自动布局)

    下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有MVC, iOS开发中的自动布局,自定义组件的封装与使用,Block回调,CoreData的使用.有的小伙伴可能会问写一个自 ...

  3. 详解iOS开发之自定义View

    iOS开发之自定义View是本文要将介绍的内容,iOS SDK中的View是UIView,我们可以很方便的自定义一个View.创建一个 Window-based Application程序,在其中添加 ...

  4. 【Swift】IOS开发中自定义转场动画

    在IOS开发中,我们model另外一个控制器的时候,一般都使用默认的转场动画. 其实我们可以自定义一些转场动画.达到不同的转场效果. 步骤如下:(photoBrowser是目标控制器) 1.在源控制器 ...

  5. IOS开发-UI学习-UITextField的各种属性设置

    UITextField是IOS中非常常用的一个控件,用来接收用户输入信息,完成应用和用户的交互.它的主要属性设置如下: //初始化textfield并设置位置及大小 UITextField *text ...

  6. iOS开发-UITableView自定义Cell

    UITableView在iOS中开发的重要地位是毋庸置疑的,基本上应用中用到的比例是一半左右,而且大部分情况都是需要自定义单元格的,这样用户看到的App才能更有美感.之前写过UITableView的基 ...

  7. iOS开发之自定义导航栏返回按钮右滑返回手势失效的解决

    我相信针对每一个iOS开发者来说~除了根视图控制器外~所有的界面通过导航栏push过去的界面都是可以通过右滑来返回上一个界面~其实~在很多应用和APP中~用户已经习惯了这个功能~然而~作为开发者的我们 ...

  8. IOS开发-UI学习-UITextField的具体属性及用法

    直接上代码,里面有各种属性的用法注释,至于每个属性有多个可以设置的值,每个值的效果如何,可以通过查看这个函数参数的枚举量,并逐一测试. //制作登陆界面 #import "ViewContr ...

  9. ios开发之自定义textView

    自定义textView,从理论上讲很简单,根据需求自定义,比如我在开发中的需求就是现实一个字数的限制以及根据输入的文字改变提示剩余字数,那么开始我的基本思路就是自定义一个View,而里面包含一个子控件 ...

随机推荐

  1. Android系统移植与驱动开发——第五章--搭建开发板的测试环境

    开发板上安装嵌入式系统要比手机上简洁很多,有很多扩展的接口,适合对程序进行测试,这里所提及的是S3C6410开发板.它是由三星公司推出的一款低功耗/高性价比的RISC处理器.,其中包含强大的硬件加速器 ...

  2. BestCoder冠军赛 - 1009 Exploration 【Tarjan+并查集缩点】

    [题意] 给一个图,这个图中既有有向边,又有无向边,每条边只能走一次,问图中是否存在环. 最多10^6个点,10^6个无向边,10^6个有向边 [题解] 因为既有有向边又有无向边,所以不能单纯的用ta ...

  3. gridview动态添加列的问题

    相信大家也和我一样遇到过这种问题,gridview在生成列的时候当列不确定怎么办?下面分享一下自己的解决方法. 举个列子说明一下. 普通列的添加比较简单. BoundField bf = new Bo ...

  4. Java序列化的机制和原理

    Java序列化的机制和原理 本文讲解了Java序列化的机制和原理.从文中你可以了解如何序列化一个对象,什么时候需要序列化以及Java序列化的算法. 有关Java对象的序列化和反序列化也算是Java基础 ...

  5. Eclipse怎么忽略掉报错的js文件

    第一步,我们要先定位错误在哪里,选择菜单里window——show view——other,选择Problems. 第二步,点击有红叉的项目,在Problems视图中,可以看到是什么错,哪个文件夹中的 ...

  6. VS2012 ActiveX控件_D接口添加方法事项

    自己写的是Clock控件,所以控件的接口是_DClock 使用向导添加方法后,会在紫色区域自动生成红色代码:(添加Hello方法) dispinterface _DClock { properties ...

  7. rhel-server-6.2-i386安装gcc、g++步骤

    安装的版本:rhel-server-6.2-i386 RHEL 6.2默认是没有gcc和gcc-c++环境的,而且我也没有$购买正版服务.只能本地安装了,总结方法如下: 上传安装镜像rhel-serv ...

  8. 每日一算法【one】

    //有一个数组  {1,2,3,4,5,6,7,8,9,12,13,45,67,89,99,101,111,123,134,565,677} 查找数组中是否有指定的某一个数. /** *------- ...

  9. jQuery判断浏览器

    在jQuery1.9版本之前,jQuery 提供了 browser 标记 <script type="text/javascript" src="http://aj ...

  10. thinkphp ajax 实例 实现

    thinkPHP后台实现 #删除用户操作      function delete()      {        if(isset($_SERVER["HTTP_X_REQUESTED_W ...