Відповіді:
Редагувати: Завдяки какаофану : Ця ситуація заплутана тим, що 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() );
.
Отримайте всі підпогляди від вашого кореневого контролера та надсилайте кожному видалення видаленняFromSuperview:
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 те, що ви говорите, правильно.)
Спробуйте таким чином швидко 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
. Це, безумовно, баггі та НЕ БЕЗПЕЧНИЙ код.