• 多个UITextField的处理(实现键盘排版)


    第一种方法(没有禁止“上、下一个的按钮”)

    Main.storyboard一定要设置相应的控制器类

    KeyboardToolbar.h

    #import <UIKit/UIKit.h>

    @class KeyboardToolbar;

    typedef enum {

        BTNTypePrevious = 0,

        BTNTypeNext,

        BTNTypeDone,

    }BTNType;

     

    @protocol KeyboardToolbarDelegate <NSObject>

     

    -(void)keyboardTool:(KeyboardToolbar *)toolbar btnClickType:(BTNType)btnType;

    @end

     

    @interface KeyboardToolbar : UIToolbar

     

    +(instancetype)toolbar;

     

    @property(nonatomic,weak)id<KeyboardToolbarDelegate> kbtDelegate;

     

    @end

    #import "KeyboardToolbar.h"

     

    @interface KeyboardToolbar()

     

    - (IBAction)btnClick:(UIBarButtonItem *)item;

     

     

    @end

     

    @implementation KeyboardToolbar

     

    +(instancetype)toolbar{

        return [[[NSBundle mainBundle] loadNibNamed:@"KeyboardToolbar" owner:nil options:nil] lastObject];

    }

     

    - (IBAction)btnClick:(UIBarButtonItem *)item {

        

        BTNType btnType = BTNTypeDone;//默认是Done

        

        if ([self.kbtDelegate respondsToSelector:@selector(keyboardTool:btnClickType:)]) {

            if (item.tag == 0) {

                btnType = BTNTypePrevious;

            }else if(item.tag == 1){

                btnType = BTNTypeNext;

            }

            

            [self.kbtDelegate keyboardTool:self btnClickType:btnType];

        }

    }

    @end

    KeyboardToolbar.xib

     

    xib中一定要设置与控制器类相对应的类

    ViewController.m

    //

    //  ViewController.m

    //  08.注册【排版技巧】

    //

    //  Created by Yong Feng Guo on 14-12-22.

    //  Copyright (c) 2014 Fung. All rights reserved.

    //

     

    #import "ViewController.h"

    #import "KeyboardToolbar.h"

     

    @interface ViewController ()<KeyboardToolbarDelegate,UITextFieldDelegate>

    @property (weak, nonatomic) IBOutlet UIView *registerContainer;

    @property(nonatomic,strong)KeyboardToolbar *toolbar;//键盘的工具条

    @property(nonatomic,strong)NSArray *fields;//注册框容器所有输入框

     

    @end

     

    @implementation ViewController

     

    /**

     *获取注册框容器的所有输入框

     *遍历所有UITextField

     *UITextField添加工具栏

     */

    -(NSArray *)fields{

        if (!_fields) {

            NSArray *subviews = self.registerContainer.subviews;

            NSMutableArray *fieldsM = [NSMutableArray array];

            NSLog(@"%ld",subviews.count);

            //遍历所有UITextField添加到数组中

            for (id obj in subviews) {

                if ([obj isKindOfClass:[UITextField class]]) {

                    //添加工具条

                    UITextField *tf = obj;

                    tf.inputAccessoryView = self.toolbar;

                    [fieldsM addObject:tf];

                }

            }

            _fields = fieldsM;

        }

        

        return _fields;

    }

     

    /**

     * 键盘工具条

     */

    -(KeyboardToolbar *)toolbar{

        if (!_toolbar) {

            _toolbar = [KeyboardToolbar toolbar];

            _toolbar.kbtDelegate = self;

        }

        return _toolbar;

    }

     

    - (void)viewDidLoad {

        [super viewDidLoad];

    //#warning 遍历后数组为空,去除size classes

        [self fields];

       

        //监听键盘的显示

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kbWillShow:) name:UIKeyboardWillShowNotification object:nil];

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kbWillHide:) name:UIKeyboardWillHideNotification object:nil];

    }

     

    -(void)kbWillHide:(NSNotification *)noti{

        [UIView animateWithDuration:0.25 animations:^{

            self.view.transform = CGAffineTransformIdentity;

        }];

    }

    -(void)kbWillShow:(NSNotification *)noti{

        NSLog(@"%@",noti.userInfo);

        //键盘高度

        CGFloat kbY = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y;

        

        //响应者的最大Y

        UITextField *firstResp = [self firstResp];

        //响应者在控制器view的最高的Y

        CGFloat tfMaxYInView = CGRectGetMaxY(firstResp.frame) + self.registerContainer.frame.origin.y;

        

        CGFloat delta = kbY - tfMaxYInView;

        NSLog(@"%f",delta);

        if (delta < 0) {

            [UIView animateWithDuration:0.25 animations:^{

                    self.view.transform = CGAffineTransformMakeTranslation(0, delta);

            }];

     

        }

     

    }

     

    -(void)dealloc{

        [[NSNotificationCenter defaultCenter] removeObserver:self];

    }

     

    -(void)keyboardTool:(KeyboardToolbar *)toolbar btnClickType:(BTNType)btnType{

        // 获取当前响应者

        UITextField *firstResp = [self firstResp];

        

        // 如果没有当前响应者,直接返回

        if(!firstResp) return;

        

        //获取响应者索

        NSInteger indexOfFirstResp = [self.fields indexOfObject:firstResp];

        

        // 更改响应者

        if (btnType == BTNTypePrevious && indexOfFirstResp != 0){//上一个

            [firstResp resignFirstResponder];

     

            [self.fields[indexOfFirstResp - 1] becomeFirstResponder];

        }else if(btnType == BTNTypeNext && indexOfFirstResp != self.fields.count -1) {//下一个

            [firstResp resignFirstResponder];

            [self.fields[indexOfFirstResp + 1] becomeFirstResponder];

        }else if(btnType == BTNTypeDone){

            [self.view endEditing:YES];

        }

    }

     

    /**

     * 返回第一响应者

     */

    -(UITextField *)firstResp{

        for (id obj in self.fields) {

            if ([obj isFirstResponder]) {

                return obj;

                break;

            }

        }

        return nil;

    }

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

        [self.view endEditing:YES];

    }

     

     

     

    @end

    第二种方式(上、下一个按钮可以禁止,推荐使用)

    Main.storyboard与上面一样

    KeyboardToolbar.h

    #import <UIKit/UIKit.h>

    @class KeyboardToolbar;

    typedef enum {

        BTNTypePrevious = 0,

        BTNTypeNext,

        BTNTypeDone,

    }BTNType;

     

    @protocol KeyboardToolbarDelegate <NSObject>

     

    -(void)keyboardTool:(KeyboardToolbar *)toolbar btndidSelected:(UIBarButtonItem *)item;

    @end

     

    @interface KeyboardToolbar : UIToolbar

    //上一个按钮

    @property (weak, nonatomic) IBOutlet UIBarButtonItem *previousItem;

    //下一个按钮

    @property (weak, nonatomic) IBOutlet UIBarButtonItem *nextItem;

     

    +(instancetype)toolbar;

     

    @property(nonatomic,weak)id<KeyboardToolbarDelegate> kbtDelegate;

     

    @end

    KeyboardToolbar.m

    #import "KeyboardToolbar.h"

     

    @interface KeyboardToolbar()

     

    - (IBAction)btnClick:(UIBarButtonItem *)item;

     

     

    @end

     

    @implementation KeyboardToolbar

     

    +(instancetype)toolbar{

        return [[[NSBundle mainBundle] loadNibNamed:@"KeyboardToolbar" owner:nil options:nil] lastObject];

    }

     

    - (IBAction)btnClick:(UIBarButtonItem *)item {

        

        BTNType btnType = BTNTypeDone;//默认是Done

        

        if ([self.kbtDelegate respondsToSelector:@selector(keyboardTool:btndidSelected:)]) {

            if (item.tag == 0) {

                btnType = BTNTypePrevious;

            }else if(item.tag == 1){

                btnType = BTNTypeNext;

            }

            

            [self.kbtDelegate keyboardTool:self btndidSelected:item];

        }

    }

    @end

    KeyboardToolbar.xib与上面一样

    ViewController.m

    //

    //  ViewController.m

    //  多个UITextField的处理

    //

    //  Created by huan on 16/1/20.

    //  Copyright © 2016 huanxi. All rights reserved.

    //

     

    #import "ViewController.h"

    #import "KeyboardToolbar.h"

    @interface ViewController ()<KeyboardToolbarDelegate, UITextFieldDelegate>

    @property (weak, nonatomic) IBOutlet UIView *registerContainer;

    //@property (weak, nonatomic) UIBarButtonItem *currentItem;//当前的Item

    @property (nonatomic, strong) KeyboardToolbar *toolbar;//键盘的工具条

    @property (nonatomic, strong) NSArray *fields;//将所有的输入框放入一个数组里

     

    @end

     

    @implementation ViewController

    /**

     * 懒加载toolbar

     *

     */

    -(KeyboardToolbar *)toolbar{

        if (!_toolbar) {

            _toolbar = [KeyboardToolbar toolbar];

            _toolbar.kbtDelegate = self;

        }

        return _toolbar;

    }

     

    - (void)viewDidLoad {

        [super viewDidLoad];

        // Do any additional setup after loading the view, typically from a nib.

        //定义一个可变数组

        NSMutableArray *fieldsM = [NSMutableArray array];

        //warning sizeClasses 导航注册框窗口的子控制器为空,去掉storyboardsizeClasses

        //遍历UITextField 添加键盘工具条

        NSLog(@"%@", self.registerContainer.subviews);

        for (UIView *subView in self.registerContainer.subviews) {

            if ([subView isKindOfClass:[UITextField class]]) {

                UITextField *tf = (UITextField *)subView;

                tf.inputAccessoryView = self.toolbar;

                //绑定tag

                tf.tag = fieldsM.count;

                [fieldsM addObject:tf];

            }

        }

        self.fields = fieldsM;

        //监听键盘事件

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willShow:) name:UIKeyboardWillShowNotification object:nil];

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willHide:) name:UIKeyboardWillHideNotification object:nil];

    }

    //显示键盘

    -(void)willShow:(NSNotification *)notifi{

        NSLog(@"%@", notifi.userInfo);

        //当键盘挡住UITextField,TextField所在父控件往上移

        //1.获得当前选中的UITextField的最大Y

        //当前获取焦点的textfield

        UITextField *curretTf = self.fields[[self indexOfFirstResponder]];

        //键盘一弹出,就判断上一个,下一个按钮可不可用

        if(curretTf.tag == 0){

            self.toolbar.previousItem.enabled = NO;

        }

        if (curretTf.tag == self.fields.count - 1) {

            self.toolbar.nextItem.enabled = NO;

        }

    //    curretTf.frame.origin.y + curretTf.frame.size.height

        CGFloat maxY = CGRectGetMaxY(curretTf.frame) + self.registerContainer.frame.origin.y;

        //2.获得键盘的y

        CGRect kbEndFrm = [notifi.userInfo[UIKeyboardFrameEndUserInfoKey]CGRectValue];

        CGFloat kbY = kbEndFrm.origin.y;

        //3.进行比较

        //计算距离

        CGFloat delta = kbY - maxY;

        if (delta < 0) {//需要往上移

            //添加动画

            [UIView animateWithDuration:0.25 animations:^{//动画是防止卡而设置的视觉效果

                self.view.transform = CGAffineTransformMakeTranslation(0, delta); //view的属性:形变

            }];

            

        }

        

    }

    //隐藏键盘

    -(void)willHide:(NSNotification *)notifi{

        [UIView animateWithDuration:0.25 animations:^{

           self.view.transform = CGAffineTransformIdentity;//恢复原状,如果没这句话,会有黑色的覆盖下面,因为没有隐藏键盘

        }];

        

        //还原工具条的item为可用

        self.toolbar.previousItem.enabled = YES;//又隐藏又显示会造成两个按钮禁止。所以写了这两句代码。

        self.toolbar.nextItem.enabled = YES;

    }

     

    /**

     * 获取当前的响应者的索引

     */

    -(NSInteger)indexOfFirstResponder{

        for (UITextField *tf in self.fields) {

            if (tf.isFirstResponder) {

                return tf.tag;

            }

        }

        //返回-1当前响应者

        return -1;

    }

     

    -(void)keyboardTool:(KeyboardToolbar *)toolbar btndidSelected:(UIBarButtonItem *)item{

    //    self.currentItem = item;

        switch (item.tag) {

            case 0://上一个

                [self previous];

                break;

            case 1://下一个

                [self next];

    //            NSLog(@"%ld")

                break;

            case 2://完成 键盘消失

                [self.view endEditing:YES];

                break;

                

            default:

                break;

        }

    }

     

    -(void)previous{

        //获取当前的焦点

        NSInteger currentIndex = [self indexOfFirstResponder];

        NSLog(@"%ld", currentIndex);

        self.toolbar.nextItem.enabled = YES;

    //    if (currentIndex == 1) {

    //        //禁止上一个按钮(“上一个变白 就是禁用)

    ////        self.currentItem.enabled = NO;

    //        self.toolbar.previousItem.enabled = NO;

    //    }

        //获得上一个索引

        NSInteger previousIndex = currentIndex - 1;

        

        //不当响应者

    //    [self.fields[currentIndex] resignFirstResponder];//把之前的焦点去掉。在iOS9没影响

     

        //索引大于0

        if (previousIndex >= 0) {

            [self.fields[previousIndex] becomeFirstResponder];

        }

        

    //    //如果没有焦点,或者当前是第一个UITextField为响应者,不应该点 上一下

    //    if (currentIndex == -1 || currentIndex == 0) {

    ////        self.

    //        return;

        

    }

     

    -(void)next{

        //获取当前的焦点

        NSInteger currentIndex = [self indexOfFirstResponder];

        NSLog(@"%ld", currentIndex);

        

        self.toolbar.previousItem.enabled = YES;

    //    //判断当前索引等于什么时候,下个按钮不可以用

    //    if(currentIndex == self.fields.count - 2){

    //        self.toolbar.nextItem.enabled = NO;

    //    }

        

        //不当响应者

    //    [self.fields[currentIndex] resignFirstResponder];

     

        //设置下一个焦点

        if(currentIndex != -1 && currentIndex != self.fields.count - 1){

            NSInteger nextIndex = currentIndex + 1;

            [self.fields[nextIndex] becomeFirstResponder];

        }

    }

    - (void)didReceiveMemoryWarning {

        [super didReceiveMemoryWarning];

        // Dispose of any resources that can be recreated.

    }

    //点击空白处键盘消失

    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

        [self.view endEditing:YES];

    }

     

     

     

    @end

    这种方式解决了上下按钮禁止问题、不移动问题、两个按钮同时禁止问题(在键盘隐藏里),增加动画效果,有视觉上的美感。

     

  • 相关阅读:
    android11——Material Design
    android10——Internet
    Andrid09——Service
    Android08——MultiMedia
    Android07——ContentProvider
    Android06——Persistence
    <转>汇编源码调试
    编程中我犯过的错误一
    中国社会9大阶层划分,看看你在哪一层?
    汇编中如果汇编和调用API混合用的话要注意Pushad popad
  • 原文地址:https://www.cnblogs.com/Lu2015-10-03/p/5147771.html
Copyright © 2020-2023  润新知