zoukankan      html  css  js  c++  java
  • iOS_22自定义键盘工具栏

    最后效果图:





    Main.storyboard





    KeyboardTool.xib




    KeyboardTool.h

    //  KeyboardTool.h
    //  键盘处理
    //  Created by beyond on 14-8-24.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    
    #import <UIKit/UIKit.h>
    @protocol KeyboardToolDelegate;
    
    typedef enum {
        kKeyboardToolButtonTypeNext, // 下一个button
        kKeyboardToolButtonTypePrevious, // 上一个button
        kKeyboardToolButtonTypeDone // 完毕button
    } KeyboardToolButtonType;
    
    @interface KeyboardTool : UIToolbar
    
    // 上一个button控件
    @property (nonatomic, weak) IBOutlet UIBarButtonItem *previousBtn;
    
    // 下一个button控件
    @property (nonatomic, weak) IBOutlet UIBarButtonItem *nextBtn;
    
    // 完毕button控件
    @property (nonatomic, weak) IBOutlet UIBarButtonItem *doneBtn;
    
    // 代理一般用weak,同一时候,避免与默认的继承的delegate冲突
    @property (nonatomic, weak) id<KeyboardToolDelegate> toolDelegate;
    
    
    
    
    
    // 类方法 返回一个实例对象
    + (id)keyboardTool;
    
    // 监听工具条上 三个button的点击 事件
    - (IBAction)previousBtnClicked;
    
    - (IBAction)nextBtnClicked;
    
    - (IBAction)doneBtnClicked;
    @end
    


    KeyboardTool.m

    //  KeyboardTool.m
    //  键盘处理
    //  Created by beyond on 14-8-24.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    
    #import "KeyboardTool.h"
    #import "KeyboardToolDelegate.h"
    
    
    @implementation KeyboardTool
    
    // 类方法,从xib文件里初始化一个KeyboardTool
    + (id)keyboardTool {
        // owner能够传KeyboardTool这个类
        // 点击"下一个"button的时候。要调用owner的next方法
        
        NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"keyboardTool" owner:nil options:nil];
        
        // 返回初始化完毕的KeyboardTool对象
        return array[0];
    }
    #pragma mark - 点击事件
    // 点击了上一个button
    - (void)previousBtnClicked {
        if ([_toolDelegate respondsToSelector:@selector(keyboardTool:buttonType:)]) {
            // 告诉代理,点击的是上一个button
            [_toolDelegate keyboardTool:self buttonType:kKeyboardToolButtonTypePrevious];
        }
    }
    // 点击了下一个button
    - (void)nextBtnClicked {
        if ([_toolDelegate respondsToSelector:@selector(keyboardTool:buttonType:)]) {
            // 告诉代理,点击的是下一个button
            [_toolDelegate keyboardTool:self buttonType:kKeyboardToolButtonTypeNext];
        }
    }
    
    // 点击了完毕button
    - (void)doneBtnClicked {
        if ([_toolDelegate respondsToSelector:@selector(keyboardTool:buttonType:)]) {
            // 告诉代理,点击的是完毕button
            [_toolDelegate keyboardTool:self buttonType:kKeyboardToolButtonTypeDone];
        }
    }
    @end
    


    KeyboardToolDelegate.h

    //
    //  KeyboardToolDelegate.h
    //  22_键盘综合案例
    //
    //  Created by beyond on 14-8-24.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    @class KeyboardTool;
    
    @protocol KeyboardToolDelegate <NSObject>
    - (void)keyboardTool:(KeyboardTool *)tool buttonType:(KeyboardToolButtonType)type;
    @end
    

    BeyondViewController.h

    //
    //  BeyondViewController.h
    //  22_键盘综合案例
    //
    //  Created by beyond on 14-8-24.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    #import "KeyboardTool.h"
    #import "KeyboardToolDelegate.h"
    
    
    
    @interface BeyondViewController : UIViewController <UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate, KeyboardToolDelegate>
    // 生日输入框
    @property (weak, nonatomic) IBOutlet UITextField *birthdayTextField;
    // 城市输入框
    @property (weak, nonatomic) IBOutlet UITextField *cityTextField;
    
    @end
    


    BeyondViewController.m

    //
    //  BeyondViewController.m
    //  22_键盘综合案例
    //
    //  Created by beyond on 14-8-24.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import "BeyondViewController.h"
    
    @interface BeyondViewController ()
    
    // 全部省名组成的数组
    @property (nonatomic, strong) NSArray *provinceNameArr;
    // 字典:省名key---value城市名组成的数组
    @property (nonatomic, strong) NSDictionary *provinceName_cities_Dict;
    // 当前激活的活跃状态的输入框
    @property (nonatomic, weak) UITextField *currentTextField;
    // 键盘上的工具条
    @property (nonatomic, weak) KeyboardTool *tool;
    // 全部输入框控件 组成的数组
    @property (nonatomic, strong) NSMutableArray *allTextFields;
    
    @end
    
    
    @implementation BeyondViewController
    
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        self.allTextFields = [NSMutableArray array];
        // 类方法,实例化一个KeyboardTool对象
        self.tool = [KeyboardTool keyboardTool];
        self.tool.backgroundColor = [UIColor clearColor];
        self.tool.barTintColor = [UIColor lightGrayColor];
        
    	// 而且设置键盘工具的代理为当前控制器,用于接收其内部的btn点击事件,感知btnType
        self.tool.toolDelegate = self;
        
        
        // 1.设置全部文本框的键盘工具条 都是 自己定义的KeyboardTool
        for (UITextField *field in self.view.subviews)
        {
    		// 假设不是文本输入框,继续
            if (![field isKindOfClass:[UITextField class]]) continue;
            
    		// 每个文本输入框的键盘工具都是它...
            field.inputAccessoryView = self.tool;
    		// 数组保存全部的文本输入框控件,后面要用到
            [self.allTextFields addObject:field];
            // 设置每个文本输入框的代理都是当前控制器
            field.delegate = self;
        }
        
        
        // 2.为生日输入框,设置键盘为DatePicker
        [self setInputViewForBirthdayTextField];
        
        
        // 3.为城市输入框,设置键盘为DatePicker
        [self  setInputViewForCityTextField];
        
        // 4.载入全部的数据
        [self  loadAllData];
        
    }
    
    // 2.为生日输入框,设置键盘为DatePicker
    - (void)setInputViewForBirthdayTextField
    {
        // 设置生日的键盘(不用设置宽高和位置)
        UIDatePicker *datePicker = [[UIDatePicker alloc] init];
        // 设置区域为中国中文简体
        datePicker.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
        // 模式为:仅仅显示日期
        datePicker.datePickerMode = UIDatePickerModeDate;
        // 监听datePicker的值改事件
        [datePicker addTarget:self action:@selector(datePickerValueChangeed:) forControlEvents:UIControlEventValueChanged];
        // 设置其为生日输入框的view
        self.birthdayTextField.inputView = datePicker;
    }
    
    // 3.为城市输入框,设置键盘为DatePicker
    - (void)setInputViewForCityTextField
    {
        // 设置城市的键盘
        UIPickerView *picker = [[UIPickerView alloc] init];
        // 设置数据源和代理
        picker.dataSource = self;
        picker.delegate = self;
        // 显示指示器
        picker.showsSelectionIndicator = YES;
        // 设置其为城市输入框的view
        self.cityTextField.inputView = picker;
    }
    // 4.载入全部的数据
    - (void)loadAllData
    {
        // 载入省份数据
        NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cities" ofType:@"plist"]];
        // 全部以省名组成的数组
        self.provinceNameArr = dict[@"provinces"];
        // 字典,键是省名,值是城市名组成的数组
        self.provinceName_cities_Dict = dict[@"cities"];
    }
    
    // 2.1监听生日选择控件的值改变事件,为生日输入框赋值
    - (void)datePickerValueChangeed:(UIDatePicker *)picker
    {
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"yyyy-MM-dd";
        // 生日输入框赋值
        self.birthdayTextField.text = [formatter stringFromDate:picker.date];
    }
    
    #pragma mark - PickerView数据源方法
    // 一共多少列
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
    {
        // 第一列是省名,第二列是省名相应的城市数组
        return 2;
    }
    // 每一列相应多少行
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
    {
        if (component == 0) {
            // 返回省名数组的长度
            return self.provinceNameArr.count;
        } else {
            // 返回第1列   当前选中的行号
            NSUInteger rowNum = [pickerView selectedRowInComponent:0];
            // 先从省名数组,取出相应的省名
            NSString *pName = self.provinceNameArr[rowNum];
            // 再从字典中,通过省名,获取城市数组,并返回其长度
            NSArray *cityArr = self.provinceName_cities_Dict[pName];
            return cityArr.count;
        }
    }
    
    // 每列每行显示什么数据
    - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
    {
        if (component == 0) {
    		//前一列,显示省名
            return self.provinceNameArr[row];
        } else {
            // 返回第1列   当前选中的行号
            NSUInteger rowNum = [pickerView selectedRowInComponent:0];
            // 先从省名数组,取出相应的省名
            NSString *pName = self.provinceNameArr[rowNum];
            // 再从字典中,通过省名,获取城市数组,并返回其长度
            NSArray *cityArr = self.provinceName_cities_Dict[pName];
            return cityArr[row];
        }
    }
    // UIPickerView选中了某一行就会调用
    - (void)pickerView:(UIPickerView *)pickerView
          didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    {
        // 刷新后一列的数据,联动效果
        [pickerView reloadComponent:1];
        
        NSUInteger pRowNum = [pickerView selectedRowInComponent:0];
        // 先从省名数组,取出相应的省名
        NSString *pName = self.provinceNameArr[pRowNum];
        
        
        NSUInteger cRowNum = [pickerView selectedRowInComponent:1];
        // 再从字典中,通过省名,获取城市数组,并返回其相应的城市名
        NSArray *cityArr = self.provinceName_cities_Dict[pName];
        NSString *cName = cityArr[cRowNum];
        // 城市输入框赋值
        self.cityTextField.text = [NSString stringWithFormat:@"%@ %@", pName, cName];
    }
    
    
    #pragma mark - 重点!!!!!!!!keyboardTool代理方法
    - (void)keyboardTool:(KeyboardTool *)tool
             buttonType:(KeyboardToolButtonType)type
    {
    	
        if (type == kKeyboardToolButtonTypeDone) {
    		//当点击完毕时,当前活动的输入框,取消第一响应者,退出键盘
            [self.currentTextField resignFirstResponder];
        } else {
    		//先取出当前输入框在输入框数组中的索引,
            NSUInteger index = [self.allTextFields indexOfObject:self.currentTextField];
            if (type == kKeyboardToolButtonTypePrevious) {
                //当点击上一个时,索引减1,
                index--;
            } else {
                //当点击下一个时,索引加1,
                index++;
            }
    		// 取出相应索引的输入框,成为即将成为的第一响应者,调出相应的键盘
            UITextField *field = self.allTextFields[index];
            [field becomeFirstResponder];
        }
    }
    
    
    #pragma mark - 重点!!!!!!!UITextField代理方法
    - (void)textFieldDidBeginEditing:(UITextField *)textField
    {
        
        // 记住被激活的文本框,其它方法keyboardTool:buttonClick:中要用到
        self.currentTextField = textField;
        
        // 先取得本输入框在全部输入框组成的数组中的索引
        NSUInteger index = [self.allTextFields indexOfObject:textField];
    	// 设置下一个按钮的,是否可用
        self.tool.nextBtn.enabled = index != self.allTextFields.count - 1;
    	// 设置上一个按钮的,是否可用
        self.tool.previousBtn.enabled = index != 0;
        
        
    }
    // 这个是 UITextField的一个托付方法!
    // 利用这个托付 我们在打开键盘的时候。点击return 就能够关闭键盘了
    - (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
        // 结束全部编辑,退出全部键盘,而且返回YES就能够
        [self.view endEditing:YES];
        return YES;
    }
    @end
    

    数据源








    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    2019年1月26日训练日记
    2019年1月25日训练日记
    2019年1月24日训练日记
    2019年1月23日训练日记
    2019年1月22日训练日记
    2019年1月21日训练日记
    2019年1月20日训练日记
    2019年1月19日训练日记
    2019年1月18日训练日记
    C语言学习小结
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4822182.html
Copyright © 2011-2022 走看看