Quando meu aplicativo retorna ao seu controlador de visualização raiz, no diretório viewDidAppear:
método preciso remover todas as subvisões.
Como posso fazer isso?
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 dasubviews
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:
fonte
self.view
como você.for (UIView *v in [self.view subviews])
é mais fácilNo Swift, você pode usar uma abordagem funcional como esta:
Como comparação, a abordagem imperativa ficaria assim:
Esses trechos de código funcionam apenas no iOS / tvOS , porém, as coisas são um pouco diferentes no macOS.
fonte
(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:fonte
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:
SWIFT 1.2
ou (menos eficiente, mas mais legível)
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
NÃO deve ser usado.
Citações da documentação da Apple sobre makeObjectsPerformSelector :
(qual seria a direção errada para esse fim)
fonte
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
fonte
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.
fonte
Usando a
UIView
extensão Swift :fonte
No objetivo C, vá em frente e crie um método de categoria fora da classe UIView.
fonte
fonte
Para remover todas as subviews Sintaxe:
Uso:
Este método está presente no arquivo NSArray.h e usa a interface NSArray (NSExtendedArray)
fonte
Se você estiver usando o Swift, é tão simples quanto:
É semelhante em filosofia à
makeObjectsPerformSelector
abordagem, porém com um pouco mais de segurança de tipo.fonte
map
não deve resultar em efeitos colaterais. Além disso, o mesmo resultado pode ser alcançado viaforEach
.Para o ios6 usando o autolayout, tive que adicionar um pouco de código para remover as restrições também.
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.fonte
No monotouch / xamarin.ios, isso funcionou para mim:
fonte
Para remover todas as subvisões das superviews:
fonte
iCount++
eiCount--
, 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 .