An NSMutableAttributedString with some attributes was correctly displayed in an UILabel up until iOS 12, but is wrong/different on iOS 14:
The string "bukskin" has two letters coloured red, the last 4 letters are underlined, correctly on iOS 12:
On iOS 14 the underlining extends beyond the end of the word for about two letters. This seems to only happen if the underlining is at the END of the string:
Dumps of the string attributes for iOS 12 and iOS 14 look identical, yet the string is displayed differently on screen in an UILabel, on iOS 14. Am I missing something?
Dump for iOS 12 (using enumerateAttributesInRange):
word=bukskin attributed_word=b{
NSColor = "UIExtendedSRGBColorSpace 0.8125 0 0 1";
NSLigature = 0;
NSUnderline = 0;
}uk{
NSColor = "UIExtendedGrayColorSpace 0 1";
NSLigature = 0;
NSUnderline = 0;
}s{
NSColor = "UIExtendedGrayColorSpace 0 1";
NSLigature = 0;
NSUnderline = 1;
}k{
NSColor = "UIExtendedSRGBColorSpace 0.8125 0 0 1";
NSLigature = 0;
NSUnderline = 1;
}in{
NSColor = "UIExtendedGrayColorSpace 0 1";
NSLigature = 0;
NSUnderline = 1;
} attrs={
NSColor = "UIExtendedGrayColorSpace 0 1";
NSLigature = 0;
NSUnderline = 1;
}
Dump for iOS14:
word=bukskin attributed_word=b{
NSColor = "UIExtendedSRGBColorSpace 0.8125 0 0 1";
NSLigature = 0;
NSUnderline = 0;
}uk{
NSColor = "<UIDynamicSystemColor: 0x600003682440; name = labelColor>";
NSLigature = 0;
NSUnderline = 0;
}s{
NSColor = "<UIDynamicSystemColor: 0x600003682440; name = labelColor>";
NSLigature = 0;
NSUnderline = 1;
}k{
NSColor = "UIExtendedSRGBColorSpace 0.8125 0 0 1";
NSLigature = 0;
NSUnderline = 1;
}in{
NSColor = "<UIDynamicSystemColor: 0x600003682440; name = labelColor>";
NSLigature = 0;
NSUnderline = 1;
} attrs={
NSColor = "<UIDynamicSystemColor: 0x600003682440; name = labelColor>";
NSLigature = 0;
NSUnderline = 1;
}
The link in Tarun Tyagi's comment hints at a fix: setting the baseline offset to 0 for the entire attributed string. That seems to work. Right after initialising I now do:
[att_word addAttribute:NSBaselineOffsetAttributeName value:[NSNumber numberWithInt:0] range:NSMakeRange(0, att_word.length)];
I'll file a bug with Apple.
The attributes dump now is:
word=bukskin attributed_word=b{
NSBaselineOffset = 0;
NSColor = "UIExtendedSRGBColorSpace 0.8125 0 0 1";
NSLigature = 0;
NSUnderline = 0;
}uk{
NSBaselineOffset = 0;
NSColor = "<UIDynamicSystemColor: 0x600000506f00; name = labelColor>";
NSLigature = 0;
NSUnderline = 0;
}s{
NSBaselineOffset = 0;
NSColor = "<UIDynamicSystemColor: 0x600000506f00; name = labelColor>";
NSLigature = 0;
NSUnderline = 1;
}k{
NSBaselineOffset = 0;
NSColor = "UIExtendedSRGBColorSpace 0.8125 0 0 1";
NSLigature = 0;
NSUnderline = 1;
}in{
NSBaselineOffset = 0;
NSColor = "<UIDynamicSystemColor: 0x600000506f00; name = labelColor>";
NSLigature = 0;
NSUnderline = 1;
} attrs={
NSBaselineOffset = 0;
NSColor = "<UIDynamicSystemColor: 0x600000506f00; name = labelColor>";
NSLigature = 0;
NSUnderline = 1;
}