iOS 7 BUG - NSAttributedString不显示

27

上周我提出了一个有关模拟器中NSAttributedString无法显示的问题:iOS 7 Simulator Bug - NSAttributedString does not appear

不幸的是,现在看来这不是模拟器的问题,而是iOS 7的问题。我已经在iPhone 5设备上重现了此问题。

该bug似乎是使用NSUnderlineStyleAttributeName和NSParagraphStyleAttributeName作为NSAttributedString的属性的组合造成的。

我目前只在两个iOS 7设备上测试过,并且该问题只在其中一个设备上出现。即使它们都升级到完全相同的版本:

  • 第一个安装iOS 7.0 (11A465)的iPhone 5:文字不显示

  • 第一个在升级到7.0.2(11A501)之后的iPhone 5:文字不显示

  • 第二个运行iOS 7.0 (11A4449d)的iPhone 5:文本正确显示

  • 第二个在升级到7.0.2(11A501)之后的iPhone 5:文字不显示

因此,看来苹果在iOS 7.0(11A4449d)之后引入了这个bug。我已向他们报告了这个问题,并将在得到任何反应时向您更新。

重现bug的步骤

如果您正在运行iOS 7.0.2,则应该能够重现此错误。

要么下载并在您的设备上运行此项目https://github.com/rohinnz/iOS-7-BUG---NSAttributedString-does-not-appear

要么

1)在Xcode 5中创建一个新的'Single View Application'。随便起名字。

2)在ViewController.m中,用以下代码替换viewDidLoad方法:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSMutableParagraphStyle* paragraph = [[NSMutableParagraphStyle alloc] init];
    paragraph.alignment = NSTextAlignmentCenter;

    NSAttributedString* attrStr = [[NSAttributedString alloc] initWithString:@"Lorem ipsum dolor sit" attributes:
                                   @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle),
                                     NSParagraphStyleAttributeName:paragraph}];

    UILabel* myLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 0, 0)];
    myLabel.backgroundColor = [UIColor greenColor];
    myLabel.attributedText = attrStr;
    [myLabel sizeToFit];

    [self.view addSubview:myLabel];
}

3)编译并在您的设备上运行。根据您的iOS 7版本,文本将显示或不显示。无论哪种情况,UILabel的背景颜色都将显示。

屏幕截图

iOS 7.0(11A465)的iPhone 5

iPhone 5 with iOS 7.0 (11A465)

iOS 7.0(11A4449d)的iPhone 5

iPhone 5 with iOS 7.0 (11A4449d)

我的问题

有人能在设备上再现此问题吗?


好主意,我很快会上传一些东西到Github。我已经向苹果提交了一个错误报告,但是我不指望他们很快回复,因为他们之前我提出的另一个iOS 7的bug还没有得到回复。 - RohinNZ
1
我通过在属性文本上使用backgroundcolor并在旋转设备时调整uilabel的大小,找到了类似的结果。如果我不使用backgroundcolor,一切都正常工作。但是使用backgroundcolor后,改变宽度后文本会消失。在旋转回原始状态后,文本又会出现。 - Jeanette Müller
UILabel存在一些bug。NSTextAttachments也会导致文本行消失,但与标签的高度成反比关系。请参考此问题:https://dev59.com/cmIk5IYBdhLWcg3wdd_Y - EthanB
我认为我的第二种解决方法,即让标签自行调整高度,是这个问题的完全可靠的解决方案。 - matt
你报告过这个 bug 吗?我也遇到了同样的问题。 - Paweł Brewczynski
显示剩余3条评论
7个回答

14

我已经找到了这个错误的解决方法。在你的 GitHub 代码中,要使用这个解决方法,你需要这样说:

NSAttributedString* attrStr = 
    [[NSAttributedString alloc] initWithString:@"Lorem ipsum dolor sit\n" // <---
    attributes:
        @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle),
        NSParagraphStyleAttributeName:paragraph}];

UILabel* myLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 0, 0)];
myLabel.backgroundColor = [UIColor greenColor];
myLabel.attributedText = attrStr;
[myLabel sizeToFit];

myLabel.numberOfLines = 2; // <---

我做了两个更改:我在您的原始字符串末尾添加了一个换行符,并将标签的numberOfLines设置为2。

解决方法的作用是强制标签的文本靠近标签顶部,这似乎解决了问题。换句话说,该bug似乎源于标签试图垂直居中其文本;如果通过调整标签的高度、numberOfLines和文本末尾多余的换行字符来故意使文本过长,则属性字符串将被绘制出来。

编辑 我刚刚发现了另一种类似的解决方法:让标签自动调整大小以适应文本。请参见我的代码和解释:https://dev59.com/cmIk5IYBdhLWcg3wdd_Y#19545193 在这段代码中,我从相反的端口执行相同的操作:我给标签一个固定的宽度约束但是一个灵活的高度约束,通过设置自己的高度,标签将其文本顶部贴合到其自身的顶部,从而能够正确地显示文本。换句话说,这只是另一种防止标签垂直居中其文本的方法,这似乎触发了该bug。

进一步的编辑 我有一种感觉,这个bug可能会在iOS 7.1中得到修复。


在iOS 8中遇到了这个问题。将numberOfLines设置为2就解决了问题。花费了近2个小时的时间来查找是否是我的错误,然后才在谷歌上搜索到这个问题。谢谢。 - kas-kad
同样在iOS 8中。花了很长时间来修复它!非常感谢。 - johnyorke

6

当我在UITableViewCell中设置UILabel文本的背景颜色时遇到了同样的问题。我的解决方法是在单元格中使用一个UserInteraction禁用的UITextView而不是UILabel,这样就可以解决问题。

更新:发现该问题仅出现在包含Basic UITableViewCell的UILabel中。

更新2:还发现当UILabel换行时,问题不会出现。一种解决方法是通过添加换行符和空格来强制文本换行。这个方法非常trick,但它确实有效。请确保将numberOfLines设置为0,并将lineBreakMode设置为NSLineBreakByWordWrapping。


3

哇,我花了一些时间才找到这个。看起来我和Indi有类似的问题。设置属性字符串的背景颜色会导致文本消失。我只能在运行iOS 7.0.3的设备上重现此问题。


3
我在我的应用程序中遇到了同样的问题。它在模拟器和我的设备上(iPhone 5 运行 7.0.2 (11A501))都出现了。后来我意识到,我的其他 ViewControllers 中的 UILabel 正确地显示使用 NSUnderlineStyleSingle 属性的 NSAttributedStrings。
经过一些故障排查,似乎如果您正在使用默认字体(我正在使用 System 17.0)并且您的 UILabel 的高度小于 62 像素,它将正确显示,无论您正在使用什么背景颜色、文本颜色或对齐方式。将 UILabel 的高度更改为大于 61 像素的值,允许自动调整大小为您更改高度,或将字体更改为自定义字体,都将导致 NSAttributedText 下划线消失。
起初,我认为这个问题可能是由于我将 UILabel 放置在新状态栏(或缺乏状态栏)后面,但即使在可能与此新功能交互的位置,高度规则仍然保持不变。我很难相信 UILabel 的高度会引起这样的问题,但这是我得出的结论。

绝对与高度有关,但以一种奇怪的方式:https://dev59.com/cmIk5IYBdhLWcg3wdd_Y - EthanB

1

解决方法:使用图像视图

CGRect rect = self.frame;

CGRect rr = [attribText boundingRectWithSize:rect.size options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesDeviceMetrics context:nil];
UIGraphicsBeginImageContextWithOptions(rr.size, NO, 0.);
[attribText drawWithRect:rr options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesDeviceMetrics context:nil];
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imView = [[UIImageView alloc]initWithImage:image];
[self addSubview:imView];

0

我注意到这个问题以类似的方式发生,但最终得出了不同的解决方案。字符串有时会消失,虽然上面提出的解决方案有助于确保文本不会消失,但文本经常显示出没有设置的任何属性(删除线、不同颜色等)。

以下是设置:

使用弹簧和支架构建的遗留项目,使用Xcode 6.1.1和iOS SDK 8.1进行构建。在iPad设备上比iPhone设备更容易注意到问题(在iPhone上约5%的时间与iPad上的95%相比)。无论我使用numberOfLinessizeToFit或其他方法,属性都无法在iPad或iPhone上100%正确显示。

解决方案是切换到自动布局并采用上述解决方案(numberOfLines = 2,对于我的情况,sizeToFit似乎是可选的)

似乎在水平拉伸UILabels时,带属性的文本存在错误。

希望这能帮助到某些人!


0
我之前也遇到了这个问题,似乎只在特定语言和 iOS 7.0 上表现出来。当我想要给中文文本加下划线时,出现了这个问题,不过我通过[label sizeToFit]解决了它。希望能有所帮助 ;)

Constantin.


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