web-dev-qa-db-fra.com

iOS 10.3: NSStrikethroughStyleAttributeName n'est pas rendu s'il est appliqué à une sous-plage de NSMutableAttributedString

Un barré (simple, double, ...) ajouté comme attribut à une instance de NSMutableAttributedString n'est pas rendu si la plage d'application n'est pas la plage de chaînes entière.

Cela se produit en utilisant addAttribute(_ name: String, value: Any, range: NSRange), insert(_ attrString: NSAttributedString, at loc: Int), append(_ attrString: NSAttributedString), ...

Brisé par Apple au début de la version bêta d'iOS 10.3, et non corrigé dans la version 10.3 finale.

Crédit: https://openradar.appspot.com/3103468

46
rshev

L'ajout d'un NSBaselineOffsetAttributeName, comme expliqué ici , à la chaîne attribuée ramène la ligne barrée. Substitution drawText:in: peut être lent, en particulier dans les cellules Vue Collection ou Vue Table.

24
Mugunth

La définition du décalage de la ligne de base semble le corriger:

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

Ceci est connu bug dans iOS 10.3

88
tommybananas

Nous avons trouvé une solution de contournement pour notre scénario spécifique (nous ne spécifions aucun style avec les propriétés d'UILabel, mais tous avec les attributs 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)
        }
    }
}

REMARQUE: si vous mélangez les propriétés de style d'UILabel avec les attributs NSAttributedString, vous devriez penser à créer une nouvelle chaîne attribuée avant le rendu, appliquer le style UILabel dessus, puis réappliquer tous les attributs de attributedText dessus.

14
rshev

Swift 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
10
Yuchen Zhong

Code de travail Swift 3 testé avec 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
10
Velu Loganathan

C'est un bogue connu de Xcode 8.3 (8E3004b)/iOS 10.3, avec cette solution de contournement AUCUNE ligne de code supplémentaire n'est nécessaire, ajoutez simplement [NSBaselineOffsetAttributeName:0] Lors de la déclaration de NSMutableAttributedString()

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)
4
AamirR