Respostas:
Edit: Com agradecimentos a cocoafan : Esta situação é confusa pelo fato de que NSView
e UIView
lidar com as coisas de maneira diferente. Para NSView
(apenas desenvolvimento para desktops Mac), você pode simplesmente usar o seguinte:
[someNSView setSubviews:[NSArray array]];
Para UIView
(apenas desenvolvimento iOS), você pode usar com segurança makeObjectsPerformSelector:
porque a subviews
propriedade retornará uma cópia da matriz de sub-visualizações:
[[someUIView subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
Obrigado a Tommy por apontar que makeObjectsPerformSelector:
parece modificar a subviews
matriz enquanto ela está sendo enumerada (o que serve para NSView
, mas não para UIView
).
Por favor, veja esta pergunta para mais detalhes.
Nota: O uso de um desses dois métodos removerá todas as visualizações que a visualização principal contém e as liberará , se não forem mantidas em outro lugar. Na documentação da Apple sobre removeFromSuperview :
Se a super visão do receptor não for nula, esse método libera o receptor. Se você planeja reutilizar a visualização, mantenha-a antes de chamar este método e libere-a conforme apropriado quando terminar ou após adicioná-la a outra hierarquia de visualização.
UIView
retorna uma cópia da subviews
matriz mutável, portanto esse código simplesmente funciona. História completamente diferente na área de trabalho, onde o mesmo código gera uma exceção. Veja stackoverflow.com/questions/4665179/…
someUIView.Subviews.All( v => { v.RemoveFromSuperview(); return true; } );
. IMHO mais limpo para dizer o que quer dizer: someUIView.Subviews.ToList().ForEach( v => v.RemoveFromSuperview() );
.
Obtenha todas as subvisões do seu controlador raiz e envie a removeFromSuperview:
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
self.view
como você.
for (UIView *v in [self.view subviews])
é mais fácil
No Swift, você pode usar uma abordagem funcional como esta:
view.subviews.forEach { $0.removeFromSuperview() }
Como comparação, a abordagem imperativa ficaria assim:
for subview in view.subviews {
subview.removeFromSuperview()
}
Esses trechos de código funcionam apenas no iOS / tvOS , porém, as coisas são um pouco diferentes no macOS.
(subviews as [UIView]).map { $0.removeFromSuperview() }
.map
. este é um efeito colateral pura e é melhor tratadas assim:view.subviews.forEach() { $0.removeFromSuperview() }
Se você deseja remover todas as subvisões no seu UIView (aqui yourView
), escreva esse código no seu botão, clique em:
[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
Isso se aplica apenas ao OSX, já que no iOS uma cópia da matriz é mantida
Ao remover todas as subvisões, é uma boa idéia começar a excluir no final da matriz e continuar excluindo até chegar ao início. Isso pode ser realizado com essas duas linhas de código:
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 (menos eficiente, mas mais legível)
for subview in mySuperView.subviews.reverse() {
subview.removeFromSuperview()
}
NOTA
Você NÃO deve remover as subvisões na ordem normal, pois isso pode causar uma falha se uma instância do UIView for excluída antes que a removeFromSuperview
mensagem seja enviada a todos os objetos da matriz. (Obviamente, excluir o último elemento não causaria uma falha)
Portanto, o código
[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
NÃO deve ser usado.
Citações da documentação da Apple sobre makeObjectsPerformSelector :
Envia para cada objeto na matriz a mensagem identificada por um determinado seletor, começando com o primeiro objeto e continuando através da matriz até o último objeto.
(qual seria a direção errada para esse fim)
removeFromSuperview
terminar, o UIView será removido da matriz e, se não houver outras instâncias vivas com uma forte relação com o UIView, o UIView também será excluído. Isso pode causar uma exceção fora do limite.
[yourView subviews]
retorna uma cópia do array, portanto, é seguro. (Note que no OSX, o que você diz é correto.)
Experimente desta maneira o Swift 2.0
view.subviews.forEach { $0.removeFromSuperview() }
forEach
solução baseada foi adicionada após a sua, eu perdi isso. Desculpas.
Use o código a seguir para remover todas as subvisões.
for (UIView *view in [self.view subviews])
{
[view removeFromSuperview];
}
Para remover todas as subviews Sintaxe:
- (void)makeObjectsPerformSelector:(SEL)aSelector;
Uso:
[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
Este método está presente no arquivo NSArray.h e usa a interface NSArray (NSExtendedArray)
Se você estiver usando o Swift, é tão simples quanto:
subviews.map { $0.removeFromSuperview }
É semelhante em filosofia à makeObjectsPerformSelector
abordagem, porém com um pouco mais de segurança de tipo.
map
não deve resultar em efeitos colaterais. Além disso, o mesmo resultado pode ser alcançado via forEach
.
Para o ios6 usando o autolayout, tive que adicionar um pouco de código para remover as restrições também.
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)];
Tenho certeza de que há uma maneira mais clara de fazer isso, mas funcionou para mim. No meu caso, eu não poderia usar um direto, [tagview removeConstraints:tagview.constraints]
pois havia restrições definidas no XCode que estavam sendo eliminadas.
No monotouch / xamarin.ios, isso funcionou para mim:
SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview);
Para remover todas as subvisões das superviews:
NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
id object = [oSubView objectAtIndex:iCount];
[object removeFromSuperview];
iCount--;
}
iCount++
e iCount--
, deixando o índice o mesmo, então haverá um loop infinito se [oSubView count]>0
. Este é definitivamente um código de buggy e NÃO UTILIZÁVEL .