Удалить все подпункты?

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

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

Ответ 1

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

[someNSView setSubviews:[NSArray array]];

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

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

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

Подробнее см. этот вопрос.

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

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

Ответ 2

Получите все подпрограммы из вашего корневого контроллера и отправьте каждый файл removeFromSuperview:

NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
    [v removeFromSuperview];
}

Ответ 3

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

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

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

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

Эти фрагменты кода работают только в iOS/tvOS, хотя в MacOS все немного иначе.

Ответ 4

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

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

Ответ 5

Это относится только к 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 сообщение removeFromSuperview будет отправлено всем объектам массива. (Очевидно, что удаление последнего элемента не приведет к сбою)

Поэтому код

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

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

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

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

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

Ответ 6

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

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

Ответ 7

Используйте следующий код, чтобы удалить все подзаголовки.

for (UIView *view in [self.view subviews]) 
{
 [view removeFromSuperview];
}

Ответ 8

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

subviews.map { $0.removeFromSuperview }

Это похоже на философию подходом makeObjectsPerformSelector, однако с немного большей безопасностью типа.

Ответ 9

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

extension UIView {
    func removeAllSubviews() {
        for subview in subviews {
            subview.removeFromSuperview()
        }
    }
}

Ответ 10

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

- (void)removeAllSubviews
{
    for (UIView *subview in self.subviews)
        [subview removeFromSuperview];
}

Ответ 11

Чтобы удалить все подпрограммы Синтаксис:

- (void)makeObjectsPerformSelector:(SEL)aSelector;

Использование:

[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

Этот метод присутствует в файле NSArray.h и использует интерфейс NSArray (NSExtendedArray)

Ответ 12

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

Ответ 13

Для ios6, использующего автоотключение, мне пришлось добавить немного кода, чтобы удалить ограничения.

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)];

Я уверен, что это лучший способ сделать это, но это сработало для меня. В моем случае я не мог использовать прямой [tagview removeConstraints:tagview.constraints], поскольку в XCode были установлены ограничения, которые очищались.

Ответ 14

В monotouch/xamarin.ios это сработало для меня:

SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview);

Ответ 15

Чтобы удалить все подзаголовки из супервизоров:

NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
    id object = [oSubView objectAtIndex:iCount];
    [object removeFromSuperview];
    iCount--;
}