2012-12-10 3 views
0

Je voudrais créer un NSSearchField, comme celui d'Ecoute 3.0. L'icône de recherche dans le champ de recherche doit être cliquable et développer et réduire si vous cliquez dessus.Icône de recherche cliquable dans NSSearchField et fond d'évanouissement

enter image description here enter image description here

Comment pouvez-vous y parvenir? J'ai cherché dans la documentation, mais je n'ai rien trouvé d'utile. Je pourrais implémenter l'extension avec le proxy d'animation, donc c'est clair.

Une autre chose est que l'arrière-plan s'estompe/disparaît à mesure qu'il se développe/se réduit. Comment puis-je y parvenir?

Je serais reconnaissant pour tous les conseils, exemples de code, etc.

EDIT

Ok je trouve la première partie moi-même.

- (void) resetSearchButtonCell { 
    NSButtonCell *c= [[NSButtonCell alloc] init]; 
    [c setButtonType:NSMomentaryChangeButton]; // configure the button 
    [c setBezelStyle:NSRegularSquareBezelStyle]; // configure the button 
    [c setBordered:NO]; 
    [c setBezeled:NO]; 
    [c setEditable:NO]; 
    [c setImagePosition:NSImageOnly]; 
    [c setImage:[NSImage imageNamed:@"search"]]; 
    [c setAlternateImage:[NSImage imageNamed:@"search-pushed"]]; 
    [c setTarget:self]; 
    [c setAction:@selector(_search:)]; 
    [self setSearchButtonCell:c]; 
} 

Maintenant, je me suis fait une propriété isCollapsed, que je bascule en _search:. Et dans la méthode setter setIsCollapsed: je fais ce qui suit:

NSRect newRect = self.frame; 

if (_isCollapsed) { 
    newRect.size.width = kCollapsedWidth; 
} else { 
    newRect.size.width = kEXpandedWidth; 
} 

[[self animator] setFrameSize:newRect.size]; 

Mais pour une raison quelconque le cadre est en cours de réinitialisation à la taille initiale, celui défini dans Interface Builder, lorsque le NSSearchField obtient ou desserre mise au point.

Quelqu'un peut-il me dire pourquoi?

EDIT

J'ai résolu ce problème aussi. C'était la mise en page automatique, qui a gâché l'animation. Maintenant, la seule chose qui reste est l'arrière-plan alpha, qui devrait changer. Je pourrais redessiner le tout, mais y a-t-il une autre solution où je pourrais juste modifier l'alpha de seulement l'arrière-plan et le bouton d'annulation?

+0

Voir ma réponse ci-dessous. – Arvin

Répondre

1

que je voulais faire quelque chose de similaire. ITSearchField est très solide et agréable. Cependant, j'ai souhaité élargir le champ de recherche une fois qu'il a gagné le focus. Comme on pourrait le découvrir rapidement, NSSearchfield comprend de nombreux composants et couches.

Voici ce que j'ai écrit pour le faire fonctionner ... Note: Cela fonctionne sur 10.7 ou supérieur. Vous devez également raccorder la contrainte de disposition de la largeur du contrôle de champ de recherche dans IB à la sortie.

.h

@interface MySearchField : NSSearchField 
@end 

.m

#pragma mark - Implementation: Search Field Control 

@interface MySearchField() 
@property (readwrite, nonatomic, getter=isExpanded) BOOL expand; 
@property (readwrite, nonatomic, getter=hasFocusRing) BOOL focusRing; 
@property (readwrite, strong, nonatomic) NSTimer *expandTimer; 
@property (readwrite, strong, nonatomic) IBOutlet NSLayoutConstraint *widthConstraint; 
@property (readwrite, nonatomic) CGFloat searchWidth; 
@end 

static NSTimeInterval const kSearchFieldTime = 0.5; 

@implementation MySearchField 

@synthesize expand, focusRing; 
@synthesize expandTimer, searchWidth; 
@synthesize widthConstraint; 

#pragma mark Timer Methods: 

- (void) resizeSearchField { 


    if (self.hasFocusRing) { 

     if (!self.isExpanded) { 

      self.searchWidth = self.widthConstraint.constant; 
      [[self.widthConstraint animator] setConstant:(self.searchWidth * 2)]; 
      self.expand = YES; 

    } } else { 

     if ((self.isExpanded) && 
      ((!self.stringValue) || ([self.stringValue isEqualToString:@""]))) { 

      [[self.widthConstraint animator] setConstant:self.searchWidth]; 
      self.expand = NO; 
    } } 
} 

- (void) stopTimer { 

    if (self.expandTimer) 
     [self.expandTimer invalidate]; 

    self.expandTimer = nil; 
} 

- (void) startTimer { 

    [self stopTimer]; 

    SEL resizeSelector = @selector(resizeSearchField); 
    NSMethodSignature *expandSignature = [MySearchField instanceMethodSignatureForSelector:resizeSelector]; 
    NSInvocation *expandInvocation = [NSInvocation invocationWithMethodSignature:expandSignature]; 
    [expandInvocation setSelector:resizeSelector]; 
    [expandInvocation setTarget:self]; 

    self.expandTimer = [NSTimer scheduledTimerWithTimeInterval:kSearchFieldTime invocation:expandInvocation repeats:NO]; 
} 

#pragma mark Override Methods: 

- (void) noteFocusRingMaskChanged { 

    self.focusRing = !NSEqualRects(NSZeroRect, self.focusRingMaskBounds); 
    [self startTimer]; 
    [super noteFocusRingMaskChanged]; 
} 

@end 

Ok, c'est vraiment ça. Vous êtes averti lorsque la bague de mise au point change et lancez une méthode de minuterie rapide. La minuterie est nécessaire lorsque vous cliquez sur le bouton d'annulation du champ de recherche qui réinitialise le contrôle. La seule chose que fait le temporisateur est de déclencher la méthode resizeSearchField.

Mise à jour: Oh oui, n'oubliez pas de définir la classe de votre champ de recherche dans IB à MySearchField ou tout ce que vous voulez l'appeler.

Profitez-en!

+0

Merci pour votre suggestion. Je suis plutôt content de 'ITSearchField', car il correspond le mieux à mes besoins. À votre santé ;) – NSAddict

Questions connexes