Remplacer la sous-chaîne de NSAtsortingbutedSsortingng par une autre NSAtsortingbutedSsortingng

Je veux remplacer une sous-chaîne (par exemple, @"replace" ) d’une NSAtsortingbutedSsortingng par une autre NSAtsortingbutedSsortingng .

Je cherche une méthode équivalente à la méthode ssortingngByReplacingOccurrencesOfSsortingng:withSsortingng: NSSsortingng ssortingngByReplacingOccurrencesOfSsortingng:withSsortingng: pour NSAtsortingbutedSsortingng .

  1. Convertissez votre chaîne atsortingbuée en une instance de NSMutableAtsortingbutedSsortingng .

  2. La chaîne atsortingbuée mutable a une propriété mutableSsortingng . Selon la documentation:

    “Le récepteur suit les modifications apscopes à cette chaîne et conserve ses mappages d’atsortingbuts à jour.”

    Vous pouvez donc utiliser la chaîne mutable résultante pour exécuter le remplacement avec replaceOccurrencesOfSsortingng:withSsortingng:options:range:

Voici comment vous pouvez modifier la chaîne de NSMutableAtsortingbutedSsortingng, tout en conservant ses atsortingbuts:

Rapide:

 // first we create a mutable copy of atsortingbuted text let originalAtsortingbutedText = nameLabel.atsortingbutedText?.mutableCopy() as! NSMutableAtsortingbutedSsortingng // then we replace text so easily let newAtsortingbutedText = originalAtsortingbutedText.mutableSsortingng.setSsortingng("new text to replace") 

Objectif c:

 NSMutableAtsortingbutedSsortingng *newAttrStr = [atsortingbtedTxt.mutableSsortingng setSsortingng:@"new ssortingng"]; 

Dans mon cas, la manière suivante était la seule (testée sur iOS9):

 NSAtsortingbutedSsortingng *atsortingbutedSsortingng = ...; NSAtsortingbutedSsortingng *anotherAtsortingbutedSsortingng = ...; //the ssortingng which will replace while ([atsortingbutedSsortingng.mutableSsortingng containsSsortingng:@"replace"]) { NSRange range = [atsortingbutedSsortingng.mutableSsortingng rangeOfSsortingng:@"replace"]; [atsortingbutedSsortingng replaceCharactersInRange:range withAtsortingbutedSsortingng:anotherAtsortingbutedSsortingng]; } 

Bien sûr, ce sera bien de trouver une autre solution.

Avec Swift 4 et iOS 11, vous pouvez utiliser l’un des 2 moyens suivants pour résoudre votre problème.


#1. Utilisation de la replaceCharacters(in:with:) NSMutableAtsortingbutedSsortingng replaceCharacters(in:with:)

NSMutableAtsortingbutedSsortingng a une méthode appelée replaceCharacters(in:with:) . replaceCharacters(in:with:) a la déclaration suivante:

Remplace les caractères et les atsortingbuts dans une plage donnée par les caractères et les atsortingbuts de la chaîne atsortingbuée donnée.

 func replaceCharacters(in range: NSRange, with attrSsortingng: NSAtsortingbutedSsortingng) 

Le code Playground ci-dessous montre comment utiliser replaceCharacters(in:with:) afin de remplacer une sous-chaîne d’une instance NSMutableAtsortingbutedSsortingng par une nouvelle instance NSMutableAtsortingbutedSsortingng :

 import UIKit // Set initial atsortingbuted ssortingng let initialSsortingng = "This is the initial ssortingng" let atsortingbutes = [NSAtsortingbutedSsortingngKey.foregroundColor : UIColor.red] let mutableAtsortingbutedSsortingng = NSMutableAtsortingbutedSsortingng(ssortingng: initialSsortingng, atsortingbutes: atsortingbutes) // Set new atsortingbuted ssortingng let newSsortingng = "new" let newAtsortingbutes = [NSAtsortingbutedSsortingngKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue] let newAtsortingbutedSsortingng = NSMutableAtsortingbutedSsortingng(ssortingng: newSsortingng, atsortingbutes: newAtsortingbutes) // Get range of text to replace guard let range = mutableAtsortingbutedSsortingng.ssortingng.range(of: "initial") else { exit(0) } let nsRange = NSRange(range, in: mutableAtsortingbutedSsortingng.ssortingng) // Replace content in range with the new content mutableAtsortingbutedSsortingng.replaceCharacters(in: nsRange, with: newAtsortingbutedSsortingng) 

# 2. Utiliser la replaceOccurrences(of:with:options:range:) NSMutableSsortingng replaceOccurrences(of:with:options:range:)

NSMutableSsortingng a une méthode appelée replaceOccurrences(of:with:options:range:) . replaceOccurrences(of:with:options:range:) a la déclaration suivante:

Remplace toutes les occurrences d’une chaîne donnée dans une plage donnée par une autre chaîne donnée, en renvoyant le nombre de remplacements.

 func replaceOccurrences(of target: Ssortingng, with replacement: Ssortingng, options: NSSsortingng.CompareOptions = [], range searchRange: NSRange) -> Int 

Le code Playground ci-dessous montre comment utiliser replaceOccurrences(of:with:options:range:) afin de remplacer une sous-chaîne d’une instance NSMutableAtsortingbutedSsortingng par une nouvelle instance NSMutableAtsortingbutedSsortingng :

 import UIKit // Set initial atsortingbuted ssortingng let initialSsortingng = "This is the initial ssortingng" let atsortingbutes = [NSAtsortingbutedSsortingngKey.foregroundColor : UIColor.red] let mutableAtsortingbutedSsortingng = NSMutableAtsortingbutedSsortingng(ssortingng: initialSsortingng, atsortingbutes: atsortingbutes) // Set new ssortingng let newSsortingng = "new" // Replace replaceable content in mutableAtsortingbutedSsortingng with new content let totalRange = NSRange(location: 0, length: mutableAtsortingbutedSsortingng.ssortingng.count) _ = mutableAtsortingbutedSsortingng.mutableSsortingng.replaceOccurrences(of: "initial", with: newSsortingng, options: [], range: totalRange) // Get range of text that requires new atsortingbutes guard let range = mutableAtsortingbutedSsortingng.ssortingng.range(of: newSsortingng) else { exit(0) } let nsRange = NSRange(range, in: mutableAtsortingbutedSsortingng.ssortingng) // Apply new atsortingbutes to the text matching the range let newAtsortingbutes = [NSAtsortingbutedSsortingngKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue] mutableAtsortingbutedSsortingng.setAtsortingbutes(newAtsortingbutes, range: nsRange) 

J’ai dû mettre du texte en gras dans les balises , voici ce que j’ai fait:

 - (NSAtsortingbutedSsortingng *)boldSsortingng:(NSSsortingng *)ssortingng { UIFont *boldFont = [UIFont boldSystemFontOfSize:14]; NSMutableAtsortingbutedSsortingng *atsortingbutedDescription = [[NSMutableAtsortingbutedSsortingng alloc] initWithSsortingng:ssortingng]; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@".*?(.*?)<\\/b>.*?" options:NSRegularExpressionCaseInsensitive error:NULL]; NSArray *myArray = [regex matchesInSsortingng:ssortingng options:0 range:NSMakeRange(0, ssortingng.length)] ; for (NSTextCheckingResult *match in myArray) { NSRange matchRange = [match rangeAtIndex:1]; [atsortingbutedDescription addAtsortingbute:NSFontAtsortingbuteName value:boldFont range:matchRange]; } while ([atsortingbutedDescription.ssortingng containsSsortingng:@""] || [atsortingbutedDescription.ssortingng containsSsortingng:@""]) { NSRange rangeOfTag = [atsortingbutedDescription.ssortingng rangeOfSsortingng:@""]; [atsortingbutedDescription replaceCharactersInRange:rangeOfTag withSsortingng:@""]; rangeOfTag = [atsortingbutedDescription.ssortingng rangeOfSsortingng:@""]; [atsortingbutedDescription replaceCharactersInRange:rangeOfTag withSsortingng:@""]; } return atsortingbutedDescription; } 
 NSMutableAtsortingbutedSsortingng *result = [[NSMutableAtsortingbutedSsortingng alloc] initWithSsortingng:@"I am a boy."]; [result addAtsortingbute:NSForegroundColorAtsortingbuteName value:[UIColor blackColor] range:NSMakeRange(0, [result length])]; NSMutableAtsortingbutedSsortingng *replace = [[NSMutableAtsortingbutedSsortingng alloc] initWithSsortingng:@"a"]; [replace addAtsortingbute:NSForegroundColorAtsortingbuteName value:[UIColor redColor] range:NSMakeRange(0, [replace length])]; [result replaceCharactersInRange:NSMakeRange(5, [replace length]) withAtsortingbutedSsortingng:replace]; 

Je trouve que toutes les autres réponses ne fonctionnent pas. Voici comment j’ai remplacé le contenu d’une chaîne NSAtsortingbuted dans une extension de catégorie:

 func ssortingngWithSsortingng(ssortingngToReplace:Ssortingng, replacedWithSsortingng newSsortingngPart:Ssortingng) -> NSMutableAtsortingbutedSsortingng { let mutableAtsortingbutedSsortingng = mutableCopy() as! NSMutableAtsortingbutedSsortingng let mutableSsortingng = mutableAtsortingbutedSsortingng.mutableSsortingng while mutableSsortingng.containsSsortingng(ssortingngToReplace) { let rangeOfSsortingngToBeReplaced = mutableSsortingng.rangeOfSsortingng(ssortingngToReplace) mutableAtsortingbutedSsortingng.replaceCharactersInRange(rangeOfSsortingngToBeReplaced, withSsortingng: newSsortingngPart) } return mutableAtsortingbutedSsortingng } 

J’ai une exigence spécifique et fixe comme ci-dessous. Cela pourrait aider quelqu’un.

Condition requirejse: Dans le storyboard, texte enrichi directement ajouté à l’atsortingbut UITextView qui contient un mot “Version de l’application: 1.0”. Maintenant, je dois dynamiser le numéro de version en le lisant à partir de plist info.

Solution: Supprimé le numéro de version 1.0 du storyboard, il suffit de garder “App Version:” et ajouté sous le code.

 NSAtsortingbutedSsortingng *atsortingbute = self.firsttextView.atsortingbutedText; NSMutableAtsortingbutedSsortingng *mutableAtsorting = [[NSMutableAtsortingbutedSsortingng alloc] initWithAtsortingbutedSsortingng:atsortingbute]; NSSsortingng *appVersionText = @"App Version:"; if ([[mutableAtsorting mutableSsortingng] containsSsortingng:appVersionText]) { NSDictionary* infoDict = [[NSBundle mainBundle] infoDictionary]; NSSsortingng* version = [infoDict objectForKey:@"CFBundleShortVersionSsortingng"]; NSSsortingng *newappversion = [NSSsortingng ssortingngWithFormat:@"%@ %@",appVersionText,version] ; [[mutableAtsorting mutableSsortingng] replaceOccurrencesOfSsortingng:appVersionText withSsortingng:newappversion options:NSCaseInsensitiveSearch range:NSMakeRange(0, mutableAtsorting.length)]; self.firsttextView.atsortingbutedText = mutableAtsorting; } 

Terminé!! Mise à jour / modifié atsortingbutText.

Swift 4: mise à jour de l’excellente solution de Sunkas pour Swift 4 et extension “extension”. Il suffit de découper ce clip dans votre ViewController (en dehors de la classe) et de l’utiliser.

 extension NSAtsortingbutedSsortingng { func ssortingngWithSsortingng(ssortingngToReplace: Ssortingng, replacedWithSsortingng newSsortingngPart: Ssortingng) -> NSMutableAtsortingbutedSsortingng { let mutableAtsortingbutedSsortingng = mutableCopy() as! NSMutableAtsortingbutedSsortingng let mutableSsortingng = mutableAtsortingbutedSsortingng.mutableSsortingng while mutableSsortingng.contains(ssortingngToReplace) { let rangeOfSsortingngToBeReplaced = mutableSsortingng.range(of: ssortingngToReplace) mutableAtsortingbutedSsortingng.replaceCharacters(in: rangeOfSsortingngToBeReplaced, with: newSsortingngPart) } return mutableAtsortingbutedSsortingng } }