Ответы:
Редактировать: С благодаря Cocoafan : Эта ситуация запутана тем, что NSView
и по- UIView
разному. Для NSView
(только для разработки на настольном Mac) вы можете просто использовать следующее:
[someNSView setSubviews:[NSArray array]];
Для UIView
(только для iOS) вы можете безопасно использовать, makeObjectsPerformSelector:
потому что subviews
свойство вернет копию массива подпредставлений:
[[someUIView subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
Спасибо Томми за то, что он указал, что, по- makeObjectsPerformSelector:
видимому, изменяет subviews
массив во время его перечисления (что он делает для NSView
, но не для UIView
).
Пожалуйста, смотрите этот вопрос для получения более подробной информации.
Примечание. Использование любого из этих двух методов приведет к удалению всех представлений, содержащихся в вашем главном представлении, и их освобождению , если они не сохраняются в другом месте. Из документации Apple по removeFromSuperview :
Если супервизор получателя не ноль, этот метод освобождает получателя. Если вы планируете повторно использовать представление, обязательно сохраните его перед вызовом этого метода и обязательно отмените его, когда вы закончите с ним или после добавления его в другую иерархию представления.
UIView
возвращает копию на subviews
изменяемый массив, так что этот код просто работает. Совершенно другая история на рабочем столе, где один и тот же код выдаст исключение. См stackoverflow.com/questions/4665179/...
someUIView.Subviews.All( v => { v.RemoveFromSuperview(); return true; } );
. ИМХО чище сказать что ты имеешь ввиду someUIView.Subviews.ToList().ForEach( v => v.RemoveFromSuperview() );
.
Получите все подпредставления от вашего корневого контроллера и отправьте каждому a removeFromSuperview:
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
self.view
как ты.
for (UIView *v in [self.view subviews])
это проще
В Swift вы можете использовать такой функциональный подход :
view.subviews.forEach { $0.removeFromSuperview() }
Для сравнения, императивный подход будет выглядеть так:
for subview in view.subviews {
subview.removeFromSuperview()
}
Эти фрагменты кода работают только в iOS / tvOS, хотя в MacOS все немного иначе.
(subviews as [UIView]).map { $0.removeFromSuperview() }
.map
. это чистый побочный эффект, с которым лучше справляться следующим образом:view.subviews.forEach() { $0.removeFromSuperview() }
Если вы хотите удалить все подпредставления в вашем UIView (здесь yourView
), то напишите этот код при нажатии кнопки:
[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
Это относится только к 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 :
Посылает каждому объекту в массиве сообщение, идентифицированное данным селектором, начиная с первого объекта и продолжая через массив до последнего объекта.
(что было бы неправильным направлением для этой цели)
removeFromSuperview
окончании UIView будет удален из массива, и если нет других живых экземпляров, имеющих сильное отношение к UIView, UIView также будет удален. Это может вызвать исключение из-за границы.
[yourView subviews]
возвращает копию массива, поэтому является безопасным. (ЗАМЕТЬТЕ, что на OSX, что вы говорите, правильно.)
Попробуйте этот способ Swift 2.0
view.subviews.forEach { $0.removeFromSuperview() }
forEach
после вашего решения было добавлено основанное решение, я пропустил это. Извиняюсь.
Используйте следующий код, чтобы удалить все подпредставления.
for (UIView *view in [self.view subviews])
{
[view removeFromSuperview];
}
Для того, чтобы удалить все подпункты синтаксиса:
- (void)makeObjectsPerformSelector:(SEL)aSelector;
Использование :
[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
Этот метод присутствует в файле NSArray.h и использует интерфейс NSArray (NSExtendedArray)
Если вы используете Swift, это так просто, как:
subviews.map { $0.removeFromSuperview }
По своей философии это похоже на makeObjectsPerformSelector
подход, но с большей степенью безопасности.
map
не должно приводить к побочным эффектам. Кроме того , тот же результат может быть достигнут с помощью forEach
.
Для 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 были установлены ограничения, которые очищались.
В monotouch / xamarin.ios это сработало для меня:
SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview);
Чтобы удалить все подпредставления из суперпредставлений:
NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
id object = [oSubView objectAtIndex:iCount];
[object removeFromSuperview];
iCount--;
}
iCount++
и iCount--
, оставляя индекс одинаковым, так что это будет бесконечный цикл, если [oSubView count]>0
. Это определенно глючит и НЕ ПОЛЕЗНЫЙ код.