2017-06-09 2 views
0

Je souhaite qu'une lecture de l'horloge apparaisse sous forme d'étiquette dans un UIButton une fois par seconde. Mais même si je le supprimer de la superView la nouvelle UIButton écrase l'ancien, comme celui-ci enter image description here ... et après quelques minutes de ce mon iPhone avait l'air :-) sérieusement brûléPuis-je mettre à jour une étiquette dans un UIButton sans redessiner le bouton?

Dans PlayViewController mes NSTimer méthodes ressemblent à ceci

- (void)startClock {  
     clockCount   = 0;  // start on 1st clock pulse 
     totalMinutes  = 0;  // appears on clockButton 
     totalSeconds  = 0;  // appears on clockButton 

     timer = [NSTimer scheduledTimerWithTimeInterval:STATES_ConcertClock 
              target:self 
              selector:@selector(nextClock) 
              userInfo:nil 
              repeats:YES]; 
    } 

    - (void)nextClock { 

     self.lastEventChangeTime = [NSDate date];  
     clockCount++; 
     [self masterClockReadout];  
    } 

et voici ma méthode de lecture d'horloge

- (void)masterClockReadout        { 
     totalMinutes  = clockCount/60; 
     totalSeconds  = clockCount % 60; 
     clockString  = [NSString stringWithFormat:@"%02d:%02d", totalMinutes, totalSeconds]; 

     [self.seconds removeFromSuperview]; 
     EscButton *seconds = [[EscButton alloc] loadEscButton:(NSString *)clockString]; 
     [self.view addSubview:seconds]; 
    } 

J'ai également mis une propriété UIView donc removeFromSuperview sait quoi retirer.

@property (nonatomic, retain) UIView* seconds; 

Ma question est la suivante: puis-je mettre à jour l'étiquette UIButton sans redessiner le bouton? et, est-ce un problème qui pourrait être résolu en utilisant un delegate?

À ce jour, mon expérience en utilisant delegates a été pour envoyer des messages de la UIButton à ViewController(par exemple ci-dessous) mais jusqu'à présent, je ne l'ai pas trouvé un exemple, je suis en mesure d'appliquer lorsque les messages sont envoyés dans la direction opposée. Donc, si l'utilisation d'un delegate est l'approche recommandée, pourriez-vous s'il vous plaît me signaler un code qui pourrait m'aider à résoudre ce problème. Merci

EscButton.h

#import <UIKit/UIKit.h> 

    @protocol EscButtonDelegate <NSObject> 
    -(void)fromEscButton:(UIButton*)button; 
    @end 

    @interface EscButton : UIView {  
    } 
    - (id)loadEscButton:(NSString *)text; 
    @property (assign) id<EscButtonDelegate> delegate; 
    @end 

EscButton.m

#import "EscButton.h" 

    @implementation EscButton 

    - (id)loadEscButton:(NSString *)text       { 

     CGFloat sideOffset = screenWidth - ESC_BUTTON_Width - MARGIN_Side; 
     CGFloat topOffset = statusBarHeight + MARGIN_Top; 

     UIButton *escButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
     escButton.frame  = CGRectMake(sideOffset, topOffset, ESC_BUTTON_Width, ESC_BUTTON_Height); 

     //  etc … 

     [escButton addTarget:self.delegate action:@selector(fromEscButton:) forControlEvents:UIControlEventTouchUpInside]; 
     [escButton setTitle:text forState:UIControlStateNormal]; 

     //  etc … 

     return escButton; 
    } 

    @end 

Répondre

1

Il n'y a pas besoin d'ajouter constamment et supprimer un bouton. Vous pouvez garder le même. Modifier le code suivant:

@property (nonatomic, retain) UIView* seconds; 

à:

@property (nonatomic, retain) UIButton *secondsB; 

changer aussi:

[self.seconds removeFromSuperview]; 
EscButton *seconds = [[EscButton alloc] loadEscButton:(NSString *)clockString]; 
[self.view addSubview:seconds]; 

à:

if (!self.secondsB) { 

    self.secondsB = [[EscButton alloc] loadEscButton:(NSString *)clockString]; 
    [self.view addSubview:_secondsB]; // previously addSubview:seconds]; 
} 

[self.secondsB setTitle:clockString forState:UIControlStateNormal]; 
+0

voulez-vous dire [self.view addSubview: secondsB] ; ? – Greg

+0

RunLoop, cela a résolu mon problème lorsque j'ai changé la ligne que j'ai commenté. Je vais avec votre réponse. – Greg

+0

Merci - désolé était une faute de frappe - corrigé maintenant. – RunLoop