J'écris un éditeur de texte pour Mac OS X. J'ai besoin d'afficher les caractères cachés dans un NSTextView (tels que les espaces, les tabulations et les caractères spéciaux). J'ai passé beaucoup de temps à chercher comment faire cela mais jusqu'ici je n'ai pas trouvé de réponse. Si quelqu'un pouvait me diriger dans la bonne direction, je serais reconnaissant.Afficher les caractères cachés dans NSTextView
Répondre
Jetez un oeil à la classe NSLayoutManager. Votre NSTextView sera associé à un gestionnaire de disposition, et le gestionnaire de disposition est responsable de l'association d'un caractère (espace, tabulation, etc.) avec un glyphe (l'image de ce personnage est dessinée à l'écran).
Dans votre cas, la méthode replaceGlyphAtIndex:withGlyph:
vous intéresserait probablement le plus, car elle vous permettrait de remplacer des glyphes individuels.
Ce que j'ai fait, c'est remplacer la méthode ci-dessous dans une sous-classe NSLayoutManager.
- (void)drawGlyphsForGlyphRange:(NSRange)range atPoint:(NSPoint)origin
{
[super drawGlyphsForGlyphRange:range atPoint:origin];
for (int i = range.location; i != range.location + range.length; i++)
{
// test each character in this range
// if appropriate replace it with -replaceGlyphAtIndex:withGlyph:
}
}
Je boucle l'index de chaque caractère. Le problème que j'ai maintenant est comment déterminer quel caractère est trouvé à chaque endroit. Dois-je utiliser une méthode NSLayoutManager ou demander à NSTextView lui-même? Les indices dans le premier sont-ils les mêmes que dans le second?
Je peux obtenir un glyphe individuel avec -glyphAtIndex: mais je n'arrive pas à comprendre comment déterminer le caractère auquel il correspond.
Vous obtenez le point de code du caractère de cette façon: NSString * completeString = [[self textStorage] string]; NSUInteger characterIndex = [self characterIndexForGlyphAtIndex: index]; unichar characterToCheck = [completeString characterAtIndex: characterIndex]; – JanX2
J'ai résolu le problème de la conversion entre les NSGlyphs et l'Unichar correspondant dans NSTextView. Le code ci-dessous fonctionne magnifiquement et remplace les espaces de balles pour le texte visible:
- (void)drawGlyphsForGlyphRange:(NSRange)range atPoint:(NSPoint)origin
{
NSFont *font = [[CURRENT_TEXT_VIEW typingAttributes]
objectForKey:NSFontAttributeName];
NSGlyph bullet = [font glyphWithName:@"bullet"];
for (int i = range.location; i != range.location + range.length; i++)
{
unsigned charIndex = [self characterIndexForGlyphAtIndex:i];
unichar c =[[[self textStorage] string] characterAtIndex:charIndex];
if (c == ' ')
[self replaceGlyphAtIndex:charIndex withGlyph:bullet];
}
[super drawGlyphsForGlyphRange:range atPoint:origin];
}
Peut-être - [NSLayoutManager setShowsControlCharacters:] et/ou - [NSLayoutManager setShowsInvisibleCharacters:] fera ce que vous voulez.
J'ai écrit un éditeur de texte il y a quelques années - voici un code sans signification qui devrait vous aider à regarder dans la bonne direction (c'est une sous-classe NSLayoutManager btw - et oui je sais qu'il fuit comme l'évier proverbial) :
- (void)drawGlyphsForGlyphRange:(NSRange)glyphRange atPoint:(NSPoint)containerOrigin
{
if ([[[[MJDocumentController sharedDocumentController] currentDocument] editor] showInvisibles])
{
//init glyphs
unichar crlf = 0x00B6;
NSString *CRLF = [[NSString alloc] initWithCharacters:&crlf length:1];
unichar space = 0x00B7;
NSString *SPACE = [[NSString alloc] initWithCharacters:&space length:1];
unichar tab = 0x2192;
NSString *TAB = [[NSString alloc] initWithCharacters:&tab length:1];
NSString *docContents = [[self textStorage] string];
NSString *glyph;
NSPoint glyphPoint;
NSRect glyphRect;
NSDictionary *attr = [[NSDictionary alloc] initWithObjectsAndKeys:[NSUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:@"invisiblesColor"]], NSForegroundColorAttributeName, nil];
//loop thru current range, drawing glyphs
int i;
for (i = glyphRange.location; i < NSMaxRange(glyphRange); i++)
{
glyph = @"";
//look for special chars
switch ([docContents characterAtIndex:i])
{
//space
case ' ':
glyph = SPACE;
break;
//tab
case '\t':
glyph = TAB;
break;
//eol
case 0x2028:
case 0x2029:
case '\n':
case '\r':
glyph = CRLF;
break;
//do nothing
default:
glyph = @"";
break;
}
//should we draw?
if ([glyph length])
{
glyphPoint = [self locationForGlyphAtIndex:i];
glyphRect = [self lineFragmentRectForGlyphAtIndex:i effectiveRange:NULL];
glyphPoint.x += glyphRect.origin.x;
glyphPoint.y = glyphRect.origin.y;
[glyph drawAtPoint:glyphPoint withAttributes:attr];
}
}
}
[super drawGlyphsForGlyphRange:glyphRange atPoint:containerOrigin];
}
est ici une mise en œuvre pleinement et de propreté
@interface GILayoutManager : NSLayoutManager
@end
@implementation GILayoutManager
- (void)drawGlyphsForGlyphRange:(NSRange)range atPoint:(NSPoint)point {
NSTextStorage* storage = self.textStorage;
NSString* string = storage.string;
for (NSUInteger glyphIndex = range.location; glyphIndex < range.location + range.length; glyphIndex++) {
NSUInteger characterIndex = [self characterIndexForGlyphAtIndex: glyphIndex];
switch ([string characterAtIndex:characterIndex]) {
case ' ': {
NSFont* font = [storage attribute:NSFontAttributeName atIndex:characterIndex effectiveRange:NULL];
[self replaceGlyphAtIndex:glyphIndex withGlyph:[font glyphWithName:@"periodcentered"]];
break;
}
case '\n': {
NSFont* font = [storage attribute:NSFontAttributeName atIndex:characterIndex effectiveRange:NULL];
[self replaceGlyphAtIndex:glyphIndex withGlyph:[font glyphWithName:@"carriagereturn"]];
break;
}
}
}
[super drawGlyphsForGlyphRange:range atPoint:point];
}
@end
Pour installer, utilisez:
[myTextView.textContainer replaceLayoutManager:[[GILayoutManager alloc] init]];
Pour trouver des noms de glyphe de police, vous devez aller à CoreGraphics:
CGFontRef font = CGFontCreateWithFontName(CFSTR("Menlo-Regular"));
for (size_t i = 0; i < CGFontGetNumberOfGlyphs(font); ++i) {
printf("%s\n", [CFBridgingRelease(CGFontCopyGlyphNameForGlyph(font, i)) UTF8String]);
}
Merci beaucoup de partager cela. – uchuugaka
Je posterai des ajouts plus tard pour la fonction de remplacement de la fonction obsolète ainsi qu'un changement pour éviter les problèmes avec la disposition contiguë. – uchuugaka
Je voudrais ajouter qu'il est préférable d'aller au texte de base pour les informations de nom de police aujourd'hui. CTFont et ses amis vont beaucoup mieux. – uchuugaka
Voici la solution de Pol Swift:
class MyLayoutManager: NSLayoutManager {
override func drawGlyphsForGlyphRange(glyphsToShow: NSRange, atPoint origin: NSPoint) {
if let storage = self.textStorage {
let s = storage.string
let startIndex = s.startIndex
for var glyphIndex = glyphsToShow.location; glyphIndex < glyphsToShow.location + glyphsToShow.length; glyphIndex++ {
let characterIndex = self.characterIndexForGlyphAtIndex(glyphIndex)
let ch = s[startIndex.advancedBy(characterIndex)]
switch ch {
case " ":
let attrs = storage.attributesAtIndex(characterIndex, effectiveRange: nil)
if let font = attrs[NSFontAttributeName] {
let g = font.glyphWithName("periodcentered")
self.replaceGlyphAtIndex(glyphIndex, withGlyph: g)
}
case "\n":
let attrs = storage.attributesAtIndex(characterIndex, effectiveRange: nil)
if let font = attrs[NSFontAttributeName] {
// let g = font.glyphWithName("carriagereturn")
let g = font.glyphWithName("paragraph")
self.replaceGlyphAtIndex(glyphIndex, withGlyph: g)
}
case "\t":
let attrs = storage.attributesAtIndex(characterIndex, effectiveRange: nil)
if let font = attrs[NSFontAttributeName] {
let g = font.glyphWithName("arrowdblright")
self.replaceGlyphAtIndex(glyphIndex, withGlyph: g)
}
default:
break
}
}
}
super.drawGlyphsForGlyphRange(glyphsToShow, atPoint: origin)
}
}
Et d'énumérer les noms de glyphe:
func listFonts() {
let font = CGFontCreateWithFontName("Menlo-Regular")
for var i:UInt16 = 0; i < UInt16(CGFontGetNumberOfGlyphs(font)); i++ {
if let name = CGFontCopyGlyphNameForGlyph(font, i) {
print("name: \(name) at index \(i)")
}
}
}
- 1. Comment afficher les caractères japonais dans JTextArea
- 2. Auto-indentation dans un NSTextView
- 3. Comment faire Emacs Afficher les caractères chinois
- 4. Révélez les éléments cachés dans jQuery
- 5. Comment afficher les caractères Unicode dans IE en utilisant HTML
- 6. NSTextView avec des jetons
- 7. NSpoint à partir du point d'insertion NSTextView
- 8. Rembourrage dans NSTextView - possible sans dessin personnalisé?
- 9. Google SEO et les éléments cachés
- 10. Comment afficher les caractères japonais sur une page php?
- 11. Afficher les caractères chinois en AJAX et aussi en excel
- 12. C# - Bascule les fichiers cachés dans le système?
- 13. Modèles Markov cachés
- 14. Révéler dynamiquement cachés divs
- 15. Script de connexion avec boutons cachés
- 16. Hauteur de NSTextView avec une ligne?
- 17. Java File.canWrite() sur Vista et les fichiers cachés super
- 18. Création de dossiers cachés
- 19. Comment fonctionnent les logiciels comme les dossiers cachés ou truecrypt?
- 20. Implémentation de modèles markov cachés dans .net?
- 21. Afficher QUELQUES caractères invisibles/espaces blancs dans Eclipse
- 22. iFrames vs Framesets à afficher sans fonds cachés (pour l'expérience Diggbar)?
- 23. Expression régulière pour les fichiers cachés sous unix
- 24. Comment afficher les caractères arabes dans une page Web en utilisant le serveur php et sql
- 25. J'ai du mal à afficher les caractères thai dans Silverlight 3
- 26. Comment puis-je obtenir des caractères accentués à afficher dans les graphes Fusion Charts?
- 27. commande d'arbre comme une regex, mais sans les fichiers cachés
- 28. Utilisez rsync pour copier uniquement les fichiers cachés
- 29. Codage de caractères pour les caractères thaïs
- 30. AS2: Désactivation des liens dans les champs de texte dynamiques cachés et les enfants MovieClip
@ Pol posté l'information plus complète sur un cours difficile à travailler en raison de documents rares. Mais les deux ont une limitation en ce que cette méthode est obsolète et la nouvelle méthode semble un peu plus difficile en ce sens qu'elle utilise des tableaux C: D Je vais ajouter un exemple basé sur cela. – uchuugaka