Réponses:
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 du subviews
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:
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
self.view
comme vous l'avez fait.
for (UIView *v in [self.view subviews])
c'est plus facile
Dans Swift, vous pouvez utiliser une approche fonctionnelle comme celle-ci:
view.subviews.forEach { $0.removeFromSuperview() }
À titre de comparaison, l' approche impérative ressemblerait à ceci:
for subview in view.subviews {
subview.removeFromSuperview()
}
Cependant, ces extraits de code ne fonctionnent que sur iOS / tvOS , les choses sont un peu différentes sur macOS.
(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:
[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
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:
for (int i=mySuperView.subviews.count-1; i>=0; i--)
[[mySuperView.subviews objectAtIndex:i] removeFromSuperview];
SWIFT 1.2
for var i=mySuperView.subviews.count-1; i>=0; i-- {
mySuperView.subviews[i].removeFromSuperview();
}
ou (moins efficace, mais plus lisible)
for subview in mySuperView.subviews.reverse() {
subview.removeFromSuperview()
}
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
[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
ne doit PAS être utilisé.
Citation de la documentation Apple sur makeObjectsPerformSelector :
Envoie à chaque objet du tableau le message identifié par un sélecteur donné, en commençant par le premier objet et en continuant à travers le tableau jusqu'au dernier objet.
(ce qui serait la mauvaise direction à cet effet)
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
view.subviews.forEach { $0.removeFromSuperview() }
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.
for (UIView *view in [self.view subviews])
{
[view removeFromSuperview];
}
Afin de supprimer toutes les sous-vues Syntaxe:
- (void)makeObjectsPerformSelector:(SEL)aSelector;
Utilisation:
[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
Cette méthode est présente dans le fichier NSArray.h et utilise l'interface NSArray (NSExtendedArray)
Si vous utilisez Swift, c'est aussi simple que:
subviews.map { $0.removeFromSuperview }
La philosophie est similaire à l' makeObjectsPerformSelector
approche, mais avec un peu plus de sécurité de type.
map
ne devrait pas entraîner d'effets secondaires. De plus, le même résultat peut être obtenu via forEach
.
Pour ios6 utilisant la mise en page automatique, j'ai dû ajouter un peu de code pour supprimer également les contraintes.
NSMutableArray * constraints_to_remove = [ @[] mutableCopy] ;
for( NSLayoutConstraint * constraint in tagview.constraints) {
if( [tagview.subviews containsObject:constraint.firstItem] ||
[tagview.subviews containsObject:constraint.secondItem] ) {
[constraints_to_remove addObject:constraint];
}
}
[tagview removeConstraints:constraints_to_remove];
[ [tagview subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
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.
Dans monotouch / xamarin.ios, cela a fonctionné pour moi:
SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview);
Pour supprimer toutes les sous-vues des super-vues:
NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
id object = [oSubView objectAtIndex:iCount];
[object removeFromSuperview];
iCount--;
}
iCount++
et iCount--
, 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 .