En utilisant le storyboard, j'ai placé une imageView
comme mon tableView's
headerView
dans une ViewController
.
Voici comment mon story-board est mis en place:
Selon les données consultées par l'utilisateur, la variable viewController
affichera ou masquera la variable headerView
. Ma question est la suivante: lorsque la headerView
est visible et que l'utilisateur glisse sur la tableView
, comment puis-je demander à la imageView
de coller à la fois à la navigationBar
et à la tableView
alors qu'elle redimensionne pour couvrir l'espace entre les deux?
C'est ce qu'il fait actuellement:
Mais voici ce que je vais faire:
Toute aide serait grandement appréciée. J'ai consulté des bibliothèques de parallaxe, mais aucune ne prend en charge sectionTitles, et je ne cherche pas nécessairement non plus l'effet de parallaxe. Lorsque l'utilisateur fait défiler l'écran vers le haut, je souhaite que ce dernier retourne à la vue normale et ne masque pas l'en-tête. Merci!
METTRE À JOUR:
J'ai suivi les conseils postés par Dany ci-dessous et fait le Suivant:
-(void)scrollViewDidScroll:(UIScrollView*)scrollView { CGRect initialFrame = CGRectMake(0, 0, 320, 160); if (scrollView.contentOffset.y < 0) { initialFrame.size.height =! scrollView.contentOffset.y; childHeaderView.frame = initialFrame; } }
childHeaderView est une imageView et pour une raison quelconque, lorsque je glisse vers le bas, l'image monte (comme la moitié derrière la barre de navigation) et ne revient pas. Tout conseil serait très appréciée!! Merci!
J'ai récemment posté un article sur la réalisation de cette contrainte en utilisant des contraintes qui pourraient aider, il s'avère que c'était assez simple.
Voici le lien: Créer un effet de parallaxe sur UIScrollView en utilisant des contraintes
Tout d'abord, vous devez supprimer la UIImageView
de l'en-tête et l'ajouter en tant que simple UIImageView
au-dessus de la UITableView
puis, puisque le protocole UITableViewDelegate
est conforme au protocole UIScrollViewDelegate
, vous pouvez implémenter la méthode scrollViewDidScroll:
pour vérifier quand la tableView
défile et a un effet bouncing
. . quelque chose comme ça:
-(void)someInitMethod {
initialFrame = yourHeaderView.frame;
}
-(void)scrollViewDidScroll:(UIScrollView*)scrollView {
if(scrollView.contentOffset.y < 0) {
initialFrame.size.height -= scrollView.contentOffset.y;
yourHeaderView.frame = initialFrame;
}
}
Assurez-vous également que vous avez défini la variable contentMode
appropriée pour votre UIImageView
. De plus, je pense que cette implémentation va créer un effet de rebond mais je ne suis pas sûr car je ne peux pas le tester pour le moment mais je pense que c'est un bon point de départ pour vous.
Voici comment je l'ai réalisé. Dans mon cas, j'utilisais une vue cartographique en haut:
viewDidLoad
, ajoutez ce qui suit: tableView.contentInset = UIEdgeInsetsMake(200, 0, 0, 0)
où 200
est la hauteur de la vue. Cela poussera le contenu de la vue tableau vers le bas.Dans le contrôleur de vue, ajoutez le code suivant, qui redimensionne la vue en fonction du défilement:
func scrollViewDidScroll(scrollView: UIScrollView) {
var scrollOffset = scrollView.contentOffset.y
var headerFrame = mapView.frame
if (scrollOffset < 0) {
// Adjust map
headerFrame = CGRect(x: mapView.frame.Origin.x,
y: mapView.frame.Origin.y,
width: mapView.frame.size.width,
height: -scrollOffset)
} else {
// Adjust map
headerFrame = CGRect(x: mapView.frame.Origin.x,
y: mapView.frame.Origin.y,
width: mapView.frame.size.width,
height: 0)
}
mapView.frame = headerFrame
}
Si je pouvais mettre contentInset
dans le storyboard, ce serait encore plus joli
Les solutions précédentes sur cette page m'avaient posé quelques problèmes lorsque j'avais besoin que cela fonctionne avec les titres de section et la barre d'index. J'ai donc proposé moi-même la solution suivante. Notez s'il vous plaît; Je n'utilise pas l'autolayout dans mon projet et je ne l'ai testé que sur iOS9 +;
Dans le storyboard de votre projet:
Ensuite, allez sur votre UIViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Remove view from table header and place it in the background instead.
[self.headerView removeFromSuperview];
UIView *backgroundView = [UIView new];
[backgroundView addSubview:self.headerView];
self.tableView.backgroundView = backgroundView;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
/* Set initialScrollOffset ivar to start offset, because in my case
the scroll offset was affected by the statusbar + navigation bar heights
and the view controller's "extend edges under top bars" option. */
initialScrollOffset = self.tableView.contentOffset.y;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
/* Modify headerView height only if the table content gets pulled
beyond initial offset. */
if (scrollView.contentOffset.y < initialScrollOffset) {
CGRect frame = self.headerView.frame;
frame.size.height = self.tableView.tableHeaderView.frame.size.height + -scrollView.contentOffset.y;
self.headerView.frame = frame;
}
}
J'avais besoin de cette implémentation uniquement pour un en-tête d'étirement avec une couleur d'arrière-plan et des étiquettes. Il devrait cependant être facile d’ajouter un UIImageView à cet en-tête.
De plus, les étapes 1 à 5 sont bien sûr facultatives. Vous pouvez créer par programme votre vue en-tête ou utiliser un fichier XIB à la place. Tant que vous vous assurez que la table a une vue d'en-tête Clear Colored définie avec la même hauteur que l'en-tête souhaité, car elle sert d'espaceur pour conserver vos titres de cellules et de sections en ligne.
MODIFIER:
J'ai trouvé un moyen encore plus propre d'accomplir cela.
viewDidLoad
ci-dessus, il n'est pas nécessaire d'extraire UIView de son conteneur et nous n'avons pas besoin de le définir en tant qu'arrière-plan de table.scrollViewDidScroll:
en ceci:UIViewController.m:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y < initialScrollOffset) {
CGRect frame = self.headerView.frame;
frame.size.height = self.tableView.tableHeaderView.frame.size.height - scrollView.contentOffset.y;
frame.Origin.y = self.tableView.tableHeaderView.frame.Origin.y + scrollView.contentOffset.y;
self.headerView.frame = frame;
}
}
C'est tout. La seule différence visuelle par rapport à l’autre solution est que le contenu défilera maintenant avec le reste des cellules au lieu d’être recouvertes par celles-ci.
S'il vous plaît jeter un oeil à ce https://github.com/matteogobbi/MGSpotyViewController qui implémente le même effet selon vos besoins.
Je ne sais pas si cela vous aiderait ou non ..
Réglez votre délégué de défilement à soi-même.
et ensuite implémenter ceci:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
float scrollViewHeight = scrollView.frame.size.height;
float scrollContentSizeHeight = scrollView.contentSize.height;
float scrollOffset = scrollView.contentOffset.y;
if (scrollOffset == 0)
{
// then we are at the top
}
else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
{
// then we are at the end
// Do what you need here
}
}