UITextfield

#import "ViewController.h"
@interface ViewController ()<UITextFieldDelegate>
@property (nonatomic, strong) UIView  * containerView;//背景View
@property (nonatomic, assign) CGFloat   originalY;//原始纵坐标
@property (nonatomic, assign) CGFloat   containerViewHeight;//原始高度

@property (nonatomic, strong) UITextField * account;//账号输入框
@property (nonatomic, strong) UITextField * password;//密码输入框
@property (nonatomic, strong) UIButton    * commitButton;//提交按钮
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self creatBgView];
    
    [self createOneAccountView];
    
    [self createOnePasswordView];
    
    [self createOneButton];

    [self registerKeyboardNotification];
   
}

#pragma mark - 创建一个背景View
-(void)creatBgView{
    UIView * containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 280, 300)];
    self.containerView = containerView;
    containerView.backgroundColor = [UIColor darkGrayColor];
    containerView.center = self.view.center;
    [self.view addSubview:containerView];
    
    //记录下container的原始纵坐标和高度 这一步很关键后面后用到这里的数据
    CGFloat originalY = self.containerView.frame.origin.y;
    self.originalY = originalY;
    
    CGFloat containerViewHeight    = self.containerView.frame.size.height;
    self.containerViewHeight = containerViewHeight;
}


#pragma mark - 创建一个账号输入框
-(void)createOneAccountView{
    UITextField * account = [[UITextField alloc] initWithFrame:CGRectMake(40, 80, 200, 40)];
    self.account = account;
    self.account.delegate = self;
//一、显示相关设置
    //1、背景颜色设置
    account.backgroundColor = [UIColor redColor];
    
    //2、背景图片设置
    account.background = [UIImage imageNamed:@""];
    
    /*
     3、边框样式设置
     UITextBorderStyleNone,       //无边框效果
     UITextBorderStyleLine,       //黑色实线边框
     UITextBorderStyleBezel,      //灰色实线边框
     UITextBorderStyleRoundedRect //圆角矩形边框
     */
    account.borderStyle = UITextBorderStyleRoundedRect;
    
    //4、左侧头视图设置
    //左侧头试图 x y值无效果
    UIView *leftView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 10, 40)];
    //clearColor 将衍射设为透明颜色 可用来调节光标的位置
    leftView.backgroundColor = [UIColor blueColor];
    //设置什么时候显示
    account.leftViewMode = UITextFieldViewModeAlways;
    account.leftView = leftView;
    
    
    //5、右侧头视图设置
    //右侧头视图 x y值无效果
    UIView *rightView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 10, 40)];
    //设置颜色
    rightView.backgroundColor = [UIColor blueColor];
    //设置什么时候显示
    account.rightViewMode = UITextFieldViewModeAlways;
    account.rightView = rightView;


    
//二、文字设置
    //1、占位文字设置
    account.placeholder = @"请输入账号";
    
    //2、内容设置,比如设置自动填充。
    account.text = @"内容设置";
    
    //3、内容是否以密文形式显示
//    account.secureTextEntry = YES;
    
    //4、重新编辑时是否自动清除内容
    account.clearsOnBeginEditing = YES;
    
    /*
     5、删除按钮显示设置
     UITextFieldViewModeNever,              //清除按钮不可见
     UITextFieldViewModeWhileEditing,       //编辑内容时清除按钮可见
     UITextFieldViewModeUnlessEditing,      //除了编辑之外,清除按钮都可见
     UITextFieldViewModeAlways              //清除按钮一直可见
     */
    //疑问1:UITextFieldViewModeUnlessEditing为什么设置这个没有效果
    account.clearButtonMode = UITextFieldViewModeWhileEditing;
    
    //6、这两个属性配合使用,一个用来设置字体自动适应,一个用来设置允许最小的字体
    account.adjustsFontSizeToFitWidth = YES;
    account.minimumFontSize = 10;
    
    /*
     7、字母大小写自动转换
     UITextAutocapitalizationTypeNone,              //无自动转换
     UITextAutocapitalizationTypeWords,             //首字母自动转大写
     UITextAutocapitalizationTypeSentences,         //每个句子的首字母转大写
     UITextAutocapitalizationTypeAllCharacters,     //所有字母自动转大写
     */
    account.autocapitalizationType = UITextAutocapitalizationTypeSentences;
    
    
    /*
     8、输入文字时自动更正提示框
     UITextAutocorrectionTypeDefault,
     UITextAutocorrectionTypeNo,
     UITextAutocorrectionTypeYes,
     */
    account.autocorrectionType = UITextAutocorrectionTypeDefault;
    
    //9、响应者问题 成为第一响应者 程序进来的时候,光标会在这个输入框内闪烁,也就是已经来到了DidBeginEditing状态
    //设置了代理的话,这个方法会使程序调用 1、2、这两个代理方法
//    [account becomeFirstResponder];
    
    //10、注销第一响应者会结束编辑
    //这个方法会使输入框结束编辑,设置了代理的话,这个方法会使程序调用4、5、这个两个代理方法
    //一般在点击return键的时候会调用这个方法来结束输入框的编辑状态
//    [account resignFirstResponder];
    
    
//三、键盘设置相关
    //1、设置不同的键盘类型
    account.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
    
    //2、返回键的样式
    account.returnKeyType = UIReturnKeyGo;
    //设为yes时 只有当输入内容时return键才可用
    //设为no时,什么时候都可用,不会锁定
//    account.enablesReturnKeyAutomatically = YES;
    
    //3、键盘显示样式
    account.keyboardAppearance = UIKeyboardAppearanceDark;
    
    //4、自定义键盘
    UIView *keyView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 100)];
    keyView.backgroundColor = [UIColor redColor];
    account.inputView = keyView;
    
    //5、自定义二级键盘
    UIView *secondView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 40)];
    secondView.backgroundColor = [UIColor greenColor];
//    account.inputAccessoryView = secondView;
    
    [self.containerView addSubview:account];
}

#pragma mark - 创建一个密码输入框
-(void)createOnePasswordView{
    UITextField * password = [[UITextField alloc] initWithFrame:CGRectMake(40, 140, 200, 40)];
    self.password = password;
    self.password.delegate = self;
    password.backgroundColor = [UIColor lightGrayColor];
    password.placeholder = @"请输入密码";
    password.returnKeyType = UIReturnKeyNext;
    [self.containerView addSubview:password];
}

#pragma mark - 创建一个提交按钮
-(void)createOneButton{
    UIButton * commit = [UIButton buttonWithType:UIButtonTypeCustom];
    commit.frame = CGRectMake(90, self.containerView.frame.size.height-100, 100, 40);
    self.commitButton = commit;
    [commit setTitle:@"提交" forState:UIControlStateNormal];
    commit.backgroundColor = [UIColor redColor];
    [self.containerView addSubview:commit];
}


#pragma mark - 注册键盘通知
-(void)registerKeyboardNotification{

    //1、键盘将要显示
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    
    //2、键盘显示完成
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    
    //3、键盘将要隐藏
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    
    //4、键盘隐藏完成
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
    
    //5、键盘的frame将要变化的通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
    
    //6、键盘的frame变化完成的通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidChangeFrame:) name:UIKeyboardDidChangeFrameNotification object:nil];
    
}


-(void)keyboardWillShow:(NSNotification *)notification{
    //1、键盘将要弹出时调用此方法
    NSDictionary * userInfo = notification.userInfo;
//    NSLog(@"willShowUserInfo = %@",userInfo);
    //通知中各个参数说明
    /*
     UIKeyboardAnimationCurveUserInfoKey = 7;                               //动画样式
     UIKeyboardAnimationDurationUserInfoKey = "0.25";                       //动画时间
     UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {375, 258}}";          //键盘的bounds
     UIKeyboardCenterBeginUserInfoKey = "NSPoint: {187.5, 796}";            //键盘变化开始时的center
     UIKeyboardCenterEndUserInfoKey = "NSPoint: {187.5, 538}";              //键盘变化结束时的center
     UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 667}, {375, 258}}";    //键盘变化开始时的frame
     UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 409}, {375, 258}}";      //键盘变化结束时的frame
     UIKeyboardIsLocalUserInfoKey = 1;                                      //ipad多任务同时运行,所有运行可见的app都会收到键盘通知,调出键盘的app返回的是1,其它app返回的是0

     */
    
    //解决键盘弹出覆盖其它视图的问题
    //键盘高度
    CGRect keyBoardFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    
    CGFloat keyBoardY              = keyBoardFrame.origin.y;                       //键盘y坐标

    //计算平移距离translationY 这里一定要跟container的原始位置尺寸进行比较来计算 否则在两个textFieldView之间进行切换时可能出现问题
    //大于0 证明有间隙
    //等于0 证明刚刚好
    //小于0 证明有覆盖
    CGFloat translationY           = keyBoardY - (self.originalY + self.containerViewHeight);
    NSLog(@"translatinY = %lf",translationY);
    
#if 0 
    //只在被覆盖的情况下才进行平移操作
    if (translationY < 0) {
        self.containerView.transform = CGAffineTransformMakeTranslation(0, translationY);
    }
    else{
        //else这部分代码是不可少的 举个例子:
        //1、第一次键盘弹出view被遮挡,view就会根据translationY进行平移
        //2、第二次键盘弹出时view没被遮挡,view就需要回到原始位置,而不是待在平移后的位置
        //这种情况会出现在 在两个或多个textFieldView之间切换时
        self.containerView.transform = CGAffineTransformIdentity;
    }
    
#elif 0
    //根据键盘的高度进行平移
    if (translationY < 0) {
        //键盘弹出被覆盖 上移
        self.containerView.transform = CGAffineTransformMakeTranslation(0, translationY);
    }
    else if(translationY == 0){
        //刚刚好 就复原到原来位置  同上这部分是不可少的
        #if 0
        self.containerView.transform = CGAffineTransformMakeTranslation(0, 0);
        #else
        self.containerView.transform = CGAffineTransformIdentity;
        #endif
    }
    else{
        //与键盘有间隔 下移
        self.containerView.transform = CGAffineTransformMakeTranslation(0, translationY);
    }
    
#elif 0
    //其实上边的代码完全可以这么写就OK  这里的关键是记录下containerView最原始的位置信息
    self.containerView.transform = CGAffineTransformMakeTranslation(0, translationY);
    
#elif 1
    //通过这种方法也可以达到紧贴键盘的目的  而不用记录原始位置信息
    CGFloat changeY   = self.containerView.frame.origin.y;          //view的实时Y坐标
    CGFloat conHeight = self.containerView.frame.size.height;       //view的高度
    CGFloat keyY      = keyBoardFrame.origin.y;                     //键盘Y坐标
    CGFloat changeTranslationY = keyY- (changeY + conHeight);
    self.containerView.transform = CGAffineTransformTranslate(self.containerView.transform , 0,changeTranslationY);
#endif
    
    
   /*********************************************************************************************************\
     *  PS:重要说明
     *  当在多个textField 之间切换时
     *  点击第一个textField键盘弹出,此时再去点另外一个textFieldView,键盘是不会隐藏后再弹出的,而是一直保持弹出状态。
     *  这个过程中textField的通知方法调用也不会来到keyboardWillHide方法,但会来到keyboardWillShow方法
     *
     *
   \*********************************************************************************************************/

    

}

-(void)keyboardDidShow:(NSNotification *)notification{
    //2、键盘弹出完成时调用此方法
    NSDictionary * userInfo = notification.userInfo;
//    NSLog(@"didShowUserInfo = %@",userInfo);
    /*
     
     UIKeyboardAnimationCurveUserInfoKey = 7;
     UIKeyboardAnimationDurationUserInfoKey = "0.25";
     UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {375, 258}}";
     UIKeyboardCenterBeginUserInfoKey = "NSPoint: {187.5, 796}";
     UIKeyboardCenterEndUserInfoKey = "NSPoint: {187.5, 538}";
     UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 667}, {375, 258}}";
     UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 409}, {375, 258}}";
     UIKeyboardIsLocalUserInfoKey = 1;
     
     */
   
}


-(void)keyboardWillHide:(NSNotification *)notification{
    //3、键盘将要隐藏式调用此方法
    NSDictionary * userInfo = notification.userInfo;
//    NSLog(@"willHideUserInfo = %@",userInfo);
    /*
     UIKeyboardAnimationCurveUserInfoKey = 7;
     UIKeyboardAnimationDurationUserInfoKey = "0.25";
     UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {375, 258}}";
     UIKeyboardCenterBeginUserInfoKey = "NSPoint: {187.5, 538}";
     UIKeyboardCenterEndUserInfoKey = "NSPoint: {187.5, 796}";
     UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 409}, {375, 258}}";
     UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 667}, {375, 258}}";
     UIKeyboardIsLocalUserInfoKey = 1;
     */
    
    self.containerView.transform   = CGAffineTransformIdentity;
}

-(void)keyboardDidHide:(NSNotification *)notification{
    //4、键盘隐藏完成时调用此方法
    NSDictionary * userInfo = notification.userInfo;
//    NSLog(@"didHideUserInfo = %@",userInfo);
    
    /*
     
     UIKeyboardAnimationCurveUserInfoKey = 7;
     UIKeyboardAnimationDurationUserInfoKey = "0.25";
     UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {375, 258}}";
     UIKeyboardCenterBeginUserInfoKey = "NSPoint: {187.5, 538}";
     UIKeyboardCenterEndUserInfoKey = "NSPoint: {187.5, 796}";
     UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 409}, {375, 258}}";
     UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 667}, {375, 258}}";
     UIKeyboardIsLocalUserInfoKey = 1;
     
     */
}

-(void)keyboardWillChangeFrame:(NSNotification *)notification{
    //5、只要键盘的frame发生变化就会来到此方法
   
   
}

-(void)keyboardDidChangeFrame:(NSNotification *)notification{
    //6、键盘的frame变化完成就会来都此方法
   
}

/*********************************************************************************************************\
 *  PS:重要说明
 *  键盘从弹出到隐藏的执行顺序为:
 *  5-1-6-2-5-3-6-4
 *
 *
 *
 \**********************************************************************************************************/

#pragma mark - UITextFieldDelegate
//1、是否允许编辑  yes为允许 no为否
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
    NSLog(@"是否可以开始编辑");
    return YES;
}

//2、已经开始编辑  开始编辑的时候会调用一次
- (void)textFieldDidBeginEditing:(UITextField *)textField{
    NSLog(@"已经开始编辑");
    
    
}


//3、是否允许改变内容
//yes当输入时输入框内容随输入改变 no不会改变
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    //range.location返回的是输入或删除的字符所在的index
    //range.length 一个一个输入时返回的总是0 一个一个删除时返回的总是1 用来判断是删除还是输入?
    //当剪切输入框的内容时range.length 是剪切走的字符个数
    NSLog(@"range.location = %lu ,range.length = %lu",range.location,(unsigned long)range.length);
    //输入或删除的字符
    NSLog(@"string = %@",string);
    return YES;
}


//4、是否能结束编辑  yes为允许 no为否
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{
    NSLog(@"是否允许结束编辑");
    return YES;
}

//5、已经结束编辑
- (void)textFieldDidEndEditing:(UITextField *)textField{
    NSLog(@"已经结束编辑");
   
}

/**
 *  PS
 当只有一个textfield时,从点击-编辑-离开的执行顺序为1、2、3、4、5
 如果是在两个textfield之间切换,代理执行的顺序是:
 点击第一个testField:1、2、3、 编辑完成
 再点击第二个testField:1、4、5、2、3、4、5
 *
 */

//6、是否允许清除 比如点击删除按钮 或者设置了自动清除 就会来到此方法
//yes就会清除输入框的内容,no不会清除
- (BOOL)textFieldShouldClear:(UITextField *)textField{
    
    return YES;
}

//7、点击键盘右下角键来到此方法
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    //取消第一响应者 收起键盘
    [textField resignFirstResponder];
    //疑问2:这里返回yes跟no有什么区别
    return YES;
}

//触摸屏幕时调用
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
#if 1
    //注销第一响应者 键盘会隐藏
    [self.account resignFirstResponder];
    [self.password resignFirstResponder];
#else
    //结束编辑键盘会隐藏
    [self.view endEditing:YES];
#endif
}

//最后不要忘记移除监听者
-(void)dealloc{
#if 0
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIKeyboardWillShowNotification
                                                  object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIKeyboardDidShowNotification
                                                  object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIKeyboardWillHideNotification
                                                  object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIKeyboardDidHideNotification
                                                  object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIKeyboardWillChangeFrameNotification
                                                  object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIKeyboardDidChangeFrameNotification
                                                  object:nil];
#else
    [[NSNotificationCenter defaultCenter] removeObserver:self];
#endif
}

@end


参考文章:

1、ios 监听系统键盘的出现和消失-布布扣-bubuko.com

2、IOS中多个UITextField的键盘处理



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值