2017-09-07 8 views
0

Three Controllers only first two pressedImpossible de dessiner plusieurs objets UIView sous-classés en même temps. Essayé de nombreuses méthodes

[modifier]

QUESTION ORIGINAL COMMENCE CI-DESSOUS. ICI EST PLUS INFO

J'ai travaillé sur cette question toute la journée et je ne trouve pas de solution. J'ai sous-classé un UIView et réduit le code de dessin à ce qui suit.

-(void)drawRect:(CGRect)rect 
{ 


    //// rechargeLevel Drawing 
    CGRect rechargeLevelRect = CGRectMake(17.5, 17.75, 64, 64); 
    UIBezierPath* rechargeLevelPath = [UIBezierPath bezierPath]; 
    [rechargeLevelPath addArcWithCenter: CGPointMake(CGRectGetMidX(rechargeLevelRect), CGRectGetMidY(rechargeLevelRect)) radius: rechargeLevelRect.size.width/2 startAngle: 90 * M_PI/180 endAngle: endAngle * M_PI/180 clockwise: YES]; 

    [[UIColor redColor] setStroke]; 
    rechargeLevelPath.lineWidth = 4.5; 
    [rechargeLevelPath stroke]; 

    endAngle++; 
    if (endAngle > 359) { 
     endAngle = 1; 
    } 
} 

J'ai essayé toutes les choses suivantes.

  1. drawRect: Avec une minuterie qui appelle setNeedsDisplay (également essayé setNeedsDisplayInRect:

  2. CAShapeLayer avec une minuterie qui appelle une méthode qui dessine la forme

  3. CAShapeLayer l'intérieur d'un bloc qui est appelé après parce que je pensais que le minuteur était en train de tout vider

  4. Créé une seconde sous-classe de UIView avec le même code mais avec diff Étiquettes récentes. L'initialisation de l'un des deux ne fonctionne toujours pas.

  5. J'ai essayé des combinaisons des méthodes ci-dessus entre les deux sous-classes et toujours rien.

La temporisation s'arrête lorsque vous démarrez une autre ou que vous utilisez le même contexte. Je n'ai aucune idée.

J'ai créé un dépôt GitHub avec le projet de test que j'ai réalisé. Il a un viewController avec six boutons qui initialisent chacune des méthodes ci-dessus à partir des deux sous-classes et les ajoute à la vue.

le repo GitHub est: https://github.com/MoseCode/drawTest

[modifier final]

QUESTION ORIGINAL SUIVENT:

Essayer de faire le dessin drawRect personnalisé avec une minuterie pour plusieurs objets en même temps.

J'ai un UIController personnalisé (WP_BonusController) configuré pour recevoir des événements tactiles. Une fois que le contrôleur a été touché 5 fois, les événements sont désactivés jusqu'à ce qu'un certain temps se soit écoulé.

Pour illustrer le temps de recharge, je trace un chemin circulaire à partir de DrawRect. J'utilise UIGraphicsGetCurrentContext et puis caresse le nouveau chemin. Mon problème est que lorsque j'instancie un groupe de ces objets WP_BonusController, ils partagent tous le même contexte à partir de UIGraphicsGetCurrentContext. J'ai vérifié les allocations de RAM pour les objets et ils sont tous différents. Mais quand je mets un point d'arrêt dans le drawRect: et vérifie le CGContextRef de UIGraphicsGetCurrentContext ils ont tous la même allocation de ram.

Lorsque j'appuie sur BonusController1 cinq fois, le minuteur démarre et commence à dessiner le cercle autour de l'icône. ça fonctionne bien.

Puis j'appuie sur bonusController2 cinq fois et il commence son timer mais quand il dessine le contexte dans son drawRect je reçois le même contexte de l'autre bonusController1. La ligne en cours de dessin est déjà à moitié dessinée.

Il en est de même pour n'importe quel nombre de ces contrôleurs.

Y at-il un moyen de créer mon propre contexte propre qui n'utilise pas le UIGraphicsGetCurrentContext. J'ai cherché partout et je ne trouve pas de solution. Peut-être que je ne comprends pas correctement l'utilisation du contexte. Je dois être capable de dessiner à ces contrôleurs individuellement à tout moment et plusieurs fois simultanément.

Voici mon drawRect: qui est appelé par une minuterie:

-(void)drawRect:(CGRect)rect 
{ 
    _currentAngle = _currentAngle + 1; 

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.frame.size.width, self.frame.size.height), NO, 0); 


    // General Declarations 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    // Resize to Target Frame 
    CGContextSaveGState(context); 
    CGRect resizedFrame = WP_CustomIconsResizingBehaviorApply(WP_CustomIconsResizingBehaviorAspectFill, CGRectMake(0, 0, 100, 100), [self getImageRect]); 
    CGContextTranslateCTM(context, resizedFrame.origin.x, resizedFrame.origin.y); 
    CGContextScaleCTM(context, resizedFrame.size.width/100, resizedFrame.size.height/100); 


    //// rechargeLevel Drawing 
    CGRect rechargeLevelRect = CGRectMake(17.5, 17.75, 64, 64); 
    UIBezierPath* rechargeLevelPath = [UIBezierPath bezierPath]; 
    [rechargeLevelPath addArcWithCenter: CGPointMake(CGRectGetMidX(rechargeLevelRect), CGRectGetMidY(rechargeLevelRect)) radius: rechargeLevelRect.size.width/2 startAngle: 90 * M_PI/180 endAngle: _currentAngle * M_PI/180 clockwise: YES]; 

    [WP_CustomIcons.thirdColor setStroke]; 
    rechargeLevelPath.lineWidth = 4.5; 
    [rechargeLevelPath stroke]; 
    CGContextRestoreGState(context); 

    refillMeter = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    [self.refillImageView setImage:refillMeter]; 

} 
+1

cette méthode de tirage appartient à une implémentation UIView personnalisée? –

+0

Oui Reinier, c'est en quelque sorte un UIView personnalisé. C'est une sous-classe d'un UIControl qui, je crois, est un sous-groupe de UIView et je pensais que ça devrait aller. J'ai passé la journée à essayer différentes implémentations et je n'arrive pas à les faire fonctionner. Je vais mettre à jour ma question avec quoi d'autre j'ai essayé. Je vous remercie. –

+0

Désolé était impossible pour moi se connecter à SO depuis vendredi à cause de l'ouragan Irma, je vois que vous pouvez gérer les acclamations! –

Répondre

0

figured it out. Dernier à essayer. Peut-être aurait dû être le premier mais j'étais pour une raison quelconque en pensant aux minuteurs.

CALayerAnimation

@implementation ThirdTimerView 


- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // 
    } 
    return self; 
} 

-(UIBezierPath *)samplePath 
{ 
    CGRect rechargeLevelRect = CGRectMake(17.5, 17.75, 64, 64); 
    UIBezierPath* rechargeLevelPath = [UIBezierPath bezierPath]; 
    [rechargeLevelPath addArcWithCenter: CGPointMake(CGRectGetMidX(rechargeLevelRect), CGRectGetMidY(rechargeLevelRect)) radius: rechargeLevelRect.size.width/2 startAngle: 90 * M_PI/180 endAngle: 450 * M_PI/180 clockwise: YES]; 

    return rechargeLevelPath; 
} 


- (void)startAnimation 
{ 
    if (self.pathLayer == nil) 
    { 
     CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 

     shapeLayer.path = [[self samplePath] CGPath]; 
     shapeLayer.strokeColor = [[UIColor redColor] CGColor]; 
     shapeLayer.fillColor = nil; 
     shapeLayer.lineWidth = 4.5f; 
     shapeLayer.lineJoin = kCALineJoinBevel; 

     [self.layer addSublayer:shapeLayer]; 

     self.pathLayer = shapeLayer; 
    } 

    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeTimer"]; 
    pathAnimation.duration = 3.0; 
    pathAnimation.fromValue = @(0.0f); 
    pathAnimation.toValue = @(1.0f); 

    [CATransaction setCompletionBlock:^{ 

     [self removeFromSuperview]; 

    }]; 

    [self.pathLayer addAnimation:pathAnimation forKey:@"strokeTimer"]; 
} 

@end