2010-06-17 17 views
1

Parfois, lors de la définition de layer.transform dans une nouvelle transformation, je vois la couche clignoter à son emplacement fini, puis l'animer de son emplacement actuel à son emplacement fini emplacement.Paramétrer layer.transform clignote la couche à l'emplacement final puis l'anime à partir de l'emplacement actuel

Je ne sais pas si cela est lié mais en même temps je suis en train de définir le sous-layerTransform sur la super couche du calque. Je n'ai vraiment aucune idée pourquoi cela se produit, des pensées seraient appréciées.

Merci.

Mise à jour

Lorsque je supprime la sous-couche de transformation, ce comportement ne se produit pas.

Ceci est ma configuration initiale.

J'évite des actions implicites avec mon sublayerTransform avec:

self.actions = [NSDictionary dictionaryWithObject:[NSNull null] forKey:@"sublayerTransform"]; 

Cette méthode transforme la couche individuelle

- (void)setSelectedCover:(int)cover{  
    selectedCover = cover; 

    CoverLayer *coverLayer = [onScreenCovers objectForKey:[NSNumber numberWithInt:cover]]; 

    [CATransaction begin]; 
    [CATransaction setValue:[NSNumber numberWithFloat:0.3f] 
        forKey:kCATransactionAnimationDuration]; 

    coverLayer.transform = flippedUpTransform; 
    [CATransaction commit]; 
} 

Cette méthode crée un défilement comme effet (je sais qu'il existe des moyens plus pratiques de défilement , mais c'est la meilleure implémentation pour mes besoins jusqu'ici) cette méthode est appelée chaque fois que le doigt bouge sur l'écran.

- (void)setScrollOffset:(float)offset absolute:(BOOL)absolute animated:(BOOL)animated{ 
    CATransform3D aSublayerTransform = self.sublayerTransform; 
    scrollOffset = aSublayerTransform.m41; 

    if (absolute) { 
     scrollOffset = offset; 
    }else { 
     scrollOffset += offset; 
    } 

    [self setValue:[NSNumber numberWithInt:scrollOffset] forKeyPath:@"sublayerTransform.translation.x"]; 
} 

Egalement. Je ne peux que reproduire cela sur des appareils de 2ème génération (pas sur le 3ème), donc ça me fait penser que c'est en partie un problème de performance de l'appareil, mais j'ai encore besoin d'un peu de travail.

J'ai envisagé d'utiliser un CABasicAnimation (animations explicites) comme ceci:

- (void)setSelectedCover:(int)cover{ 
    selectedCover = cover; 

    CoverLayer *coverLayer = [onScreenCovers objectForKey:[NSNumber numberWithInt:cover]]; 

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"]; 
    animation.toValue = [NSValue valueWithCATransform3D:flippedUpTransform]; 
    animation.duration = 0.3f; 

     [coverLayer addAnimation:animation forKey:@"transform"]; 
    } 

Cela fonctionne vraiment bien fait, pas vacillante! le seul problème maintenant est de le faire rester.

Je a ajouté à l'animation:

animation.removedOnCompletion = NO; 
animation.fillMode = kCAFillModeForwards; 

Cette réalité fait-il rester à la fin de l'animation, mais je pense qu'il est important pour tous ceux qui travaillent sur une tâche similaire à savoir que l'ajout ces deux lignes ne font que coller la couche de présentation, elle ne la persiste pas sur la couche modèle. Dans mon cas, j'ai des transformations supplémentaires pour la couche en cours si je veux me transformer à nouveau, en disant layer.transform = newtransform et le modèle n'a jamais été changé, ma couche retournera à sa transformation d'origine avant d'exécuter l'animation explicite.

J'ai donc pensé que j'avais une bonne solution au problème de la persistance de la transformation. J'ai ajouté:

animation.delegate = coverLayer.delegate; 

Dans mon cas, chaque couche qui s'anime, a besoin de son propre délégué parce que je pouvais avoir plusieurs couches animant en même temps parce que les choses bougent si vite. donc je veux que chaque couche en soit responsable.

C'est ce que j'ai implémenté dans le délégué.

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ 

    if (flag) { 

    [CATransaction begin]; 
    [CATransaction setValue:(id)kCFBooleanTrue 
        forKey:kCATransactionDisableActions]; 
    cover.transform = flippedUpTransform; 
    [CATransaction commit]; 
    [cover performSelector:@selector(removeAllAnimations) withObject:nil afterDelay:0.2]; 

    } 
} 

Si l'animation terminée avec succès je prends le produit fini transform et l'appliquer au modèle lui-même

Peu de temps après je supprimer l'animation explicite parce que quand d'autres transformations sont définies, il se déroulera l'animation, je dernière ajouté .

Cela fonctionne.

Si l'animation ne s'est pas terminée, je ne fais rien. Je n'ai pas besoin de mettre à jour la couche modale parce que l'animation qui a été interrompue devrait être responsable de reprendre là où celle-ci s'est arrêtée et de s'assurer que la présentation est persistante.

Le problème est de compter sur les appels différés pour toujours être bon. Ils ne le sont pas, ils le gardent assez ensemble, mais parfois les choses peuvent paraître un peu plus petites. En fin de compte, je vais accepter cette solution Si je ne peux pas rectifier plus loin. Ce n'est pas aussi simple ...

Répondre

0

La mise à jour iOS4 résout ce problème.

0

Il serait utile que vous montriez le code que vous utilisez, mais parfois j'ai vu un scintillement se produire lorsque le code anime la propriété (transformer dans votre cas) et puis définit la propriété dans une boucle d'exécution ultérieure. Qu'est-ce qui se passe, c'est qu'il y a une animation ajoutée (la couche) deux fois. Gardez juste à l'esprit que faire une modification directement à une propriété de la couche non-root anime (implicitement) cette propriété sauf si vous désactivez l'animation. Souvenez-vous également que l'animation de la propriété ne définit pas automatiquement la propriété. Si vous utilisez des films d'animation, assurez-vous lorsque vous ajoutez l'animation à la couche, vous utilisez « transformer » comme la clé - quelque chose comme:

CABasicAnimation *transformAnim = [CABasicAnimation 
             animationForKey:@"transform"]; 
[transformAnim setToValue:CATransform3DMake...]; 
[transformAnim setDuration:...]; // etc. etc. 

// This next line actually sets the transform 
[transformLayer setTransform:CATransform3DMake...]; 
// This overrides the default animation for animating the transform 
[transformLayer addAnimation:transformAnim forKey:@"transform"]; 

Je ne sais pas si vous utilisez des films d'animation, mais c'est ce qui m'est venu à l'esprit.

En outre, vous êtes sous-layerTransform peut affecter cela. Que se passe-t-il lorsque vous commentez cela? Il pourrait être utile de mettre à jour votre question avec du code.

Cordialement.

+0

Merci pour la réponse. Le runloop est une idée intéressante que je n'ai pas encore regardée pour ce problème. J'ai ajouté du code et une histoire à ma situation, cela ne me dérangerait pas. Merci. – maxpower

+0

[coverLayer setTransform: flippedUpTransform]; provoque réellement le scintillement lorsque je fais une animation explicite. Je veux définir la transformation lorsque l'animation est terminée, ce qui est dans ma mise à jour, mais il est plus difficile à gérer avec toutes mes transformations en cours. – maxpower

+0

Que se passe-t-il si vous définissez la transformation comme je l'ai fait dans mon exemple de code. Vous voyez, si vous ne définissez pas réellement la transformation, vous devez faire les trucs fillModeForwards et removedOnCompletion pour qu'il reste en position avancée, mais vous n'avez pas encore défini la transformation du calque. Dans mon exemple de code, vous définissez la transformation sur le calque lui-même, mais en indiquant à la couche d'animer la nouvelle transformation en utilisant votre animation explicite personnalisée au lieu de la valeur par défaut lorsque vous ajoutez l'animation à l'aide de la clé "transformer". Cela a-t-il du sens? –