美文网首页梦想者iOS-VendoriOS
从此不再担心键盘遮住输入框OC(一)

从此不再担心键盘遮住输入框OC(一)

作者: Jiar_ | 来源:发表于2015-11-15 16:33 被阅读10431次

    新版本在这里:从此不再担心键盘遮住输入框OC(�二)


    想必大家在iOS开发中都有遇到过这种问题。点击输入框后,弹出的键盘遮挡了输入框,然后你就无法看见你输入了什么。为了解决这个问题,我也在 GithubCocoaChina以及Code4App上花了不少时间去找相关的代码以及实现。
    找到的相关内容很多,但是都有一个共同点,是通过将底部的View上滑至键盘之上,从而可以看见输入框内的内容。在这方面做得好的有IQKeyboardManager,喜欢的可以去看看,但是我不是就直接采用了IQKeyboardManager,而是自己写了一个键盘组件KeyboardToolBar,优点是小巧易使用,支持CocoaPods,侵入性小,作者爱交友~

    先来一张效果图

    KeyboardToolBar1 showKeyboardToolBar1 show
    下面我通过如何使用源码分析两个方面来介绍KeyboardToolBar

    如何使用


    就是不想用CocoaPods

    • KeyboardToolBar下载zip。将Classes文件夹下的代码复制到你的项目中去。

    如果你也用CocoaPods

    Podfile

    platform :ios, '7.0'
    pod 'KeyboardToolBar', '~> 1.0.0'
    

    import

    /// 不要忘了先导入.h 
    #import "KeyboardToolBar.h"
    

    注册使用KeyboardToolBar

    /// 使用该方法给UITextField注册使用KeyboardToolBar 
    /// @param textField 需要注册的UITextField 
    [KeyboardToolBar registerKeyboardToolBar:self.textField];
    

    反注册(移除)eyboardToolBar

    /// 不想让UITextField使用KeyboardToolBar的时候 
    /// 强烈建议使用该方法给UITextField移除KeyboardToolBar 
    /// @param textField 需要移除的UITextField
    [KeyboardToolBar unregisterKeyboardToolBar:self.textField];
    

    unregisterAllKeyboardToolBar

    /// 如果嫌一个一个给UITextField移除KeyboardToolBar麻烦 
    /// 使用这个方法一次性将所有的UITextField移除KeyboardToolBar
    [KeyboardToolBar unregisterAllKeyboardToolBar];
    

    源码分析


    实现思路

    我的设想是在键盘上方的工具栏处做文章,哪怕是键盘挡住了输入框,但是如果将输入框上的placeholder以及输入的内容时刻在工具栏上显示,那么哪怕键盘挡住了输入框,依旧可以清楚知道我现在要输入哪方面的内容以及我现在输入的内容是什么。

    说明

    为了看起来清楚些,以下代码中我使用KTB代表KeyboardToolBar单例对象

    .h文件

    /// 继承iOS自带的UIToolbar
    @interface KeyboardToolBar : UIToolbar
    

    /// KeyboardToolBar宽度 
    #define KeyboardToolBarWidth [UIScreen mainScreen].bounds.size.width 
    /// KeyboardToolBar高度 
    #define KeyboardToolBarHeight 44 
    /// KeyboardToolBar上UIScrollView组件的宽度 
    #define KeyboardScrollViewWidth (KeyboardToolBarWidth-80)
    

    属性

    @property(nonatomic, strong)UIScrollView *scrollView;
    @property(nonatomic, strong)UITextField *toolBarTextField; 
    /// 字典用于存放注册使用KeyboardToolBar的所有UITextField
    @property(nonatomic, retain)NSMutableDictionary *allRegisterTextFields;
    

    KeyboardToolBar构造单例方法

    /// KTBstatic KeyboardToolBar *keyboardToolBar = nil;
    + (instancetype)shareKeyboardToolBar {
        if (keyboardToolBar == nil) { 
            /// KTB是否初始化,如果没有,则进行初始化 
            /// KeyboardToolBar上需要有一个UIScrollView组件,UIScrollView内部有一个UITextField,如果UITextField内的内容过多,UIScrollView就派上用场了。
            /// KeyboardToolBar的右侧还需要有一个'完成'按钮,点击该按钮后关闭键盘
            keyboardToolBar = [[KeyboardToolBar alloc]initWithFrame:CGRectMake(0, 0, KeyboardToolBarWidth, KeyboardToolBarHeight)];
            [keyboardToolBar setBarStyle:UIBarStyleDefault];
            keyboardToolBar.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, KeyboardScrollViewWidth, KeyboardToolBarHeight)];
            keyboardToolBar.scrollView.backgroundColor = [UIColor clearColor]; 
            keyboardToolBar.scrollView.contentSize = CGSizeMake(KeyboardScrollViewWidth, KeyboardToolBarHeight); 
            keyboardToolBar.scrollView.bounces = NO;
            keyboardToolBar.toolBarTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, KeyboardScrollViewWidth, KeyboardToolBarHeight)];
            keyboardToolBar.toolBarTextField.textAlignment = NSTextAlignmentLeft;
            keyboardToolBar.toolBarTextField.userInteractionEnabled = NO;
            [keyboardToolBar.scrollView addSubview:keyboardToolBar.toolBarTextField];
            UIBarButtonItem *textFieldItem = [[UIBarButtonItem alloc] initWithCustomView:keyboardToolBar.scrollView];
            UIBarButtonItem *finishBtnItem = [[UIBarButtonItem alloc]initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:keyboardToolBar action:@selector(resignKeyboard)];
            NSArray * buttonsArray = [NSArray arrayWithObjects:textFieldItem,finishBtnItem,nil]; [keyboardToolBar setItems:buttonsArray];
        } 
        return keyboardToolBar;
    }
    /// 关闭键盘
    - (void)resignKeyboard {
        keyboardToolBar.toolBarTextField.text = @"";
        [[[UIApplication sharedApplication] keyWindow] endEditing:YES];
    }
    

    KeyboardToolBar注册方法

    + (void)registerKeyboardToolBar:(UITextField *)textField {
        if([KeyboardToolBar shareKeyboardToolBar].allRegisterTextFields == nil) {
            keyboardToolBar.allRegisterTextFields = [NSMutableDictionary dictionaryWithCapacity:10];
        }
        /// 将KTB赋予传入的textField
        [textField setInputAccessoryView:keyboardToolBar];
        /// 为传入的textField对象addTarget
        [textField addTarget:keyboardToolBar action:@selector(textFieldDidBegin:) forControlEvents:UIControlEventEditingDidBegin];
        [textField addTarget:keyboardToolBar action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
        /// 将传入的textField保存于KTB
        [keyboardToolBar.allRegisterTextFields setValue:textField forKey:[NSString stringWithFormat:@"%p",textField]];
    }
    - (void)textFieldDidBegin:(UITextField *)textField {
        [self reSetTextField:textField];
    }
    - (void)textFieldDidChange:(UITextField *)textField {
        [self reSetTextField:textField];
    }
    /// 将textField的placeholder以及textField上的文字及时显示在KTB内部的UITextField上
    - (void)reSetTextField:(UITextField *)textField {
        UITextField *tempTextField = [keyboardToolBar.allRegisterTextFields objectForKey:[NSString stringWithFormat:@"%p",textField]];
        CGFloat textWidth = [KeyboardToolBar widthForString:tempTextField.text withFont:keyboardToolBar.toolBarTextField.font];
        if(textWidth > KeyboardScrollViewWidth) {
            keyboardToolBar.toolBarTextField.frame = CGRectMake(0,0,textWidth,KeyboardToolBarHeight);
            keyboardToolBar.scrollView.contentSize = CGSizeMake(textWidth, KeyboardToolBarHeight);
            [self.scrollView scrollRectToVisible:CGRectMake(textWidth-KeyboardScrollViewWidth,0,KeyboardScrollViewWidth,KeyboardToolBarHeight) animated:YES];
        } else {
            keyboardToolBar.toolBarTextField.frame = CGRectMake(0, 0, KeyboardScrollViewWidth, KeyboardToolBarHeight);
            keyboardToolBar.scrollView.contentSize = CGSizeMake(KeyboardScrollViewWidth, KeyboardToolBarHeight);
        }
        keyboardToolBar.toolBarTextField.text = tempTextField.text;
        keyboardToolBar.toolBarTextField.textColor = tempTextField.textColor;
        if(tempTextField.placeholder != nil) {
            NSAttributedString *attribute = textField.attributedPlaceholder;
            NSDictionary *dictionary = [attribute attributesAtIndex:0 effectiveRange:nil];
            keyboardToolBar.toolBarTextField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:tempTextField.placeholder attributes:@{NSForegroundColorAttributeName: [dictionary valueForKey:NSForegroundColorAttributeName]}];
        }
    }
    /// 根据文本内容和字体计算NSString长度用于设置KTB内部的UIScrollView以及UITextField的宽度
    + (CGFloat)widthForString:(NSString *)str withFont:(UIFont *)font {
        NSDictionary *attribute = @{NSFontAttributeName: font};
        CGSize size = [str boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attribute context:nil].size;
        return size.width;
    }
    

    KeyboardToolBar反注册(移除)方法

    /// 直接将KTB中所有已注册的UITextField移除
    + (void)unregisterKeyboardToolBar:(UITextField *)textField {
        if(keyboardToolBar == nil || keyboardToolBar.allRegisterTextFields.count == 0) {
            return;
        }
        UITextField *tempTextField = [keyboardToolBar.allRegisterTextFields objectForKey:[NSString stringWithFormat:@"%p",textField]];
        [tempTextField setInputAccessoryView:nil];
        [tempTextField removeTarget:keyboardToolBar action:@selector(textFieldDidBegin:) forControlEvents:UIControlEventEditingDidBegin];
        [tempTextField removeTarget:keyboardToolBar action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
        [keyboardToolBar.allRegisterTextFields removeObjectForKey:[NSString stringWithFormat:@"%p",textField]];
        if(keyboardToolBar.allRegisterTextFields.count == 0) {
            keyboardToolBar.allRegisterTextFields = nil;
            keyboardToolBar = nil;
        }
    }
    /// 根据传入的UITextField兑现。从KTB内移除
    + (void)unregisterAllKeyboardToolBar {
        if(keyboardToolBar == nil || keyboardToolBar.allRegisterTextFields.count == 0) {
            return;
        }
        NSEnumerator *enumeratorValue = [keyboardToolBar.allRegisterTextFields objectEnumerator];
        for(UITextField *tempTextField in enumeratorValue) {
            [tempTextField setInputAccessoryView:nil];
            [tempTextField removeTarget:keyboardToolBar action:@selector(textFieldDidBegin:) forControlEvents:UIControlEventEditingDidBegin];
            [tempTextField removeTarget:keyboardToolBar action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
        } 
        [keyboardToolBar.allRegisterTextFields removeAllObjects];
        keyboardToolBar.allRegisterTextFields = nil;
        keyboardToolBar = nil;
    }
    
    好了,以上就是我的介绍,欢迎大家来我的KeyboardToolBar主页进行Star、Issues或Pull requests,我是Jiar,我热爱交朋友~

    相关文章

      网友评论

      • 唐僧多粥少:...哥。。。 这个我用了所有的textfield都弹出了这种的了,但我只要其中一个需要,我用了unregister,其它的依旧在
      • 白菜松:感觉实际开发产品不太会用到这样的效果......
      • ff3ce38dbeb4:弹出de显示框没有光标怎么整,尝试修改,改不了啊,求楼主帮忙
        Jiar_:@吃不胖的大青虫 你想的是,希望通过直接在键盘上面的区域编辑框内修改文本,从而给希望赋值的编辑框赋值吧。我刚开始也尝试着这么做,中途遇到一些比较棘手的问题,所以改变了模式。你可以尝试着写着看。
        ff3ce38dbeb4:@Jiar_ 这样设置只是把KeyboardToolBar键盘上显示文本的地方设置为可编辑的状态,需要去点击才会出现光标。我想要的效果是默认进去就有光标的那种效果
        Jiar_:@吃不胖的大青虫 KeyboardToolBar键盘上显示文本的地方吗?user interaction enable设置yes就可以了,但是这样做可能会出问题~尝试着改着玩吧
      • 孤居引:这是虽然你的文件夹是黄色了,但是后面是?,还是不能运行。此时点击你的带问号的文件在Xcode上卖弄点击source control->add selected files.
        这个方法也是不管用。。。
        Jiar_:@羽小翼 我会考虑的,谢谢
        孤居引:@羽小翼 解决了,SVN的时候好像没有识别,又添加了一次,就好了。然后给个建议:在.m文件里面添加keyboardToolBar.toolBarTextField.secureTextEntry = tempTextField.secureTextEntry;会不会比较好?
        Jiar_:@羽小翼 项目构建有点问题,最好是把我这个删干净重新导入。我建议是使用pod依赖管理
      • 孤居引:赞赞,不过为什么把unregisterAllKeyboardToolBar给注释掉了?是不想让删除吗? :relaxed:
        Jiar_:@羽小翼 这种情况…我还真没遇到过。你用的是pod还是直接下的源码。
        孤居引:@Jiar_ 昨天用的好好的,今天SVN一下就不能用了是怎么回事?
        Jiar_:@羽小翼 因为会影响系统自带的一些东西,你可以尝试开启使用一下就明白了。
      • 姜流儿96:赞一个
      • 闭家锁:我觉得根据键盘弹出动画移动输入框也不错,根据键盘的frame高度,如果输入框被挡住,上移输入框位置到键盘上方,效果也很好
        Jiar_:@闭家锁 嗯。这确实是主流的做法
      • 对酒当歌的夜:很不错,收藏了,貌似主流应用都是往上弹的,
        Jiar_:@对酒当歌的夜 嗯。多谢支持
      • 飞鸽在线:交流交流
        飞鸽在线: @Jiar_赞
        Jiar_:欢迎
      • a丽颖: :+1:
        Jiar_:谢谢

      本文标题:从此不再担心键盘遮住输入框OC(一)

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