40 votes

Quelle est la manière correcte de supprimer une vue secondaire d'une hiérarchie de vues et de la détruire ?

J'ai un UIView parent avec un certain nombre de sous-vues. Périodiquement, je dois supprimer une sous-vue et la retirer complètement du système. Quelle est la bonne façon de procéder ? J'ai essayé ceci :

UIView *v = [self.containerView viewWithTag:[n integerValue]];

[v removeFromSuperview];

et j'ai obtenu un résultat bizarre. Précédemment présent UIView a aussi disparu. Qu'est-ce qui se passe ?

72voto

mahboudz Points 23653

Essayez ça :

UIView *v = [self.containerView viewWithTag:[n integerValue]];
v.hidden = YES;
[self.containerView bringSubviewToFront:v];
[v removeFromSuperview];

Une autre chose que je viens de remarquer dans le document sur la classe UIView - voir la dernière phrase :

removeFromSuperview Détache le récepteur de sa vue supérieure et de sa fenêtre, et le supprime de la chaîne des répondeurs.

  • (void)removeFromSuperview

Discussion Si la vue supérieure du récepteur n'est pas nil, cette méthode libère le récepteur. Si vous prévoyez de réutiliser la vue, veillez à la conserver avant d'appeler cette méthode et veillez à la libérer comme il se doit lorsque vous en avez fini avec elle ou après l'avoir ajoutée à une autre hiérarchie de vues.

N'invoquez jamais cette méthode pendant l'affichage.

MISE À JOUR : Nous sommes maintenant en 2014 et la suppression d'une sous-vue sans la masquer fonctionne parfaitement. Le code de l'affiche originale devrait fonctionner tel quel :

UIView *v = [self.containerView viewWithTag:[n integerValue]];
[v removeFromSuperview];

Cela supprimera v et toutes les vues qu'il a attachées à lui en tant que sous-vues, laissant derrière lui containerView et tous les frères et sœurs de v.

1 votes

inquiétant N'invoquez jamais cette méthode pendant l'affichage.

0 votes

Rien de plus simple, il suffit de faire comme le dit Blackberry pour (UIView *s dans [view subviews]) [s removeFromSuperview] ;

0 votes

En 2009, si vous supprimiez une vue secondaire avant de la masquer, vous obteniez des résultats étranges. C'est du moins ce que je voyais, tout comme l'auteur de l'article original. Et il y avait auparavant cet avertissement dans la référence de la classe UIView, qui a été remplacé par un autre. Je dirais que la méthode utilisée par l'auteur de l'article original pour supprimer une sous-vue est probablement correcte maintenant et ne nécessite pas de code supplémentaire. (il ne supprime qu'une seule sous-vue)

40voto

Blackberry Points 1042

Pour supprimer toutes les sous-vues de votre vue :

for(UIView *subview in [view subviews]) {
   [subview removeFromSuperview];
}

Si vous voulez supprimer une vue spécifique, alors seulement :

for(UIView *subview in [view subviews]) {
  if([subview isKindOfClass:[UIButton class]]) {
     [subview removeFromSuperview];
 } else {
     // Do nothing - not a UIButton or subclass instance
 }
}

Vous pouvez également supprimer des sous-vues par valeur de balise :

for(UIView *subview in [view subviews]) {
    if(subview.tag==/*your subview tag value here*/) {
        [subview removeFromSuperview];

    } else {
        // Do nothing - not a UIButton or subclass instance
    }
}

3 votes

Je préfère cette réponse à celle qui a été acceptée. Elle semble être une approche beaucoup plus directe - et vous avez été assez minutieux en incluant des options pour choisir ce que quelqu'un pourrait vouloir supprimer. +1.

0 votes

Hmm... en fait, maintenant que j'ai essayé de l'exécuter, cela ne fonctionne pas. J'utilise l'option isKindOfClass. J'ai UILabels et UISliders dans mon UIView, et j'essaie de supprimer tous les sliders, donc j'ai : if ([subview isKindOfClass:[UISlider class]]); et cela renvoie vrai pour tout, y compris les étiquettes, donc tout est supprimé. J'ai essayé de remplacer isKindOfClass par isMemberOfClass, mais cela ne fonctionne pas non plus. Y a-t-il quelque chose de spécial à propos de UISliders qui ferait que cela ne fonctionne pas ?

0 votes

J'ai trouvé mon problème, j'avais une faute de frappe qui m'a pris une éternité à trouver. Le code fonctionne exactement comme il est montré ici.

0voto

sujal Points 931

C'est la bonne idée générale. Ces autres UIViews qui disparaissent, quelle est leur relation avec cette UIView ? Sont-elles des sous-vues de cette vue ? Sont-elles désallouées par la méthode dealloc de la vue que vous supprimez ?

Êtes-vous sûr que vos étiquettes sont uniques ?

Sujal

0 votes

Tous les frères et sœurs de la vue que j'essaie de supprimer disparaissent instantanément de l'écran. Que se passe-t-il ?

0 votes

Tous les frères et sœurs ont des étiquettes uniques, c'est ainsi que je me réfère aux vues.

0voto

NSResponder Points 14459

Disparaissent-ils simplement de l'écran, ou disparaissent-ils de l'écran ? et la hiérarchie des vues ? Que vous montre le débogueur ?

0voto

Kevlar Points 3988

Est-il possible que cell.contentView ait la même balise que la sous-vue que vous voulez supprimer ? Selon l'indicateur documentation viewWithTag supprime :

La vue dans la hiérarchie du récepteur qui correspond à la balise. Le récepteur est inclus dans la recherche.

Si c'est le cas, il se peut que vous supprimiez par inadvertance cell.contentView de la cellule. Si n est égal à zéro et que le contentview de votre cellule n'est pas associé à une balise, la valeur par défaut est de 0 et c'est ce qui se produit.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X