Fade in / out contenu de UIScrollView comme Safari Mobile fait dans son onglet
-
22-08-2019 - |
Question
NOTE:. J'ai ajouté ma nouvelle solution à la réponse UPDATE ci-dessous
J'essaie de recréer les effets que nous avons vu dans l'onglet Mobile Safari sur iPhone / iPod touch.
Fondamentalement, il est un UIScrollView qui contient 4 UIView réutilisable (agissant comme tampon circulaire), et les rouleaux horizontalement. Lorsque vous faites défiler, se fade in / out en toute transparence avec l'opacité de décalage du UIView.
À l'heure actuelle, je fais tout le sale boulot dans - (void)scrollViewDidScroll:(UIScrollView *)scrollView
. Tels que obtenir le contentOffset de UIScrollView, déterminer le pageingation, calculer le delta entre contentOffset et chaque position de UIView et décider / définir la valeur alpha de chaque UIView au moment où scrollViewDidScroll:
a été appelé.
Et cela fonctionne, la performance est bien, tout se passe bien, mais le seul problème est trop calcul.
J'ai essayé de beginAnimations:
de UIView et commitAnimations:
, mais il est inutile dans scrollViewDidScroll:
, puisque 1) la nouvelle valeur alpha doivent encore être calculer moi-même, et 2) scrollViewDidScroll: continuais appelé lors du défilement, il est inutile de faire l'animation ici. Est-il possible de réécrire cette partie avec Core Animation? Donc, je ne dois pas faire le calcul moi-même sur la valeur alpha de chaque UIView, au contraire, je reste des œuvres entières à Core Animation.
La solution
UPDATE
Je suis venu avec une autre façon de mettre à jour la valeur alpha de chaque page. Lorsque vous créez afficher le contenu, j'utilise KVO à addObserver avec contentOffset de UIScrollView:
[self.scrollView addObserver:[self.contentViews objectAtIndex:i]
forKeyPath:@"contentOffset"
options:NSKeyValueObservingOptionNew
context:@selector(updateAlpha:)];
Alors que chacun de mes contentViews recevra le message quand contentOffset a changé:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
[self performSelector:(SEL)context withObject:change];
}
Et mes contentViews peut faire le calcul et animez par eux-mêmes lors du défilement:
- (void)updateAlpha:(NSDictionary *)change {
CGFloat offset = [[change objectForKey:NSKeyValueChangeNewKey] CGPointValue].x;
CGFloat origin = [self frame].origin.x;
CGFloat delta = fabs(origin - offset);
[UIView beginAnimations:@"Fading" context:nil];
if (delta < [self frame].size.width) {
self.alpha = 1 - delta/self.frame.size.width*0.7;
} else {
self.alpha = 0.3;
}
[UIView commitAnimations];
}
Bien sûr, vous devrez supprimer l'observateur lorsque vous supprimez l'affichage du contenu de superview, et les ajouter à nouveau lorsque le nouveau point de vue du contenu créé.
Espérons que cela aide à ceux qui veulent faire la même chose.
Autres conseils
Comme vous l'aurez remarqué de la fréquence scrollViewDidScroll: que l'on appelle, UIScrollView ne se contente pas oublier feu et une transition Core Animation: il se déplace manuellement les limites en fonction de touches, accélération, etc. Il n'y a aucun moyen simple de changer cette .
Cependant, si vous être débordés par les événements de défilement, vous pouvez essayer un truc comme suit:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970];
if (timestamp - _savedTimestamp) < 0.1)
return;
_savedTimestamp = timestamp;
// do the rest of your work here
}
H