美文网首页
一个关于UITextView的奇葩问题 :-[UITextFie

一个关于UITextView的奇葩问题 :-[UITextFie

作者: codeCoder | 来源:发表于2017-02-20 16:02 被阅读132次

    在公司的项目中,发现了一个奇葩问题,只要一点击输入框,系统过一段时间会崩溃.
    在这个界面我监听了UIKeyboardWillShowNotificationUIKeyboardWillHideNotification,并且在delloc方法中释放了通知.
    调试时我发现这个界面的 监听到UIKeyboardWillShowNotification键盘即将弹出时,调用的方法会连续走两次,然后程序就会崩掉.系统打印-[UITextField textInputView]: message sent to deallocated instance 0x156d12720
    奇葩问题...
    在项目中,为了使弹出的键盘不遮挡输入框,我添加了一个分类.这个分类在键盘弹出的时候判断如果键盘遮挡输入框,会让控制器的view上移.

    @implementation UITextField (autoAdjust)
    
    - (void)setAutoAdjust: (BOOL)autoAdjust
    {
        if (autoAdjust) {
            [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object: nil];
            [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object: nil];
        } else {
            [[NSNotificationCenter defaultCenter] removeObserver: self];
        }
    }
    
    - (void)keyboardWillShow: (NSNotification *)notification
    {
        if (self.isFirstResponder) {
            CGPoint relativePoint = [self convertPoint: CGPointZero toView: [UIApplication sharedApplication].keyWindow];
            
            CGFloat keyboardHeight = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height;
            CGFloat actualHeight = CGRectGetHeight(self.frame) + relativePoint.y + keyboardHeight;
            CGFloat overstep = actualHeight - CGRectGetHeight([UIScreen mainScreen].bounds) + 5;
            if (overstep > 0) {
                CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
                CGRect frame = [UIScreen mainScreen].bounds;
                frame.origin.y -= overstep + 10;
                [UIView animateWithDuration: duration delay: 0 options: UIViewAnimationOptionCurveLinear animations: ^{
                    [UIApplication sharedApplication].keyWindow.frame = frame;
                } completion: nil];
            }
        }
    }
    
    - (void)keyboardWillHide: (NSNotification *)notification
    {
        if (self.isFirstResponder) {
            CGFloat duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
            CGRect frame = [UIScreen mainScreen].bounds;
            [UIView animateWithDuration: duration delay: 0 options: UIViewAnimationOptionCurveLinear animations: ^{
                [UIApplication sharedApplication].keyWindow.frame = frame;
            } completion: nil];
        }
    }
    
    - (void)dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver: self];
    }
    
    @end
    

    结果查询了以后发现,就是这个分类出现了问题.解决的方法是不使用这个分类而在控制器中专门写代码控制view的移动.
    这个问题的奇葩之处在于即便不使用,而且在代码中即使没有import这个分类,程序依然会报错.
    引以为鉴,引以为鉴.

    相关文章

      网友评论

          本文标题:一个关于UITextView的奇葩问题 :-[UITextFie

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