Lorsque mon application revient à son contrôleur de vue racine, dans la viewDidAppear:
méthode, je dois supprimer toutes les sous-vues.
Comment puis-je faire ceci?
Edit: Avec merci à cocoafan : Cette situation est embrouillé par le fait que NSView
et UIView
gérer les choses différemment. Pour NSView
(développement Mac de bureau uniquement), vous pouvez simplement utiliser ce qui suit:
[someNSView setSubviews:[NSArray array]];
Pour UIView
(développement iOS uniquement), vous pouvez l'utiliser en toute sécurité makeObjectsPerformSelector:
car la subviews
propriété renverra une copie du tableau de sous-vues:
[[someUIView subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
Merci à Tommy d' avoir signalé que cela makeObjectsPerformSelector:
semble modifier le subviews
tableau pendant son énumération (ce qu'il fait pour NSView
, mais pas pour UIView
).
Veuillez consulter cette question SO pour plus de détails.
Remarque: L' utilisation de l'une de ces deux méthodes supprimera toutes les vues que contient votre vue principale et les libérera si elles ne sont pas conservées ailleurs. De la documentation d'Apple sur removeFromSuperview :
Si la vue d'ensemble du récepteur n'est pas nulle, cette méthode libère le récepteur. Si vous prévoyez de réutiliser la vue, assurez-vous de la conserver avant d'appeler cette méthode et assurez-vous de la libérer selon vos besoins lorsque vous en avez terminé ou après l'avoir ajoutée à une autre hiérarchie de vues.
UIView
renvoie une copie dusubviews
tableau mutable, donc ce code fonctionne. Histoire complètement différente sur le bureau, où le même code lèvera une exception. Voir stackoverflow.com/questions/4665179/…someUIView.Subviews.All( v => { v.RemoveFromSuperview(); return true; } );
. À mon humble avis propre à dire ce que vous entendez:someUIView.Subviews.ToList().ForEach( v => v.RemoveFromSuperview() );
.Obtenez toutes les sous-vues de votre contrôleur racine et envoyez à chacune un removeFromSuperview:
la source
self.view
comme vous l'avez fait.for (UIView *v in [self.view subviews])
c'est plus facileDans Swift, vous pouvez utiliser une approche fonctionnelle comme celle-ci:
À titre de comparaison, l' approche impérative ressemblerait à ceci:
Cependant, ces extraits de code ne fonctionnent que sur iOS / tvOS , les choses sont un peu différentes sur macOS.
la source
(subviews as [UIView]).map { $0.removeFromSuperview() }
.map
. ceci est un effet secondaire pur et est mieux géré comme ceci:view.subviews.forEach() { $0.removeFromSuperview() }
Si vous souhaitez supprimer toutes les sous-vues sur votre UIView (ici
yourView
), alors écrivez ce code à votre bouton, cliquez sur:la source
Cela ne s'applique qu'à OSX car dans iOS, une copie du tableau est conservée
Lors de la suppression de toutes les sous-vues, il est judicieux de commencer la suppression à la fin du tableau et de continuer à supprimer jusqu'au début. Cela peut être accompli avec ces deux lignes de code:
SWIFT 1.2
ou (moins efficace, mais plus lisible)
REMARQUE
Vous ne devez PAS supprimer les sous-vues dans l'ordre normal, car cela peut provoquer un blocage si une instance UIView est supprimée avant que le
removeFromSuperview
message ait été envoyé à tous les objets du tableau. (Évidemment, la suppression du dernier élément ne provoquerait pas de plantage)Par conséquent, le code
ne doit PAS être utilisé.
Citation de la documentation Apple sur makeObjectsPerformSelector :
(ce qui serait la mauvaise direction à cet effet)
la source
removeFromSuperview
terminé, l'UIView sera supprimé du tableau, et s'il n'y a pas d'autres instances vivantes ayant une relation forte avec l'UIView, l'UIView sera également supprimée. Cela peut provoquer une exception hors limite.[yourView subviews]
retourne une COPIE du tableau, est donc sûr. (NOTEZ que sur OSX, ce que vous dites est correct.)Essayez de cette façon Swift 2.0
la source
forEach
solution basée a été ajoutée après la vôtre, cela m'a manqué. Mes excuses.Utilisez le code suivant pour supprimer toutes les sous-vues.
la source
Utilisation de l'
UIView
extension Swift :la source
Dans l'objectif-C, allez-y et créez une méthode de catégorie hors de la classe UIView.
la source
la source
Afin de supprimer toutes les sous-vues Syntaxe:
Utilisation:
Cette méthode est présente dans le fichier NSArray.h et utilise l'interface NSArray (NSExtendedArray)
la source
Si vous utilisez Swift, c'est aussi simple que:
La philosophie est similaire à l'
makeObjectsPerformSelector
approche, mais avec un peu plus de sécurité de type.la source
map
ne devrait pas entraîner d'effets secondaires. De plus, le même résultat peut être obtenu viaforEach
.Pour ios6 utilisant la mise en page automatique, j'ai dû ajouter un peu de code pour supprimer également les contraintes.
Je suis sûr qu'il y a une façon plus nette de le faire, mais cela a fonctionné pour moi. Dans mon cas, je ne pouvais pas utiliser un direct
[tagview removeConstraints:tagview.constraints]
car il y avait des contraintes définies dans XCode qui étaient effacées.la source
Dans monotouch / xamarin.ios, cela a fonctionné pour moi:
la source
Pour supprimer toutes les sous-vues des super-vues:
la source
iCount++
etiCount--
, en laissant l'index le même, ce sera donc une boucle infinie si[oSubView count]>0
. C'est définitivement un code bogué et NON UTILISABLE .