处理键盘升起后对界面覆盖问题的处理

大家在开发app的时候,界面中时常会有输入框(UItextfield,UItextview),这时我们点击输入框时会吊起键盘,根据手机屏幕不同我们的键盘会不同程度上覆盖界面上的部分控件,包括有无nav时坐标的变化与处理都会不同。所以本文就是针对此问题作了处理,基本上的常见的键盘引起的问题此demo应该都可以解决.

下面直接上代码,首先是.h中的一些申明:

<span style="font-family: Arial, Helvetica, sans-serif;">#define SCREEN_WIDTH    ([UIScreen mainScreen].bounds.size.width</span>
#define SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)

@interface ZTKeyboardVC : UIViewController<UITextFieldDelegate,UIScrollViewDelegate,UITextViewDelegate>

@property(nonatomic,strong)UIView*temView;
@property(nonatomic,assign)CGRect temRect;//记录输入框的坐标
@property(nonatomic,assign)CGRect temRect2;//记录scrollview的坐标
@property(nonatomic,assign)CGRect temRect3;//记录self.view的坐标
@property(nonatomic,assign) CGFloat temY;//记录scrollview改变偏移的前一次Y偏移
@property(nonatomic,assign) CGFloat temHeight;//记录处理有无nav的屏高
@property(nonatomic,assign)CGPoint temPoint;//记录contoffset
@property(nonatomic,assign) int keyHeight;//键盘高度
@property(nonatomic,assign) int mark;//记录高度差值
@property(nonatomic,assign) BOOL Show;//标记键盘是否升起
@property(nonatomic,assign) CGFloat offsetY;//scrollview的Y偏移量
@property(nonatomic,strong)NSArray*textArr;//输入框对象的集合
@property(nonatomic,strong)UIScrollView*temScroll;
@property(nonatomic,strong)UITapGestureRecognizer *recognizer;

+(void)loadWithSuperVC:(UIViewController*)VC WithScrollview:(UIScrollView*)scrollview :(NSArray*(^)())Input;

@end


 
 

重点在.m 中

-(NSArray*)textArr//这里是懒加载
{
    if (_textArr==nil) {
        _textArr=[NSArray new];
    }
    
    return _textArr;
}



#pragma mark--调用此类方法触发坐标升降变换
+(void)loadWithSuperVC:(UIViewController*)VC WithScrollview:(UIScrollView*)scrollview :(NSArray*(^)())Input
{
    ZTKeyboardVC*ZT=[ZTKeyboardVC new];
    [VC addChildViewController:ZT];
    [ZT AddObserverForKeyboard1];
    [ZT AddObserverForKeyboard0];
    ZT.textArr=Input();

    for (int i=0; i<ZT.textArr.count; i++) {
        if ([ZT.textArr[i] isKindOfClass:[UITextView class]]) {
            UITextView*txtview=ZT.textArr[i];
            txtview.delegate=ZT;

        }
        if ([ZT.textArr[i] isKindOfClass:[UITextField class]]){
            UITextField*txtfield=ZT.textArr[i];
            txtfield.delegate=ZT;
           
        }
        
        
    }
    
    if (VC.navigationController.navigationBar.frame.size.height) {//有nav的处理
        ZT.temHeight=SCREEN_HEIGHT-64;
    }
    else
        ZT.temHeight=SCREEN_HEIGHT;
    
    if (scrollview) {
        
        ZT.offsetY=0;
        ZT.temScroll=scrollview;
        ZT.temScroll.delegate=ZT;
        ZT.temRect2=ZT.temScroll.frame;
       
        
    }
    else{
   
       // NSLog(@"PP=%f",VC.navigationController.navigationBar.frame.size.height);
        ZT.temView=VC.view;
        if (VC.navigationController.navigationBar.frame.size.height) {
            ZT.temRect3=CGRectMake(VC.view.frame.origin.x, VC.view.frame.origin.y+64, VC.view.frame.size.width, VC.view.frame.size.height);
        }
        else
            ZT.temRect3= VC.view.frame;
    }
    
}

下面看一些scroll与 textfield 的代理方法,这个demo是分为有无scroll来处理的

#pragma mark--不减速停止,此时手指离开立刻停止
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    _offsetY=scrollView.contentOffset.y;
}

#pragma mark--减速停止,此时手指离开时还在滚动
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    _offsetY=scrollView.contentOffset.y;
}

#pragma mark--textView输入框将要编辑时调用
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
    
     _temRect=textView.frame;
    _temY=_temScroll.contentOffset.y;
   
    if (_Show) {
    
        NSLog(@"ppppppp");
        [self changeframeForshow];
    }
     return YES;
}



#pragma mark--textView按ruturn,键盘消失
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString*)text
{
    if ([text isEqualToString:@"\n"]) {
        [textView resignFirstResponder];
        return NO;
    }
    return YES;
}

#pragma mark--textField按ruturn,键盘消失
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    
    [textField resignFirstResponder];
    return YES;
}

#pragma mark--textField输入框开始编辑时调用
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    _temY=_temScroll.contentOffset.y;
    _temRect=textField.frame;
  
    if (_Show) {
        
        [self changeframeForshow];

    }
    
}

键盘通知注册与移除以及通知触发时事件的处理

#pragma mark--注册通知(事件即将发生)
-(void)AddObserverForKeyboard0
{
    
    //增加监听,当键盘出现或改变时收出消息
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];
    
    //增加监听,当键退出时收出消息
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}


#pragma mark--注册通知(事件已经发生)
-(void)AddObserverForKeyboard1
{
    //增加监听,当键盘已经出现或改变时收出消息
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardDidShow)
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];
    
    //增加监听,当键已经退出时收出消息
   [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardDidHide)
                                                 name:UIKeyboardDidHideNotification
                                               object:nil];
    
    _Show=NO;
}

-(void)keyboardDidShow
{
    _Show=YES;
}

-(void)keyboardDidHide
{
    _Show=NO;
    [self changeframeForhide];
}

#pragma mark--改变坐标
-(void)changeframeForshow
{
   
    if (!_temScroll) {
        _mark=-_keyHeight+(_temHeight-CGRectGetMaxY(_temRect));
        if (_mark<0) {
            
            [UIView animateWithDuration:0.4 animations:^{
                
                _temView.frame=CGRectMake(_temRect3.origin.x,_temRect3.origin.y+_mark-0.5 , _temRect3.size.width, _temRect3.size.height);
                
            }];
            
        }
        
        
    }
    else{//有scrollview
        _offsetY=_temY;
        _mark=-_keyHeight+(_temHeight-CGRectGetMaxY(_temRect))+_offsetY;
        NSLog(@"mark==%i",_mark);
       if (_mark<0) {
           [UIView animateWithDuration:0.2 animations:^{
          _temScroll.contentOffset=CGPointMake(0, _offsetY-_mark);
            }];
       
       }
        
       
    }
    

}

-(void)changeframeForhide
{
    if (_temScroll==nil) {
        
        [UIView animateWithDuration:0.5 animations:^{
            
            _temView.frame=_temRect3;
        }];
    }
    else{
    
        _temScroll.contentOffset=CGPointMake(0, 0);//回归
        _offsetY=0;
    
            
    }
    
}


#pragma mark--键盘升起
- (void)keyboardWillShow:(NSNotification *)aNotification
{
    
    //获取键盘的高度
    NSDictionary *userInfo = [aNotification userInfo];
    NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGRect keyboardRect = [aValue CGRectValue];
    _keyHeight = keyboardRect.size.height;
    NSLog(@"键盘高度=%i",_keyHeight);
    [self changeframeForshow];
    
}


#pragma mark--键盘退出
- (void)keyboardWillHide:(NSNotification *)aNotification
{
    [self changeframeForhide];
    
}


-(void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil];
}

代码中我已经详细的注释了,各位有问题请留言!!


你可能感兴趣的:(ios,键盘,UITextField,升起)