Удалить все подвиды?
когда мое приложение вернется к своему корневому контроллеру представления, в viewDidAppear:
метод мне нужно удалить все подвиды.
Как я могу это сделать?
15 ответов:
Edit: С благодарностью кокосовый орех: эта ситуация запутана тем, что
NSView
иUIView
обрабатывать вещи по-разному. ИбоNSView
(только для разработки настольных компьютеров Mac), вы можете просто использовать следующее:[someNSView setSubviews:[NSArray array]];
на
UIView
(только для разработки iOS), вы можете безопасно использоватьmakeObjectsPerformSelector:
потому чтоsubviews
свойство будет возвращать скопировать из массива подвидов:[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
спасибо Томми за то, что указал на это
makeObjectsPerformSelector:
появляется изменитьsubviews
массив во время его перечисления (что он делает дляNSView
, а неUIView
).см. это так вопрос для более подробной информации.
Примечание: использование любого из этих двух методов удалит все представления, которые содержит ваш основной вид и освободить их, если они не сохраняются в другом месте. Из документации Apple по removeFromSuperview:
если супервизор приемника не равен нулю, этот метод освобождает приемник. Если вы планируете повторно использовать представление, обязательно сохраните его перед вызовом этого метода и обязательно освободите его, когда вы закончите с ним или после добавления его в другую иерархию представлений.
получить все подвиды от вашего корневого контроллера и отправить каждому removeFromSuperview:
NSArray *viewsToRemove = [self.view subviews]; for (UIView *v in viewsToRemove) { [v removeFromSuperview]; }
на Свифт можно использовать функциональный подход такой:
view.subviews.forEach { .removeFromSuperview() }
для сравнения:императивный подход будет выглядеть так:
for subview in view.subviews { subview.removeFromSuperview() }
эти фрагменты кода работают только в iOS / tvOS хотя, на macOS все немного по-другому.
Если вы хотите удалить все подвиды на вашем UIView (здесь
yourView
), затем написать этот код на кнопку нажмите:[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
при удалении всех подвидов, это хорошая идея, чтобы начать удаление в конце массива и продолжать удалять, пока вы не достигнете начала. Это можно сделать с помощью этих двух строк кода:
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:
отправляет каждому объекту в массиве сообщение, идентифицированное заданным селектор, начиная с первого объекта и продолжая через массив до последнего объекта.
(что было бы неправильным направлением для этой цели)
используйте следующий код для удаления всех вложенных представлений.
for (UIView *view in [self.view subviews]) { [view removeFromSuperview]; }
Если вы используете Swift, это так же просто, как:
subviews.map { .removeFromSuperview }
это похоже в философии на
makeObjectsPerformSelector
подход, однако с немного большей безопасностью типа.
в objective-C, идти вперед и создать метод категории от класса UIView.
- (void)removeAllSubviews { for (UIView *subview in self.subviews) [subview removeFromSuperview]; }
чтобы удалить все подвиды синтаксис:
- (void)makeObjectsPerformSelector:(SEL)aSelector;
использование :
[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
этот метод присутствует в NSArray.H файл и использует интерфейс NSArray(NSExtendedArray)
для ios6 с помощью autolayout мне пришлось добавить немного кода, чтобы удалить ограничения тоже.
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 были установлены ограничения, которые очищались.