Comment bien animer UIScrollView contentOffset
J'ai UIScrollView sous-classe. Son contenu est réutilisable, environ 4 ou 5 points de vue sont utilisés pour afficher des centaines d'éléments (pendant le défilement des objets cachés, de les réutiliser et de sauts à un autre poste lorsque son besoin de les voir)
Ce dont j'ai besoin: possibilité de faire défiler automatiquement mon défiler la vue de n'importe quelle position. Par exemple, mon scroll view affiche les 4e, 5e et 6e élément et quand j'appuie sur certaines cette touche pour faire défiler jusqu'à 30 de l'élément. En d'autres mots j'ai besoin de comportement standard de UIScrollView.
Cela fonctionne bien:
[self setContentOffset:CGPointMake(index*elementWidth, 0) animated:YES];
mais j'ai besoin de personnalisation. Par exemple, changer l'animation de la durée, ajouter un peu de code à exécuter à la fin de l'animation.
Évident décision:
[UIView animateWithDuration:3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
[self setContentOffset:CGPointMake(index*elementWidth, 0)];
} completion:^(BOOL finished) {
//some code
}];
mais j'ai quelques actions connecté à l'événement scroll, et maintenant ils sont tous en bloc d'animation et il entraîne tous les sous-vue de cadres pour animer trop (grâce à quelques éléments réutilisables tous les anime pas comme je veux)
La question est: Comment puis-je faire de l'animation personnalisée (en fait j'ai besoin d'une durée personnalisée, les actions sur la fin et BeginFromCurrentState option) pour le décalage du contenu SANS d'animation de tous le code, connecté à scrollViewDidScroll
événement?
UPD:
Grâce à Andrew répondre(première partie) j'ai résolu le problème avec l'animation à l'intérieur de scrollViewDidScroll
:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
[UIView performWithoutAnimation:^{
[self refreshTiles];
}];
}
Mais scrollViewDidScroll
doit (pour ma part) s'exécute à chaque image de l'animation comme dans le cas de
[self setContentOffset:CGPointMake(index*elementWidth, 0) animated:YES];
Cependant, maintenant, il s'exécute qu'une seule fois au début de l'animation.
Comment puis-je résoudre ce problème?
OriginalL'auteur Lloyd18 | 2014-02-13
Vous devez vous connecter pour publier un commentaire.
Avez-vous essayé la même approche, mais avec les handicapés de l'animation dans
scrollViewDidScroll
?Sur iOS 7, vous pouvez essayer d'emballage de votre code dans
scrollViewDidScroll
danssur les précédentes versions iOS, vous pourriez essayer:
Mise à jour:
Malheureusement, c'est là que vous frappez la partie la plus difficile de toute la chose.
setContentOffset:
appelle le délégué juste une fois, c'est l'équivalent desetContentOffset:animated:NO
, qui appelle de nouveau une fois.setContentOffset:animated:YES
appelle le délégué à l'animation des modifications des limites de la scrollview et vous voulez, mais vous ne voulez pas de l'animation, de sorte que le seul moyen de contourner ce que je peux trouver est à changer peu à peu lacontentOffset
de la scrollview, de sorte que le système d'animation n'est pas simplement sauter à la valeur finale, comme c'est le cas pour le moment.À faire que vous pouvez regarder des animations d'image clé, comme pour iOS 7:
Ainsi, vous obtenez deux mises à jour et vous pouvez bien sûr utiliser de mathématiques, et une boucle d'ajouter jusqu'à beaucoup plus de ces avec le bon timing.
Sur les précédentes versions iOS, vous aurez à déposer à CoreAnimation pour les animations d'images clés, mais c'est fondamentalement la même chose avec un peu différente de la syntaxe.
Méthode 2:
Vous pouvez essayer d'interrogation de la presentationLayer de la scrollview pour tous les changements avec une minuterie que vous commencez au début de l'animation, puisque, malheureusement, la presentationLayer les propriétés ne sont pas KVO observables. Ou vous pouvez utiliser
needsDisplayForKey
dans une sous-classe de la couche pour être averti lorsque les limites de changement, mais qui aura besoin de quelques travaux à installer et il est la cause de la redessiner, ce qui peut affecter les performances.Méthode 3:
Serait à disséquer ce qui se passe exactement à la scrollView lors de l'animation est OUI, essayer d'intercepter l'animation qui est indiqué sur la scrollview et changer ses paramètres, mais puisque ce serait la plus hacky, cassants à cause d'Apple, les changements et la plus délicate de la méthode, je ne vais pas rentrer dans les.
Ajout d'une réponse à votre commentaire dans ma réponse, car il serait très long pour un commentaire.
Magnifique réponse! Merci beaucoup!
performWithoutAnimation ne semble pas fonctionner pour moi. J'ai un calque de dégradé et je suis à jour de l'alpha, mais le gradient de la couche semble être toujours à la traîne, peu importe j'ai mis tout le code à l'intérieur de performWithoutAnimation :/
OriginalL'auteur Andrew
Une belle façon de le faire est avec la AnimationEngine de la bibliothèque. C'est une très petite bibliothèque: six dossiers, avec plus de trois si vous voulez amortie printemps comportement.
Derrière les coulisses, il utilise un
CADisplayLink
pour exécuter votre bloc d'animation une fois chaque image. Vous obtenez un propre bloc de base de la syntaxe qui est facile à utiliser, et un tas de interpolation et les fonctions d'accélération qui vous font gagner du temps.Pour animer
contentOffset
:OriginalL'auteur bcattle