由于未捕获的异常'CALayerInvalidGeometry',应用程序终止,原因是'CALayer bounds contains NaN: [0 nan; 280 524]'。

13

我正在开发一款书籍应用程序,用户可以在TextView上更改字体大小。

当用户更改字体大小时,应用程序会保存当前文本位置,以便在用户更改字体大小后不改变该位置。

在大多数情况下,它运行得很好,但有时,当用户更改字体大小时,应用程序会出现此类错误,我仍然无法确定如何修复它。

由于未捕获的异常 'CALayerInvalidGeometry' 而终止应用程序,原因是:'CALayer bounds contains NaN: [0 nan; 280 524]' * First throw call stack: (0x3231e3e7 0x3a019963 0x3231e307 0x33edb4d7 0x33edb30d 0x3419141f 0x3419b82f 0x342d1cf1 0x3414f80d 0xe7bf1 0xe607d 0xfad35 0x34218087 0x34218111 0x34218087 0x3421803b 0x34218015 0x342178cb 0x34217db9 0x341405f9 0x3412d8e1 0x3412d1ef 0x35e455f7 0x35e45227 0x322f33e7 0x322f338b 0x322f220f 0x3226523d 0x322650c9 0x35e4433b 0x341812b9 0xdf9f1 0xdf978) libc++abi.dylib: terminate called throwing an exception

由于此问题偶尔出现,因此我也无法100%复现此问题。

这是代码。 有人有什么想法来修复吗? 提前致谢。

- (UITextRange *)getCurrentTextRange:(UITextView *)textView {

    CGRect bounds               = textView.bounds;
    UITextPosition *start       = [textView characterRangeAtPoint:bounds.origin].start;
    UITextPosition *end         = [textView positionFromPosition:start offset:1];
    UITextRange *textRange      = [textView textRangeFromPosition:start toPosition:end];

    return textRange;
}

- (void)changeFontSize:(UIButton*)button {

    UITextRange *textRange  = [self getCurrentTextRange:_textView];
    int fontSize            = [[NSUserDefaults standardUserDefaults] integerForKey:@"fontSize"];

    //button.tag == 1 => decreaseFontSize
    if (button.tag == 1) {

        //set a minimum size
        if (fontSize <= [LSUniversalManager getFontSizeForMinimum]) {
            return;
        }

        fontSize--;

    //button.tag == 2 => increaseFontSize
    } else if (button.tag == 2) {        
        fontSize++;
    }

    _textView.font      = [UIFont systemFontOfSize:fontSize];
    [[NSUserDefaults standardUserDefaults] setInteger:fontSize forKey:@"fontSize"];

    //avoid shifting the scroll position after changing font size
    CGRect rect = [_textView firstRectForRange:textRange];
    [_textView setContentOffset:CGPointMake(0, rect.origin.y)];
}
2个回答

21

在这里,您可能会得到一个无效的输出,导致rect的值为NaN(一种特殊的浮点数值,表示“无效的浮点数”,最常见的原因是被零除)。 您是否有可能将无效或荒谬的UITextRange传递给了-firstRectForRange? 如果UITextPosition *start引用文本中的最后一个字符,然后创建另一个恰好超过末尾的字符位置会发生什么?


感谢您的评论,我相信当textRange中有无效值时,[_textView firstRectForRange:textRange]会出现这种情况,就像您所提到的那样。您认为我可以在使用firstRectForRange之前检查textRange是否有效吗?很抱歉,我无法确定如何重现此情况。
如果UITextPosition * start引用了什么会发生...
也许我应该尝试一下这个。 UITextPosition * end = [textView characterRangeAtPoint:CGPointMake(CGRectGetMaxX(bounds),CGRectGetMaxY(bounds))].end; 在getCurrentTextRange方法中。
- Umeumeume
1
如果其他人遇到了这个问题...我有一个UIPopoverController从屏幕边缘的按钮呈现,并意外地将允许的方向朝向外部。没有足够的空间呈现==这个错误。 - WCByrne
在我的情况下,这是由于尝试显示一个UIWebView而触发的,该UIWebView是从包含无效数据的NSData对象创建的,可能是来自空文件。 - jk7

1
在我的情况下,代码执行了 0.0 / 0.0,导致结果为 -nan(无穷大),并进一步用于转换为 double。
我添加了一个保护条件以确保值大于 0.0。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接