1

The application I am working on encountered an issue when testing with iOS 10.3 Simulator via XCode 8.3 beta 2, where the superscript in AttributedString displayed on the same line with normal text. For iOS 10.2.x and below, it is displaying correctly.

iOS 10.3 screenshot: https://www.dropbox.com/s/p5v71g722cg5qhy/Screen%20Shot%202017-02-21%20at%2010.24.21%20AM.png?dl=0

iOS 10.2.x and below screenshot: https://www.dropbox.com/s/lcfsic6xyz953qp/Screen%20Shot%202017-02-21%20at%2010.19.17%20AM.png?dl=0

Here's how I handled the text:

  • Initially, the string is in HTML format, and tag for the text "8,9" above

<html>  
<head>  
     <style> body { color: #554344 ; font-family: \'MyCustomFont\'; font-size: 18px; } sup { font-size: 13px; } </style>  
</head>  
<body>  
     ABCdef<sup>1,2,3,8,9</sup>  
</body>  
</html>  
  • The html string then converted into NSAttributedString using the following script

private func convertHTMLToAttributedString(string: String) -> NSAttributedString {  
       guard let data = string.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return NSAttributedString() }  
       return try! NSAttributedString(  
           data: data,  
           options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],  
           documentAttributes: nil)  
   } 
  • The NSAttributedString then will be rendered via UILabel.attributedText This is the attributedText description:

1,2,3,8,9{  
   NSColor = "kCGColorSpaceModelRGB 0.333333 0.262745 0.266667 1 ";  
   NSFont = "<UICTFont: 0x7fed0a469880> font-family: \"MyCustomFont\"; font-weight: normal; font-style: normal; font-size: 10.00pt";  
   NSKern = 0;  
   NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 13/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";  
   NSStrokeColor = "kCGColorSpaceModelRGB 0.333333 0.262745 0.266667 1 ";  
   NSStrokeWidth = 0;  
   NSSuperScript = 1;  
}

Note: I thought the issue was related to our custom font, but the issue still happen when we use the default font.

Is this an issue related with Swift 3.1 and should be fixed?

Huy Nguyen
  • 51
  • 1
  • 5
  • I recently discovered the same effect (`NSSuperScript` seems to have no effect) within an macOS app. – ixany Mar 06 '17 at 14:18

1 Answers1

1

We found that it's an issue in UILabel's attributed text rendering in iOS 10.3, not Swift 3.1-related. Affected strike-through style for us.

For our specific scenario (we have all attributes specified in NSAttributedString, not using UILabel's properties) this is the solution:

/// This UILabel subclass accomodates conditional fix for NSAttributedString rendering broken by Apple in iOS 10.3
final class PriceLabel: UILabel {

    override func drawText(in rect: CGRect) {
        guard let attributedText = attributedText else {
            super.drawText(in: rect)
            return
        }

        if #available(iOS 10.3, *) {
            attributedText.draw(in: rect)
        } else {
            super.drawText(in: rect)
        }
    }
}
rshev
  • 4,086
  • 1
  • 23
  • 32
  • Even though my label only has set the `text` property, `attributedText` is not nil (it contains the same string, plus attributes for `NSColor`, `NSFont`, and `NSParagraphStyle`). Therefore the guard statement in the above code always returns true. – koen Apr 05 '17 at 01:27
  • @Koen it's not guaranteed to be non-nil though. Who knows what they might change in the subsequent iOS version or if it was non-nil pre-iOS 10. – rshev Apr 05 '17 at 07:39
  • Yeah, good point. Still interesting why `attributedText` gets set when only `text` is set. But that's outside the scope of this question. – koen Apr 05 '17 at 12:34