2010-10-08 5 views
3

J'ai UILabel et j'en ai besoin pour être en mesure de soutenir la copie & coller (en fait seulement la copie car il est en lecture seule). J'ai sous-classé UILabel pour supporter la copie et ça marche bien. J'ai également ajouté un surlignage de texte pour que l'utilisateur sache exactement ce qu'il copie lorsqu'il clique sur l'étiquette.Comment faire pour "désélectionner" la notification sur UILabel

Mon problème est que je ne sais pas comment annuler cette surbrillance lorsque l'utilisateur clique ailleurs. La bulle de copie disparaît, mais je n'obtiens aucun rappel, le texte reste donc en surbrillance. Y at-il un rappel spécial que j'ai raté que je peux utiliser ou dois-je trouver un hack sale? Ou y a-t-il peut-être plus de façon standard de mettre en évidence du texte dans UILabel que je ne connais pas et qui serait géré automatiquement comme Copier la bulle?

Voici mon habitude Code UILabel:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { 
    if(action == @selector(copy:)) { 
     return YES; 
    } 
    else { 
     return [super canPerformAction:action withSender:sender]; 
    } 
} 

- (BOOL)becomeFirstResponder { 
    if([super becomeFirstResponder]) { 
     self.highlighted = YES; 

     UIMenuController *menu = [UIMenuController sharedMenuController]; 
     [menu setTargetRect:self.bounds inView:self]; 
     [menu setMenuVisible:YES animated:YES]; 

     return YES; 
    } 
    return NO; 
} 

- (BOOL)resignFirstResponder { 
    if([super resignFirstResponder]) { 
     self.highlighted = NO; 

     UIMenuController *menu = [UIMenuController sharedMenuController]; 
     [menu setMenuVisible:NO animated:YES]; 
     [menu update]; 

     return true; 
    } 
    return false; 
} 

- (void)copy:(id)sender { 
    UIPasteboard *board = [UIPasteboard generalPasteboard]; 
    [board setString:self.text]; 
    self.highlighted = NO; 
    [self resignFirstResponder]; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    if([self isFirstResponder]) { 
     //UIMenuController *menu = [UIMenuController sharedMenuController]; 
     //[menu setMenuVisible:NO animated:YES]; 
     //[menu update]; 
     [self resignFirstResponder]; 
    } 
    else if([self becomeFirstResponder]) { 
     //UIMenuController *menu = [UIMenuController sharedMenuController]; 
     //[menu setTargetRect:self.bounds inView:self]; 
     //[menu setMenuVisible:YES animated:YES]; 
    } 
} 

- (void)setHighlighted:(BOOL)hl { 
    [super setHighlighted:hl]; 

    [self setNeedsLayout]; 
} 

- (void)drawRect:(CGRect)rect { 
    [super drawRect:rect]; 

    if(self.highlighted) { 
     CGContextRef ctx = UIGraphicsGetCurrentContext(); 
     CGContextSetRGBFillColor(ctx, 0.3, 0.8, 1.0, 0.3); 
     CGContextAddRect(ctx, CGRectMake(0, 0, [self textRectForBounds:self.frame limitedToNumberOfLines:1].size.width, self.frame.size.height)); 
     CGContextFillPath(ctx); 
    } 
} 

Toute aide appréciée!

Répondre

2

Personnellement, j'utiliserais un UITextView avec l'option d'ensemble modifiable à NO. Sinon, si vous voulez plus de contrôle, sous-classifiez votre vue en plein écran la plus haute (ou fenêtre) dont votre UILabel est un enfant. Override - (UIView *) hitTest: Point (CGPoint) withEvent: (UIEvent *); Si la vue d'accès n'est pas votre UILabel, créez un NSNotification que vous gérez dans votre sous-classe UILabel et désélectionnez-le.

BTW, vous devez TOUJOURS gérer touchCanceled aussi!

+0

Merci pour les conseils. Je pense qu'il y avait une raison pour laquelle je n'ai pas utilisé UITextView, mais je ne me souviens pas de ce que c'était. Je vais vérifier. Je ne savais pas sur la méthode la plus hittest, je vais essayer celui-là aussi. A propos de touchCancel, je suppose que c'est juste de faire les mêmes choses que dans les touchers. Dans la plupart des cas, non? – Lope

+0

serait intéressé de savoir pourquoi vous n'avez pas utilisé un UITextView ... –

+0

ouais je pense juste une copie de la toucheEnded devrait être bien. –

Questions connexes