Comment puis-je replace du text dans UITextView avec le support de NSUndoManager?

Je veux être en mesure de replace du text dans un UITextView par programmation, donc j'ai écrit cette méthode comme une catégorie UITextView:

- (void) replaceCharactersInRange:(NSRange)range withSsortingng:(NSSsortingng *)newText{ self.scrollEnabled = NO; NSMutableSsortingng *textStorage = [self.text mutableCopy]; [textStorage replaceCharactersInRange:range withSsortingng:newText]; //replace text but undo manager is not working well [[self.undoManager prepareWithInvocationTarget:self] replaceCharactersInRange:NSMakeRange(range.location, newText.length) withSsortingng:[textStorage subssortingngWithRange:range]]; NSLog(@"before replacing: canUndo:%d", [self.undoManager canUndo]); //prints YES self.text = textStorage; NSLog(@"after replacing: canUndo:%d", [self.undoManager canUndo]); //prints NO if (![self.undoManager isUndoing])[self.undoManager setActionName:@"replace characters"]; [textStorage release]; //new range: range.location = range.location + newText.length; range.length = 0; self.selectedRange = range; self.scrollEnabled = YES; } 

Cela fonctionne mais NSUndoManager arrête de fonctionner (il semble être réinitialisé) juste après avoir fait self.text=textStorage J'ai trouvé une API privée: -insertText:(NSSsortingng *) qui peut faire le travail mais qui sait si Apple va approuver mon application si je l'utilise. Est-il possible de replace le text dans UITextView avec le support NSUndoManager? Ou peut-être qu'il me manque quelque chose ici?

Il n'y a en fait aucune raison pour que des hacks ou des catégories personnalisées accomplissent cela. Vous pouvez utiliser la méthode replaceRange:withText: UITextInput Protocol replaceRange:withText: Pour insert du text, vous pouvez simplement faire:

 [textView replaceRange:textView.selectedTextRange withText:replacementText]; 

Cela fonctionne à partir de iOS 5.0. Annuler fonctionne automatiquement et il n'y a pas de problèmes de défilement bizarre.

Après avoir trébuché sur ce problème et avoir eu les cheveux gris, j'ai finalement trouvé une solution satisfaisante. C'est un peu ringard, mais ça marche comme un charme. L'idée est d'utiliser le support de copyr-coller de travail que UITextView offre! Je pense que vous pourriez être intéressé:

 - (void)insertText:(NSSsortingng *)insert { UIPasteboard *pboard = [UIPasteboard generalPasteboard]; // Clear the current pasteboard NSArray *oldItems = [pboard.items copy]; pboard.items = nil; // Set the new content to copy pboard.ssortingng = insert; // Paste [self paste: nil]; // Restore pasteboard pboard.items = oldItems; [oldItems release]; } 

EDIT: Bien sûr, vous pouvez personnaliser ce code pour insert du text à n'importe quelle position dans la vue du text. Définissez simplement le paramètre selectedRange avant d'appeler le paste .

Ne devrait-il pas être

 [[self.undoManager prepareWithInvocationTarget:self] replaceCharactersInRange:NSMakeRange(range.location, newText.length) withSsortingng:[self.text subssortingngWithRange:range]]; 

Et vous pouvez probablement supprimer la string mutable et juste faire,

 self.text = [self.text ssortingngByReplacingCharactersInRange:range withSsortingng:newText];