Удалить все подпредставления? - PullRequest
308 голосов
/ 28 января 2010

Когда мое приложение возвращается к своему корневому контроллеру представления, в методе viewDidAppear: мне нужно удалить все подпредставления.

Как я могу это сделать?

Ответы [ 15 ]

563 голосов
/ 28 января 2010

Редактировать: Благодаря cocoafan : Эта ситуация осложняется тем, что NSView и UIView обрабатывают вещи по-разному. Для NSView (только для настольных компьютеров Mac) вы можете просто использовать следующее:

[someNSView setSubviews:[NSArray array]];

Для UIView (только для iOS) можно смело использовать makeObjectsPerformSelector:, поскольку свойство subviews вернет копию массива подпредставлений:

[[someUIView subviews]
 makeObjectsPerformSelector:@selector(removeFromSuperview)];

Спасибо Томми за то, что он указал, что makeObjectsPerformSelector:, кажется, изменяет массив subviews во время его перечисления (что он делает для NSView, но не для UIView).

Пожалуйста, смотрите этот вопрос для более подробной информации.

Примечание: Использование любого из этих двух методов удалит все представления, которые содержит ваш основной вид , и освободит их , если они не сохранены в другом месте. Из документации Apple по убрать из Superuperview :

Если суперпредставление получателя не равно нулю, этот метод освобождает получателя. Если вы планируете повторно использовать представление, обязательно сохраните его перед вызовом этого метода и обязательно отмените его, когда вы закончите с ним или после добавления его в другую иерархию представления.

170 голосов
/ 28 января 2010

Получите все подпредставления от вашего корневого контроллера и отправьте каждому a removeFromSuperview:

NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
    [v removeFromSuperview];
}
106 голосов
/ 25 ноября 2014

В Swift вы можете использовать функциональный подход , например:

view.subviews.forEach { $0.removeFromSuperview() }

Для сравнения, императивный подход будет выглядеть так:

for subview in view.subviews {
    subview.removeFromSuperview()
}

Эти фрагменты кода работают только в iOS / tvOS , но в macOS все немного по-другому.

13 голосов
/ 03 мая 2013

Если вы хотите удалить все подпредставления в вашем UIView (здесь yourView), то напишите этот код при нажатии кнопки:

[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
8 голосов
/ 22 мая 2014

Это относится только к OSX, так как в iOS сохраняется копия массива

При удалении всех подпредставлений хорошей идеей будет начать удаление в конце массива и продолжать удаление, пока не дойдете до начала. Это можно сделать с помощью двух строк кода:

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();
}

или (менее эффективно, но более читабельно)

for subview in mySuperView.subviews.reverse() {
    subview.removeFromSuperview()
}

Примечание

Вы должны НЕ удалить подпредставления в обычном порядке, поскольку это может привести к сбою, если экземпляр UIView удаляется до того, как сообщение removeFromSuperview было отправлено всем объектам массива. (Очевидно, что удаление последнего элемента не приведет к сбою)

Следовательно, код

[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

следует НЕ использовать.

Цитата из Документация Apple о makeObjectsPerformSelector :

Посылает каждому объекту в массиве сообщение, идентифицированное данным селектор, начиная с первого объекта и продолжая массив до последнего объекта.

(что было бы неправильным направлением для этой цели)

4 голосов
/ 19 марта 2017

Используйте следующий код для удаления всех подпредставлений.

for (UIView *view in [self.view subviews]) 
{
 [view removeFromSuperview];
}
4 голосов
/ 18 ноября 2015

Попробуйте этот способ Swift 2.0

view.subviews.forEach { $0.removeFromSuperview() }
2 голосов
/ 03 декабря 2016

В target-C продолжайте и создайте метод категории вне класса UIView.

- (void)removeAllSubviews
{
    for (UIView *subview in self.subviews)
        [subview removeFromSuperview];
}
2 голосов
/ 08 сентября 2015

Использование Swift UIView расширение:

extension UIView {
    func removeAllSubviews() {
        for subview in subviews {
            subview.removeFromSuperview()
        }
    }
}
2 голосов
/ 29 мая 2015

Если вы используете Swift, это просто:

subviews.map { $0.removeFromSuperview }

По своей философии он похож на подход makeObjectsPerformSelector, но с большей безопасностью типов.

...