简体   繁体   English

iOS 10.3:如果将NSStrikethroughStyleAttributeName应用于NSMutableAttributedString的子范围,则不会渲染

[英]iOS 10.3: NSStrikethroughStyleAttributeName is not rendered if applied to a sub range of NSMutableAttributedString

A strikethrough (single, double, ...) added as attribute to an instance of NSMutableAttributedString is not rendered if the apply range is not the whole string range. 如果应用范围不是整个字符串范围,则不会渲染作为属性添加到NSMutableAttributedString实例的删除线(单,双,...)。

This happens using addAttribute(_ name: String, value: Any, range: NSRange) , insert(_ attrString: NSAttributedString, at loc: Int) , append(_ attrString: NSAttributedString) , ... 使用addAttribute(_ name: String, value: Any, range: NSRange)insert(_ attrString: NSAttributedString, at loc: Int)append(_ attrString: NSAttributedString) ,...

Broken by Apple in early iOS 10.3 betas, and not fixed in 10.3 final. 苹果在早期的iOS 10.3 Beta中被苹果破解,在10.3最终版本中未修复。

Credit: https://openradar.appspot.com/31034683 信用: https//openradar.appspot.com/31034683

Setting the baseline offset seems to fix it: 设置基线偏移量似乎可以解决此问题:

[attributedStr addAttribute:NSBaselineOffsetAttributeName value:@0 range:NSMakeRange(0, 10)];
[attributedStr addAttribute:NSStrikethroughStyleAttributeName value:@2 range:NSMakeRange(0, 10)];

This is a known bug in iOS 10.3 这是iOS 10.3中的已知错误

Adding a NSBaselineOffsetAttributeName , as explained here , to the attributed string brings back the strikethrough line. 添加NSBaselineOffsetAttributeName ,如解释在这里 ,在属性串带回删除线。 Overriding drawText:in: can be slow especially on Collection View or Table View Cells. 覆盖drawText:in:可能很慢,尤其是在“集合视图”或“表格视图”单元格上。

Found a workaround for our specific scenario (we don't specify any styling with UILabel's properties, but all with NSAttributedString attributes): 找到了针对我们特定情况的解决方法(我们没有使用UILabel的属性指定任何样式,而是全部使用NSAttributedString属性来指定):

/// 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)
        }
    }
}

NOTE: if you mix UILabel's styling properties with NSAttributedString attributes, you should think of creating a new attributed string before rendering, apply UILabel's styling on it and then re-apply all attributedText 's attributes over it. 注意:如果将UILabel的样式属性与NSAttributedString属性混合使用,则应考虑在渲染之前创建新的属性字符串,在其上应用UILabel的样式,然后在其上重新应用所有attributedText的属性。

swift 3 working code tested with 10.3 快速的3工作代码经过10.3测试

let attributeString: NSMutableAttributedString = NSMutableAttributedString(string: "₹3500")
attributeString.addAttribute(NSBaselineOffsetAttributeName, value: 0, range: NSMakeRange(0, attributeString.length))
attributeString.addAttribute(NSStrikethroughStyleAttributeName, value: 1, range: NSMakeRange(0, attributeString.length))
productPriceLabel.attributedText = attributeString

Swift 4 斯威夫特4

let text = "Hello World"
let textRange = NSMakeRange(0, text.count)
let attributedText = NSMutableAttributedString(string: text)
attributedText.addAttribute(NSAttributedStringKey.strikethroughStyle,
                            value: NSUnderlineStyle.styleSingle.rawValue,
                            range: textRange)
myLabel.attributedText = attributedText

Its a bug known to Xcode 8.3 (8E3004b) / iOS 10.3, with this workaround NO extra line of code is need, just add [NSBaselineOffsetAttributeName:0] when declaring NSMutableAttributedString() 它是Xcode 8.3(8E3004b)/ iOS 10.3已知的错误,使用此替代方法无需额外的代码行,只需在声明NSMutableAttributedString()时添加[NSBaselineOffsetAttributeName:0]

let attrStr = NSMutableAttributedString(string: YOUR_STRING_HERE, attributes: [NSBaselineOffsetAttributeName : 0])

// Now if you add the strike-through attribute to a range, it will work
attrStr.addAttributes([
    NSFontAttributeName: UIFont.boldSystemFont(ofSize: 24),
    NSStrikethroughStyleAttributeName: 1
], range: NSRange)

对于Swift 5, NSBaselineOffsetAttributeName通过kCTBaselineOffsetAttributeName进行了更改,并将更改每个新版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 NSStrikethroughStyleAttributeName,如何在iOS 10.3中删除字符串? - NSStrikethroughStyleAttributeName , How to strike out the string in iOS 10.3? NSMutableAttributedString的属性NSStrikethroughStyleAttributeName在iOS8中无法正常工作 - NSMutableAttributedString's attribute NSStrikethroughStyleAttributeName doesn't work correctly in iOS8 iOS:未呈现 NSMutableAttributedString.AddAttributes。 (Xamarin) - iOS: NSMutableAttributedString.AddAttributes not rendered. (Xamarin) 在iOS中为特定范围的NSMutableAttributedString添加属性时崩溃 - Getting crash while adding attributes to NSMutableAttributedString for a particular range in iOS NSMutableAttributedString的多个范围 - Multiple range on NSMutableAttributedString 在iOS中使用NSMutableAttributedString作为常量 - Using NSMutableAttributedString as a Constant in iOS iOS - 将所有NSMutableAttributedString属性复制到另一个NSMutableAttributedString - iOS - copy all NSMutableAttributedString attributes to another NSMutableAttributedString iOS崩溃@ NSMutableAttributedString - iOS crash @ NSMutableAttributedString iOS 3.1.3上的NSMutableAttributedString - NSMutableAttributedString on iOS 3.1.3 在iOS 8和iOS 9中,NSMutableAttributedString在特定范围内不会以不同的颜色显示字符串 - NSMutableAttributedString doesn't show string in different color for some specific range in iOS 8 & iOS 9
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM