美文网首页iOS 中间件开发
深入讲解iOS键盘三:自定义键盘的两种方法

深入讲解iOS键盘三:自定义键盘的两种方法

作者: kyson老师 | 来源:发表于2019-03-22 15:39 被阅读47次

    本系列博客是本人的开发笔记。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:iOS 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

    iOS系统提供了多种键盘,我们可以通过Enum类型

    typedef NS_ENUM(NSInteger, UIKeyboardType) {
        UIKeyboardTypeDefault,
        UIKeyboardTypeASCIICapable, can enter ASCII characters
        UIKeyboardTypeNumbersAndPunctuation,
        UIKeyboardTypeURL,
        UIKeyboardTypeNumberPad,
        UIKeyboardTypePhonePad,
        UIKeyboardTypeNamePhonePad,
        UIKeyboardTypeEmailAddress,
        UIKeyboardTypeDecimalPad ,
        UIKeyboardTypeTwitter ,
        UIKeyboardTypeWebSearch ,
        UIKeyboardTypeASCIICapableNumberPad ,
        UIKeyboardTypeAlphabet = UIKeyboardTypeASCIICapable,
    };
    

    设置。但有的时候由于某些特殊业务的需要,我们不得不自定义键盘,比如某些银行的APP处于安全考虑,他们键盘数字的位置是随机的,这个时候只能自定义键盘。幸运的是,iOS也为我们提供了多种方式自定义键盘。我们可以根据自身情况选择合适的方案。

    对现有键盘稍加改动

    这种情况适合身份证的输入。由于身份证大部分情况下都是数字,偶尔可能出现“X”字符,如果我们弃用数字键盘直接使用诸如UIKeyboardTypeNumbersAndPunctuation等包含数字和字符的键盘又显得没有太大必要,那稍加改动数字键盘是个不错的选择。思路也很简单,在弹出键盘的同时获取键盘对应的window,在window上加上我们需要的按钮即可。如下是笔者改动的数字键盘。

    更改现有键盘
    下面,我对重点代码做个讲解:
    -(void)keyboardWillShow:(NSNotification *)notification{
        //移除掉原先添加的按钮
        [self.extrakeyButton removeFromSuperview];
        self.extrakeyButton     = nil;
        //这几行代码相信看了之前系列博客的读者应该很熟悉了
        NSDictionary *userInfo  = [notification userInfo];
        CGFloat animationDuration   = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
        CGRect kbEndFrame           = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
        CGFloat kbHeight            = kbEndFrame.size.height;
        //以下是对添加的X按钮Frame的设置
        CGFloat extrakeyButtonX = 0;
        CGFloat extrakeyButtonW = 0;
        CGFloat extrakeyButtonH = 0;
        extrakeyButtonW = (SCREEN_WIDTH - 7) / 3;
        extrakeyButtonH = kbHeight / 4;
        CGFloat extrakeyButtonY = 0;
        extrakeyButtonY = SCREEN_HEIGHT + kbHeight - extrakeyButtonH;
        //创建“X”按钮,并设置相应的属性
        self.extrakeyButton = [[UIButton alloc] initWithFrame:CGRectMake(extrakeyButtonX, extrakeyButtonY, extrakeyButtonW, extrakeyButtonH)];
        [self.extrakeyButton addTarget:self action:@selector(buttonDidClicked) forControlEvents:UIControlEventTouchUpInside];
        self.extrakeyButton.titleLabel.font = [UIFont systemFontOfSize:27];
        [self.extrakeyButton setTitle:@"X" forState:(UIControlStateNormal)];
        [self.extrakeyButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        //获取键盘对应的Window(这段代码只在iOS 11上做过测试,还不够严谨)
        UIWindow *tempWindow = [[[UIApplication sharedApplication] windows] lastObject];
        [tempWindow addSubview:self.extrakeyButton];
        //设置动画
        [UIView animateWithDuration:animationDuration animations:^{
            CGRect frame    = self.extrakeyButton.frame;
            frame.origin.y  = frame.origin.y - kbHeight;
            self.extrakeyButton.frame = frame;
        } completion:nil];
    }
    

    以上代码只在iOS11的iPhone 8 Plus 上做过测试,可能不具备一定的普遍性,比如iPhone X的键盘位置有一定改变,按钮的位置需要加代码兼容。因此这种解决方案非常局限,只能用于身份证等业务非常简单的备选方案。有个iOS开发者对这个键盘做了个封装,读者可以点击这里获取

    自己设计一个键盘

    iOS中可以通过设置TextField/TextView的inputView来定制键盘,

    //The custom input view to display when the text field becomes the first responder.
    @property(readwrite, strong) UIView *inputView;
    
    自定义键盘

    这个自定义键盘就解决了我们开头提到的问题:键盘上的数字是随机排列的0-9,如果需要添加新的按键可以添加到键盘剩下的空白中。下面来讲解一下核心代码的实现:

    CustomKeyboardView *keyView = [[CustomKeyboardView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 176)];
    self.xTextField.inputView = keyView;
    
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            self.backgroundColor = UIColor.lightGrayColor;
            //创建数字数组,并打乱
            NSMutableArray *integers = [[NSMutableArray alloc] init];
            for (NSInteger i = 0; i < 10; ++i) {
                [integers addObject:@(i)];
            }
            NSArray  *shuffledIntegers = [self shuffle:integers];
            //添加数字按钮
            for (NSInteger index = 0; index < 10; ++index) {
                UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
                btn.backgroundColor = UIColor.grayColor ;
                [btn addTarget:self action:@selector(buttonDidClicked:) forControlEvents:UIControlEventTouchUpInside];
                btn.frame = CGRectMake(CGRectGetWidth(self.frame) / 3 * (index % 3 ), 45 *  (index / 3 ) , CGRectGetWidth(self.frame) / 3 - 1, 44);
                NSString *indexString = [NSString stringWithFormat:@"%@",shuffledIntegers[index]];
                [btn setTitle:indexString forState:UIControlStateNormal];
                [self addSubview:btn];
            }
            
        }
        return self;
    }
    

    打乱键盘中数字的布局方法很多,一般的洗牌算法就可以实现:

    -(NSArray *)shuffle:(NSArray<NSNumber *> *)array
    {
        if(array == nil || array.count < 1)
            return nil;
        NSMutableArray *resultArray = [NSMutableArray arrayWithArray:array];
        NSInteger value;
        NSNumber *median;
        
        for(NSInteger index = 0; index < array.count; index ++){
            value = rand() % resultArray.count;
            median = resultArray[index];
            
            resultArray[index] = resultArray[value];
            resultArray[value] = median;
        }
        return resultArray;
    }
    

    最后是点击键盘按钮后的回调处理

    -(void)buttonDidClicked:(UIButton *) sender{
        if (self.delegate) {
            [self.delegate keyboardItemDidClicked:sender.titleLabel.text];
        }
    }
    

    相比较而言,大家是否觉得这种方法比第一种方法既简单又简洁?

    本文Demo的代码获取

    引用

    iOS身份证键盘
    iOS自定义键盘demo

    相关文章

      网友评论

        本文标题:深入讲解iOS键盘三:自定义键盘的两种方法

        本文链接:https://www.haomeiwen.com/subject/epcqvqtx.html