UITableView à l'intérieur de UIScrollView ne reçoit pas de robinet d'abord après scrollling
Bref
Je rencontre un problème avec un UITableView
à l'intérieur d'un UIScrollView
. Quand je scroll externes scrollView
, le table
ne reçoit pas le willSelect/didSelect
les cas, le premier contact, mais il ne le fait sur le second. Ce qui est encore plus étrange, la cellule elle-même est la touche et la mise en surbrillance de l'état, même lorsque le delegate
ne pas.
Explication détaillée
Mon point de vue de la hiérarchie:
UIView
- UIScrollView (outerscroll)
- Some other views and buttons
- UITableView (tableView)
À l'intérieur de défilement de la vue, j'ai quelques vues supplémentaires que obtenir étendue/fermé de façon dynamique. La vue de la table doit obtenir "fixe" sur le dessus, avec quelques autres éléments de la vue, de sorte que c'est pourquoi j'ai créé cette disposition, qui me permet de déplacer facilement des éléments d'une manière similaire que Apple recommande par l'utilisation des transformations quand le livre arrive.
La Vue de la table est transformé avec un effet de conversion lors de la outerscroll se déplace comme ceci:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.outerScrollView) {
CGFloat tableOffset = scrollView.contentOffset.y - self.fixedHeaderFrame.origin.y;
if (tableOffset > 0) {
self.tableView.contentOffset = CGPointMake(0, tableOffset);
self.tableView.transform = CGAffineTransformMakeTranslation(0, tableOffset);
}
else {
self.tableView.contentOffset = CGPointMake(0, 0);
self.tableView.transform = CGAffineTransformIdentity;
}
//Other similar transformations are done here, but not involving the table
}
Dans ma cellule, si j'en œuvre de ces méthodes:
- (void)setSelected:(BOOL)selected {
[super setSelected:selected];
if (selected) {
NSLog(@"selected");
}
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
[super setHighlighted:highlighted animated:animated];
if (highlighted) {
NSLog(@"highlighted");
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
NSLog(@"touchesBegan");
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
NSLog(@"touchesEnded");
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesCancelled:touches withEvent:event];
NSLog(@"touchesCancelled");
}
Y peut voir cette sortie lors de l'échec (appuyez d'abord sur):
2014-02-10 13:04:40.940 MyOrderApp[5588:70b] highlighted
2014-02-10 13:04:40.940 MyOrderApp[5588:70b] touchesBegan
2014-02-10 13:04:40.978 MyOrderApp[5588:70b] touchesEnded
Et celui-ci lorsque les œuvres (deuxième tap):
2014-02-10 13:05:30.359 MyOrderApp[5588:70b] highlighted
2014-02-10 13:05:30.360 MyOrderApp[5588:70b] touchesBegan
2014-02-10 13:05:30.487 MyOrderApp[5588:70b] touchesEnded
2014-02-10 13:05:30.498 MyOrderApp[5588:70b] expanded
Aucun autre cadre de changement, animation ou tout autre point de vue, l'interaction se fait entre la première et la deuxième pression. Aussi, seulement lors du défilement de grandes quantités, le bug apparaît, mais avec des scrollings de quelques pixels tout continue à fonctionner comme prévu.
J'ai testé la modification de certaines propriétés, mais avec pas de chance. Certaines des choses que j'ai fait:
- Supprimer
userInteractionEnabled
à partir de points de vue autres que le livre et le tableau - Ajouter un appel à
setNeedsLayout
sur la table, de défilement et de la vue principale lorsquescrollViewDidScroll
se produit. - Supprimer les transformations de la table (encore)
J'ai vu certains commentaires sur le comportement inattendu de l'incorporation de UITableViews
à l'intérieur de UIScrollViews
mais je ne peux pas voir une telle avertir dans la documentation officielle par Apple, donc je m'attends à ce que cela fonctionne.
L'application est iOS7+ seulement.
Questions
Quelqu'un a connu des problèmes similaires? Pourquoi est-ce et comment puis-je le résoudre? Je pense que je pourrais être en mesure d'intercepter le robinet geste sur la cellule et de le passer avec un délégué personnalisé ou similaire, mais je voudrais la table pour recevoir la bonne événements et donc mon UITableViewDelegate
le reçoit comme prévu.
Mises à jour
- J'ai essayé de désactiver la cellule de la réutilisation comme suggéré dans un commentaire, mais il se produit toujours de la même manière.
- avez-vous essayé [yourScroll bringSubviewToFront: yourTable]; ?
- Vous mentionnez que cela se produit uniquement lorsque vous faites défiler beaucoup, ce qui m'amène à penser que les loisirs ou le recyclage des tableCells pourrait affecter cette? Pouvez-vous mettre un NSlog à l'intérieur de la cellForRowAtIndexPath: fonction et de voir si ce bug est déclenchée lorsque cela s'appelle?
- merci mais j'ai déjà essayé. En outre, les cellules sont arriver au toucher (en cas d'échec et lorsque l'on travaille), et ils sont à l'intérieur de la table, de sorte que la position de la table ne semble pas être le problème.
- C'était en fait une très bonne astuce, mais cela n'a pas fonctionné non plus. J'ai enlevé les cellules de la réutilisation de le tester et se produit toujours de la même façon. 🙁
- Puis-je vous demander pourquoi êtes-vous à l'aide d'une tableview à l'INTÉRIEUR d'un scrollview? C'est comme avoir une scrollview sur un scrollview...
- Hmm...interessant, pouvez-vous poster le code où vous le journal "élargi"? Est-il dans la de déléguer l'appel?
- Oui, il est dans ma méthode du délégué. J'utilise une source de données générique qui gère le clic, c'est pourquoi je n'ai pas posté, mais la source de données fonctionne partout, tout autour de l'application, sauf qu'ici, il y a donc peu de chances que le problème est là.
- il n'est pas si facile à expliquer en raison de la hiérarchie vue que j'ai besoin de construire, mais, fondamentalement, j'ai besoin de quelques têtes qui s'accrochent sur le dessus lors du défilement de l'extérieur de défilement de la vue, tandis que la table ont leur propre en-tête de vues fonctionne comme prévu et aussi empiler sur le dessus de l'en-tête de section est visible de défilement et le reste. Si j'utilise 1 table alors seulement je ne vais pas être en mesure de reproduire le même comportement
- avez-vous des suplementaire touch geste modules de reconnaissance sur d'autres points de vue?
- avez vous trouver une solution pour cela?
- Avez-vous pensé à elle encore
- Pas de. Ce que j'ai fait est un hack, l'ajout d'un robinet geste de reconnaissance à la table et cliquez sur juste la indexpath du point et appeler le délégué de tableView:willSelectRowAtIndexPath: et tableView:didSelectRowAtIndexPath: (s'il existe)
Vous devez vous connecter pour publier un commentaire.
De La Documentation D'Apple, vous ne devriez pas incorporer un
UITableView
à l'intérieur d'unUIScrollView
.Votre problème est vraiment lié à ce que votre
UIScrollView
n'.Mais si c'est juste pour masquer la tableview en cas de besoin (c'était mon cas), vous pouvez tout simplement passer le
UITableView
dans son superview.J'ai écrit un petit exemple ici : https://github.com/rvirin/SoundCloud/
laisser l'intérieur UITableView de
scrollEnabled
propriété définie commeYES
. cela permet à l'intérieureUITableView
sais pour manipuler de défilement liées à la touche sur leUIScrollView
correctement.bounces
àNO
afin d'éviter tout impair comportement de défilement.scrollEnabled
propriétéYES
etbounces
àNO
résolu le problème.J'ai rencontré ce même problème et trouvé une solution!!
Vous devez définir la
delaysTouchesBegan
de vrai sur votre scrollview, de sorte que la scrollview envoie ses échecs de défilement-geste (c'est à dire le robinet) à ses enfants.var delaysTouchesBegan: Bool
-Une valeur Booléenne déterminant si le récepteur des retards d'envoi touche en entamer la phase de son point de vue.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIGestureRecognizer_Class/index.html#//apple_ref/occ/instp/UIGestureRecognizer/delaysTouchesBegan
Mais il y a un hic...il ne fonctionne pas si vous le faites directement sur le scrollview!
Apparemment, c'est un iOS bug où la définition de cette propriété ne fonctionne pas (merci apple). Toutefois, il y a une solution simple: définissez la propriété directement sur le scrollview pan geste. Bien sûr, cela a fonctionné parfaitement pour moi:
Il semble que votre UiTableView ne reconnaît pas votre robinet. Avez-vous essayé de l'utiliser :
Note d'apple:
appelée lorsque la reconnaissance de l'une des gestureRecognizer ou otherGestureRecognizer serait bloqué par l'autre. retour sur OUI pour permettre à la fois de reconnaître simultanément. l'implémentation par défaut renvoie AUCUN (par défaut pas de deux gestes peuvent être reconnus simultanément)
remarque: le retour de OUI est garanti pour permettre la reconnaissance simultanée. le retour N'est pas garanti pour empêcher la reconnaissance simultanée, comme les autres geste de son délégué peut retourner OUI
Espère que cela va aider.
Geste modules de reconnaissance ne fonctionne pas correctement pour les deux embarqués faire défiler les vues ou les sous-classes.
Essayer une solution de contournement:
Utilisation transparente, la coutume, et en y ajoutant tout dans la cellule
UIButton
avec la bonne balise, ou sous-classeUIButton
et ajouter un chemin d'index de propriété et les écraser à chaque fois réutilisés dans la cellule.Ajouter ce bouton à la propriété de votre cellule personnalisé.
Ajouter une cible souhaitée,
UIControlEvent
(un ou plusieurs) qui pointe vers votre UITableViewDelegate protocole de l'adoption de la classe.Désactiver la sélection de l'IB, et de gérer manuellement la sélection à partir du code.
Cette solution nécessite une attention particulière pour les cas de simple/multi sélection.
UITableViewCell
est sélectionné par un appuyez ou appuyez longuement sur le geste. La solution proposée par moi-même travaillé pendant deux incorporéUITableView
classes (je voulais avoir horizontale de la table comme des lignes qui peuvent être dirigées par un glissement de doigt) résultant dans l'INTERFACE utilisateur de comportement, tout à fait comme prévu (parfaite gestion des de sélection de cellule, et le balayage des deux vues de table). Je peux partager le code si vous le souhaitez.J'ai rencontré un UITableView avec scrollEnabled étant PAS dans un UIScrollView dans un code existant. Je n'ai pas été capable de changer la hiérarchie existante facilement ni activer le défilement, mais venir avec la solution de contournement suivante pour la première appuyez problème:
Encore une fois, c'est juste une solution de contournement de travail dans mon cas précis. Avoir une vue de la table dans un parchemin de point de vue est toujours une mauvaise chose.
Je vous recommande de regarder pour les options comme ne pas laisser votre cellule en surbrillance lorsque vous sont en fait de défilement de l'extérieur de défilement de la vue qui est très facile à manipuler et est la méthode recommandée. Vous pouvez le faire simplement en prenant une valeur booléenne et le basculement dans la méthode ci-dessous
didSelectRowAtIndexPath
, il n'a rien à voir avec la surbrillance.La scrollview est à essayer de comprendre si l'utilisateur a l'intention de faire défiler ou pas, il est donc de retarder la première touche sur le but. Vous pouvez désactiver cette fonction en paramètre
delaysContentTouches
àNO
.J'ai le même problème avec imbriqué UITableView et ont trouvé un travail autour de cela:
Vous aurez besoin de définir la hauteur de l'intérieur de la vue de la table de correspondance avec la hauteur totale de ses cellules, de sorte qu'il n'aura pas de défilement lorsque l'utilisateur fait défiler la vue extérieure.
Espère que cette aide.
Mon erreur a été mise en œuvre de la méthode du délégué:
à la place de celui que j'ai destiné à mettre en œuvre:
Donc uniquement sur la deuxième cellule exploité, parce que c'était lors de la première cellule serait de sélectionné. Stupide erreur faite avec l'aide de la saisie semi-automatique. Juste une pensée pour ceux d'entre vous qui errent ici pour ne pas vous rendre compte que vous avez fait la même erreur de trop.
De votre point de vue contrôleur de mettre ce code dans cellForRowAtIndexPath
Ajouter cette fonction à votre viewController ainsi-
Comme d'autres réponses dites que vous ne devriez pas mettre un tableview dans un scrollview. Une UITableView hérite de UIScrollView de toute façon, donc je suppose que c'est là où les choses deviennent confus. Ce que je fais toujours dans cette situation est:
1) la sous-classe UITableViewController et comprennent une propriété UIView *headView.
2) Dans le parent de UIViewController créer toutes les choses dans un récipient UIView
3) Initialiser votre personnalisé UITableView et ajouter la tableView de l'afficher à la vue du contrôleur de pleine taille
4) Définir la headView à votre UIView gubbins
5) Dans le tableViewController méthode
Faire:
Maintenant, vous avez une vue de la table avec un tas d'autres shizzle en haut.
Profitez-en!
Que, si le toucher la vue de la table qu'elle fonctionnera correctement. aussi avec défilement voir dans la même vue-contrôleur également.
J'ai le même problème, reportez-vous à "l'Imbrication de Défilement des Vues" comme lxx dit.
https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/UIScrollView_pg/NestedScrollViews/NestedScrollViews.html
Un exemple de la croix directionnelle de défilement peut être trouvé dans les Stocks de l'application. La vue de dessus est une vue de table, mais la vue d'en bas est un défilement horizontal de la vue configuré à l'aide de la pagination mode. Alors que deux de ses trois sous-vues sont des vues personnalisées, le troisième point de vue (qui contient les articles de presse) est un UITableView (une sous-classe de UIScrollView) qui est une sous-vue de la barre de défilement horizontale de la vue. Après un défilement horizontal pour les nouvelles, vous pouvez alors faire défiler son contenu verticalement.
C'est un travail