如何获取uitextfield如何换行中的内容

使用UITextField限制只可输入中,英文,数字的方法
作者:辛多雷的挽歌
字体:[ ] 类型:转载 时间:
在我们日常开发中经常遇到一些情况,要UITextField只能输入某一种特定的字符.比如大写A-Z或者小写a-z,或者汉字.或者数字.那么该如何实现呢,下面通过这篇文章来看看吧。
本文主要介绍使用UITextField限制只可输入中,英文,数字,我们可以使用NSPredicate正则表达式可以过滤,下面看看详细的步骤方法
首先设置UItextField的代理
实现如下方法:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if ([self isInputRuleAndNumber:string] || [string isEqualToString:@""]) {
return YES;
return NO;
然后添加事件,因为选择输入法联想的词.是不会经过textField:shouldChangeCharactersInRange:replacementString:方法的
[textField addTarget:self action:@selector(textFieldChanged:) forControlEvents:UIControlEventEditingChanged];
- (void)textFieldChanged:(UITextField *)textField {
NSString *toBeString = textField.
NSString *lastS
if(toBeString.length&0)
lastString=[toBeString substringFromIndex:toBeString.length-1];
if (![self isInputRuleAndNumber:toBeString]&&[self hasEmoji:lastString]) {
textField.text = [self disable_emoji:toBeString];
NSString *lang = [[textField textInputMode] primaryLanguage];
if([lang isEqualToString:@"zh-Hans"]) {
UITextRange *selectedRange = [textField markedTextRange];
UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
if(!position) {
NSString *getStr = [self getSubString:toBeString];
if(getStr && getStr.length & 0) {
textField.text = getS
NSString *getStr = [self getSubString:toBeString];
if(getStr && getStr.length & 0) {
textField.text= getS
再来实现限制:
pattern中,输入需要验证的通过的字符
&&&& 小写a-z
&&&& 大写A-Z
&&&& 汉字\u4E00-\u9FA5
&&&& 数字\u0030-\u0039
- (BOOL)isInputRuleAndNumber:(NSString *)str {
NSString *pattern = @"[a-zA-Z\u4E00-\u9FA5\\u0030-\\u0039]";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
BOOL isMatch = [pred evaluateWithObject:str];
return isM
实现判断是否是Emoji
- (BOOL)hasEmoji:(NSString*)str{
NSString *pattern = @"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
BOOL isMatch = [pred evaluateWithObject:str];
return isM
#define kMaxLength 20;
-(NSString *)getSubString:(NSString*)string
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_);
NSData* data = [string dataUsingEncoding:encoding];
NSInteger length = [data length];
if (length & kMaxLength) {
NSData *data1 = [data subdataWithRange:NSMakeRange(0, kMaxLength)];
NSString *content = [[NSString alloc] initWithData:data1 encoding:encoding];
if (!content || content.length == 0) {
data1 = [data subdataWithRange:NSMakeRange(0, kMaxLength - 1)];
content = [[NSString alloc] initWithData:data1 encoding:encoding];
以上就是这篇文章的全部内容了,希望能对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具iOS6下UITextField退格变清空问题的解决方法 - 推酷
iOS6下UITextField退格变清空问题的解决方法
自己的项目中一直有一个必现的UITextField退格变清空问题,测试发现只有iOS6下有,其它iOS版本都没有问题,基本上可以确定与iOS6有关。由于问题不是很大又忙就搁置了很久,今天实在不能忍受便花了点时间解决此问题,记录一下吧。
这个问题是在某个有默认值的UITextField上是必现的,一旦用退格键删除最后一个字符或中间某个字符,整个UITextfield的内容被清空了,一直百思不得其解,google了一下发现有人遇到类似的问题,并给出了复现步骤(
有一个secureTextEntry为Yes的UITextField和 一个普通的UITextField,重现步骤:
1. 点击普通的UITextField输入类容,
2. 点击密码UITextField输入内容,
3. 点击普通的UITextField重新获得焦点,
4. 接着点击键盘上的退格键,
结果:这时会发现普通的UITextField被清空了。
测试了一下,随便找一个有用户名与密码登录页面的应用,在iOS6下就会复现出这个问题,比如iPhone自带的邮件app。但这个重现步骤说得并不准确,第1步和第2步的前提是对应的UITextField已经有内容,虽然跟自己的复现方法有点不一样,不过总算知道这个问题是怎么回事了。怎么说呢,这应该是iOS6的UITextField的一个新特性引入的问题,原文把这个问题称之为“iOS 6 Secure密码UITextField造成非密码UITextField退格清空Bug”,但是iOS6.0就有这个问题,iOS6.1.3都没有解决,估计apple没把它当bug,坑爹啊。
咱们拿apple没办法,那就只有想办法绕过去啊,初步的思路是截获退格键删除行为,每点一次退格键删除时只允许删除一个字符。这就要用到UITextFieldDelegate的一个textField:shouldChangeCharactersInRange:replacementString方法,这个方法是在UITextField的内容改变时调用,第二个参数表明内容改变的范围,第三个参数是替代的字符串。代码如下:
Here’s Code
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
if (range.location & 0 && range.length == 1 && string.length == 0)
textField.text = [textField.text substringToIndex:textField.text.length - 1];
return NO;
return YES;
设置一下UITextField的delegate就可以调用到此方法,range.length == 1 && string.length == 0就是删除一个字符时所满足的条件,如果条件满足,就只让textField的内容减少一个字符。初步测试,可以解决退格变清空的问题,但是又带来另一个问题:如果是在文字中间点退格键删除文字,就变成从文字的最后删除一个字符。这并不是我们想要的,怎么办呢,那就要找到删除的字符的位置,这个
里给了一个终极解决办法,代码如下:
Here’s Code
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
if (range.location & 0 && range.length == 1 && string.length == 0)
// Stores cursor position
UITextPosition *beginning = textField.beginningOfDocument;
UITextPosition *start = [textField positionFromPosition:beginning offset:range.location];
NSInteger cursorOffset = [textField offsetFromPosition:beginning toPosition:start] + string.length;
// Save the current text, in case iOS deletes the whole text
NSString *text = textField.text;
// Trigger deletion
[textField deleteBackward];
// iOS deleted the entire string
if (textField.text.length != text.length - 1)
textField.text = [text stringByReplacingCharactersInRange:range withString:string];
// Update cursor position
UITextPosition *newCursorPosition = [textField positionFromPosition:textField.beginningOfDocument offset:cursorOffset];
UITextRange *newSelectedRange = [textField textRangeFromPosition:newCursorPosition toPosition:newCursorPosition];
[textField setSelectedTextRange:newSelectedRange];
return NO;
return YES;
思路是先取到光标位置,把文本内容暂存,清空原来UITextField的内容,然后将暂存的文本内容中光标左侧的文字replace掉重新赋给UITextField,并恢复光标位置,难点在于怎么获取光标位置与恢复光标位置。
一般用到用户名与密码UITextField的地方用这个方法就能解决问题了,只是还有点小问题,即如果不是从中间删除一个字符,而是一次删除若干个字符还是有问题的,这是由if中的range.length == 1条件限制的,稍加改造下应该就能解决。另外一个问题是如果有中文字符或其它UTF8字符,估计得考虑一下是不是应该要用“text.length – 1”,不过能有多少应用的用户名或密码带中文呢
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致UITextField 的那点事 - IOS - 伯乐在线
& UITextField 的那点事
UITextField被用作项目中获取用户信息的重要控件,但是在实际应用中存在的不少的坑:修改keyboardType来限制键盘的类型,却难以限制第三方键盘的输入类型;在代理中限制了输入长度以及输入的文本类型,但是却抵不住中文输入的联想;键盘弹起时遮住输入框,需要接收键盘弹起收回的通知,然后计算坐标实现移动动画。
对于上面这些问题,苹果提供给我们文本输入框的同时并不提供解决方案,因此本文将使用category+runtime的方式解决上面提到的这些问题,本文假设读者已经清楚从UITextField成为第一响应者到结束编辑过程中的事件调用流程。
最常见的输入限制是手机号码以及金额,前者文本中只能存在纯数字,后者文本中还能包括小数。笔者暂时定义了三种枚举状态用来表示三种文本限制:
typedef NS_ENUM(NSInteger, LXDRestrictType)
LXDRestrictTypeOnlyNumber = 1,
///& 只允许输入数字
LXDRestrictTypeOnlyDecimal = 2,
只允许输入实数,包括.
LXDRestrictTypeOnlyCharacter = 3,
只允许非中文输入
typedef NS_ENUM(NSInteger, LXDRestrictType){&&&&LXDRestrictTypeOnlyNumber = 1,&&&&&&///& 只允许输入数字&&&&LXDRestrictTypeOnlyDecimal = 2,&&&& ///&&&只允许输入实数,包括.&&&&LXDRestrictTypeOnlyCharacter = 3,&&///&&&只允许非中文输入};
在文本输入的时候会有两次回调,一次是代理的replace的替换文本方法,另一个需要我们手动添加的EditingChanged编辑改变事件。前者在中文联想输入的时候无法准确获取文本内容,而当确认好输入的文本之后才会调用后面一个事件,因此回调后一个事件才能准确的筛选文本。下面的代码会筛选掉文本中所有的非数字:
- (void)viewDidLoad
[textField addTarget: self action: @selector(textDidChanged:) forControlEvents: UIControlEventEditingChanged];
- (void)textDidChanged: (UITextField *)textField
NSMutableString * modifyText = textField.text.mutableC
for (NSInteger idx = 0; idx
- (void)viewDidLoad{&&&&[textField addTarget: self action: @selector(textDidChanged:) forControlEvents: UIControlEventEditingChanged];}&- (void)textDidChanged: (UITextField *)textField{&&&&NSMutableString * modifyText = textField.text.mutableCopy;&&&&for (NSInteger idx = 0; idx
如果说我们每次需要限制输入的时候都加上这么一段代码也是有够糟的,那么如何将这个功能给封装出来并且实现自定义的限制扩展呢?笔者通过工厂来完成这一个功能,每一种文本的限制对应一个单独的类。抽象提取出一个父类,只提供一个文本变化的实现接口和一个限制最长输入的NSUInteger整型属性:
#pragma mark - h文件
@interface LXDTextRestrict : NSObject
@property (nonatomic, assign) NSUInteger maxL
@property (nonatomic, readonly) LXDRestrictType restrictT
+ (instancetype)textRestrictWithRestrictType: (LXDRestrictType)restrictT
// 子类实现来限制文本内容
- (void)textDidChanged: (UITextField *)textF
#pragma mark - 继承关系
@interface LXDTextRestrict ()
@property (nonatomic, readwrite) LXDRestrictType restrictT
@interface LXDNumberTextRestrict : LXDTextRestrict
@interface LXDDecimalTextRestrict : LXDTextRestrict
@interface LXDCharacterTextRestrict : LXDTextRestrict
#pragma mark - 父类实现
@implementation LXDTextRestrict
+ (instancetype)textRestrictWithRestrictType: (LXDRestrictType)restrictType
LXDTextRestrict * textR
switch (restrictType) {
case LXDRestrictTypeOnlyNumber:
textRestrict = [[LXDNumberTextRestrict alloc] init];
case LXDRestrictTypeOnlyDecimal:
textRestrict = [[LXDDecimalTextRestrict alloc] init];
case LXDRestrictTypeOnlyCharacter:
textRestrict = [[LXDCharacterTextRestrict alloc] init];
textRestrict.maxLength = NSUIntegerM
textRestrict.restrictType = restrictT
return textR
- (void)textDidChanged: (UITextField *)textField
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
#pragma mark - h文件@interface LXDTextRestrict : NSObject&@property (nonatomic, assign) NSUInteger maxLength;@property (nonatomic, readonly) LXDRestrictType restrictType;&// 工厂+ (instancetype)textRestrictWithRestrictType: (LXDRestrictType)restrictType;// 子类实现来限制文本内容- (void)textDidChanged: (UITextField *)textField;&@end&&#pragma mark - 继承关系@interface LXDTextRestrict ()&@property (nonatomic, readwrite) LXDRestrictType restrictType;&@end&@interface LXDNumberTextRestrict : LXDTextRestrict@end&@interface LXDDecimalTextRestrict : LXDTextRestrict@end&@interface LXDCharacterTextRestrict : LXDTextRestrict@end&#pragma mark - 父类实现@implementation LXDTextRestrict&+ (instancetype)textRestrictWithRestrictType: (LXDRestrictType)restrictType{&&&&LXDTextRestrict * textRestrict;&&&&switch (restrictType) {&&&&&&&&case LXDRestrictTypeOnlyNumber:&&&&&&&&&&&&textRestrict = [[LXDNumberTextRestrict alloc] init];&&&&&&&&&&&&break;&&&&&&&&&case LXDRestrictTypeOnlyDecimal:&&&&&&&&&&&&textRestrict = [[LXDDecimalTextRestrict alloc] init];&&&&&&&&&&&&break;&&&&&&&&&case LXDRestrictTypeOnlyCharacter:&&&&&&&&&&&&textRestrict = [[LXDCharacterTextRestrict alloc] init];&&&&&&&&&&&&break;&&&&&&&&&default:&&&&&&&&&&&&break;&&&&}&&&&textRestrict.maxLength = NSUIntegerMax;&&&&textRestrict.restrictType = restrictType;&&&&return textRestrict;}&- (void)textDidChanged: (UITextField *)textField{&}&@end
由于子类在筛选的过程中都存在遍历字符串以及正则表达式验证的流程,把这一部分代码逻辑给封装起来。根据EOC的原则优先使用static inline的内联函数而非宏定义:
typedef BOOL(^LXDStringFilter)(NSString * aString);
static inline NSString * kFilterString(NSString * handleString, LXDStringFilter subStringFilter)
NSMutableString * modifyString = handleString.mutableC
for (NSInteger idx = 0; idx & modifyString.) {
NSString * subString = [modifyString substringWithRange: NSMakeRange(idx, 1)];
if (subStringFilter(subString)) {
[modifyString deleteCharactersInRange: NSMakeRange(idx, 1)];
return modifyS
static inline BOOL kMatchStringFormat(NSString * aString, NSString * matchFormat)
NSPredicate * predicate = [NSPredicate predicateWithFormat: @"SELF MATCHES %@", matchFormat];
return [predicate evaluateWithObject: aString];
#pragma mark - 子类实现
@implementation LXDNumberTextRestrict
- (void)textDidChanged: (UITextField *)textField
textField.text = kFilterString(textField.text, ^BOOL(NSString *aString) {
return kMatchStringFormat(aString, @"^\\d$");
@implementation LXDDecimalTextRestrict
- (void)textDidChanged: (UITextField *)textField
textField.text = kFilterString(textField.text, ^BOOL(NSString *aString) {
return kMatchStringFormat(aString, @"^[0-9.]$");
@implementation LXDCharacterTextRestrict
- (void)textDidChanged: (UITextField *)textField
textField.text = kFilterString(textField.text, ^BOOL(NSString *aString) {
return kMatchStringFormat(aString, @"^[^[\\u4e00-\\u9fa5]]$");
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
typedef BOOL(^LXDStringFilter)(NSString * aString);static inline NSString * kFilterString(NSString * handleString, LXDStringFilter subStringFilter){&&&&NSMutableString * modifyString = handleString.mutableCopy;&&&&for (NSInteger idx = 0; idx & modifyString.length;) {&&&&&&&&NSString * subString = [modifyString substringWithRange: NSMakeRange(idx, 1)];&&&&&&&&if (subStringFilter(subString)) {&&&&&&&&&&&&idx++;&&&&&&&&} else {&&&&&&&&&&&&[modifyString deleteCharactersInRange: NSMakeRange(idx, 1)];&&&&&&&&}&&&&}&&&&return modifyString;}&static inline BOOL kMatchStringFormat(NSString * aString, NSString * matchFormat){&&&&NSPredicate * predicate = [NSPredicate predicateWithFormat: @"SELF MATCHES %@", matchFormat];&&&&return [predicate evaluateWithObject: aString];}&&#pragma mark - 子类实现@implementation LXDNumberTextRestrict&- (void)textDidChanged: (UITextField *)textField{&&&&textField.text = kFilterString(textField.text, ^BOOL(NSString *aString) {&&&&&&&&return kMatchStringFormat(aString, @"^\\d$");&&&&});}&@end&@implementation LXDDecimalTextRestrict&- (void)textDidChanged: (UITextField *)textField{&&&&textField.text = kFilterString(textField.text, ^BOOL(NSString *aString) {&&&&&&&&return kMatchStringFormat(aString, @"^[0-9.]$");&&&&});}&@end&@implementation LXDCharacterTextRestrict&- (void)textDidChanged: (UITextField *)textField{&&&&textField.text = kFilterString(textField.text, ^BOOL(NSString *aString) {&&&&&&&&return kMatchStringFormat(aString, @"^[^[\\u4e00-\\u9fa5]]$");&&&&});}&@end
有了文本限制的类,那么接下来我们需要新建一个UITextField的分类来添加输入限制的功能,主要新增三个属性:
@interface UITextField (LXDRestrict)
/// 设置后生效
@property (nonatomic, assign) LXDRestrictType restrictT
/// 文本最长长度
@property (nonatomic, assign) NSUInteger maxTextL
/// 设置自定义的文本限制
@property (nonatomic, strong) LXDTextRestrict * textR
12345678910
@interface UITextField (LXDRestrict)&/// 设置后生效@property (nonatomic, assign) LXDRestrictType restrictType;/// 文本最长长度@property (nonatomic, assign) NSUInteger maxTextLength;/// 设置自定义的文本限制@property (nonatomic, strong) LXDTextRestrict * textRestrict;&@end
由于这些属性是category中添加的,我们需要手动生成getter和setter方法,这里使用objc_associate的动态绑定机制来实现。其中核心的方法实现如下:
- (void)setRestrictType: (LXDRestrictType)restrictType
objc_setAssociatedObject(self, LXDRestrictTypeKey, @(restrictType), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
self.textRestrict = [LXDTextRestrict textRestrictWithRestrictType: restrictType];
- (void)setTextRestrict: (LXDTextRestrict *)textRestrict
if (self.textRestrict) {
[self removeTarget: self.text action: @selector(textDidChanged:) forControlEvents: UIControlEventEditingChanged];
textRestrict.maxLength = self.maxTextL
[self addTarget: textRestrict action: @selector(textDidChanged:) forControlEvents: UIControlEventEditingChanged];
objc_setAssociatedObject(self, LXDTextRestrictKey, textRestrict, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
123456789101112131415
- (void)setRestrictType: (LXDRestrictType)restrictType{&&&&objc_setAssociatedObject(self, LXDRestrictTypeKey, @(restrictType), OBJC_ASSOCIATION_RETAIN_NONATOMIC);&&&&self.textRestrict = [LXDTextRestrict textRestrictWithRestrictType: restrictType];}&- (void)setTextRestrict: (LXDTextRestrict *)textRestrict{&&&&if (self.textRestrict) {&&&&&&&&[self removeTarget: self.text action: @selector(textDidChanged:) forControlEvents: UIControlEventEditingChanged];&&&&}&&&&textRestrict.maxLength = self.maxTextLength;&&&&[self addTarget: textRestrict action: @selector(textDidChanged:) forControlEvents: UIControlEventEditingChanged];&&&&objc_setAssociatedObject(self, LXDTextRestrictKey, textRestrict, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}
完成这些工作之后,只需要一句代码就可以完成对UITextField的输入限制:
self.textField.restrictType = LXDRestrictTypeOnlyD
self.textField.restrictType = LXDRestrictTypeOnlyDecimal;
自定义的限制
假如现在文本框限制只允许输入emoji表情,上面三种枚举都不存在我们的需求,这时候自定义一个子类来实现这个需求。
@interface LXDEmojiTextRestrict : LXDTextRestrict
@implementation LXDEmojiTextRestrict
- (void)textDidChanged: (UITextField *)textField
NSMutableString * modifyString = textField.text.mutableC
for (NSInteger idx = 0; idx & modifyString.) {
NSString * subString = [modifyString substringWithRange: NSMakeRange(idx, 1)];
NSString * emojiExp = @"^[\\ud83c\\udc00-\\ud83c\\udfff]|[\\ud83d\\udc00-\\ud83d\\udfff]|[\\u2600-\\u27ff]$";
NSPredicate * predicate = [NSPredicate predicateWithFormat: @"SELF MATCHES %@", emojiExp];
if ([predicate evaluateWithObject: subString]) {
[modifyString deleteCharactersInRange: NSMakeRange(idx, 1)];
textField.text = modifyS
1234567891011121314151617181920212223
@interface LXDEmojiTextRestrict : LXDTextRestrict&@end&@implementation LXDEmojiTextRestrict&- (void)textDidChanged: (UITextField *)textField{&&&&NSMutableString * modifyString = textField.text.mutableCopy;&&&&for (NSInteger idx = 0; idx & modifyString.length;) {&&&&&&&&NSString * subString = [modifyString substringWithRange: NSMakeRange(idx, 1)];&&&&&&&&NSString * emojiExp = @"^[\\ud83c\\udc00-\\ud83c\\udfff]|[\\ud83d\\udc00-\\ud83d\\udfff]|[\\u2600-\\u27ff]$";&&&&&&&&NSPredicate * predicate = [NSPredicate predicateWithFormat: @"SELF MATCHES %@", emojiExp];&&&&&&&&if ([predicate evaluateWithObject: subString]) {&&&&&&&&&&&&idx++;&&&&&&&&} else {&&&&&&&&&&&&[modifyString deleteCharactersInRange: NSMakeRange(idx, 1)];&&&&&&&&}&&&&}&&&&textField.text = modifyString;}&@end
代码中的emoji的正则表达式还不全,因此在实践中很多的emoji点击会被筛选掉。效果如下:
另一个让人头疼的问题就是输入框被键盘遮挡。这里通过在category中添加键盘相关通知来完成移动整个window。其中通过下面这个方法获取输入框在keyWindow中的相对坐标:
- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view
- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view
我们给输入框提供一个设置自动适应的接口:
@interface UITextField (LXDAdjust)
/// 自动适应
- (void)setAutoAdjust: (BOOL)autoA
@implementation UITextField (LXDAdjust)
- (void)setAutoAdjust: (BOOL)autoAdjust
if (autoAdjust) {
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: self];
- (void)keyboardWillShow: (NSNotification *)notification
if (self.isFirstResponder) {
CGPoint relativePoint = [self convertPoint: CGPointZero toView: [UIApplication sharedApplication].keyWindow];
CGFloat keyboardHeight = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.
CGFloat actualHeight = CGRectGetHeight(self.frame) + relativePoint.y + keyboardH
CGFloat overstep = actualHeight - CGRectGetHeight([UIScreen mainScreen].bounds) + 5;
if (overstep & 0) {
CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = [UIScreen mainScreen].
frame.origin.y -=
[UIView animateWithDuration: duration delay: 0 options: UIViewAnimationOptionCurveLinear animations: ^{
[UIApplication sharedApplication].keyWindow.frame =
} completion: nil];
- (void)keyboardWillHide: (NSNotification *)notification
if (self.isFirstResponder) {
CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = [UIScreen mainScreen].
[UIView animateWithDuration: duration delay: 0 options: UIViewAnimationOptionCurveLinear animations: ^{
[UIApplication sharedApplication].keyWindow.frame =
} completion: nil];
- (void)dealloc
[[NSNotificationCenter defaultCenter] removeObserver: self];
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
@interface UITextField (LXDAdjust)&/// 自动适应- (void)setAutoAdjust: (BOOL)autoAdjust;&@end&@implementation UITextField (LXDAdjust)&- (void)setAutoAdjust: (BOOL)autoAdjust{&&&&if (autoAdjust) {&&&&&&&&[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object: nil];&&&&&&&&[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object: nil];&&&&} else {&&&&&&&&[[NSNotificationCenter defaultCenter] removeObserver: self];&&&&}}&- (void)keyboardWillShow: (NSNotification *)notification{&&&&if (self.isFirstResponder) {&&&&&&&&CGPoint relativePoint = [self convertPoint: CGPointZero toView: [UIApplication sharedApplication].keyWindow];&&&&&&&&&CGFloat keyboardHeight = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height;&&&&&&&&CGFloat actualHeight = CGRectGetHeight(self.frame) + relativePoint.y + keyboardHeight;&&&&&&&&CGFloat overstep = actualHeight - CGRectGetHeight([UIScreen mainScreen].bounds) + 5;&&&&&&&&if (overstep & 0) {&&&&&&&&&&&&CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];&&&&&&&&&&&&CGRect frame = [UIScreen mainScreen].bounds;&&&&&&&&&&&&frame.origin.y -= overstep;&&&&&&&&&&&&[UIView animateWithDuration: duration delay: 0 options: UIViewAnimationOptionCurveLinear animations: ^{&&&&&&&&&&&&&&&&[UIApplication sharedApplication].keyWindow.frame = frame;&&&&&&&&&&&&} completion: nil];&&&&&&&&}&&&&}}&- (void)keyboardWillHide: (NSNotification *)notification{&&&&if (self.isFirstResponder) {&&&&&&&&CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];&&&&&&&&CGRect frame = [UIScreen mainScreen].bounds;&&&&&&&&[UIView animateWithDuration: duration delay: 0 options: UIViewAnimationOptionCurveLinear animations: ^{&&&&&&&&&&&&[UIApplication sharedApplication].keyWindow.frame = frame;&&&&&&&&} completion: nil];&&&&}}&- (void)dealloc{&&&&[[NSNotificationCenter defaultCenter] removeObserver: self];}&@end
如果项目中存在自定义的UITextField子类,那么上面代码中的dealloc你应该使用method_swillzing来实现释放通知的作用
其实大多数时候,实现某些小细节功能只是很简单的一些代码,但是需要我们去了解事件响应的整套逻辑来更好的完成它。另外,昨天给微信小程序刷屏了,我想对各位iOS开发者说与其当心自己的饭碗是不是能保住,不如干好自己的活,顺带学点js适应一下潮流才是王道。
关于作者:
可能感兴趣的话题
不能限制联想或者是输入文字的长度吗?
关于iOS频道
iOS频道分享iOS和Swift开发,应用设计和推广,iOS相关的行业动态。
新浪微博:
推荐微信号
(加好友请注明来意)
– 好的话题、有启发的回复、值得信赖的圈子
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选文章
– UI,网页,交互和用户体验
– 专注iOS技术分享
– 专注Android技术分享
– JavaScript, HTML5, CSS
– 专注Java技术分享
– 专注Python技术分享
& 2017 伯乐在线

我要回帖

更多关于 uitextfield 内容偏移 的文章

 

随机推荐