Когда мое приложение вернется к контроллеру корневого представления, в методе viewDidAppear:
мне нужно удалить все подпрограммы.
Как я могу это сделать?
Когда мое приложение вернется к контроллеру корневого представления, в методе viewDidAppear:
мне нужно удалить все подпрограммы.
Как я могу это сделать?
Изменить: Благодаря 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:
Если супервизор приемников не равен нулю, этот метод освобождает приемник. Если вы планируете повторно использовать представление, обязательно сохраните его перед вызовом этого метода и обязательно отпустите его по мере необходимости, когда вы закончите с ним, или после добавления его в другую иерархию представлений.
Получите все подпрограммы из вашего корневого контроллера и отправьте каждый файл removeFromSuperview:
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
В Swift вы можете использовать такой функциональный подход:
view.subviews.forEach { $0.removeFromSuperview() }
Для сравнения, императивный подход будет выглядеть так:
for subview in view.subviews {
subview.removeFromSuperview()
}
Эти фрагменты кода работают только в iOS/tvOS, хотя в MacOS все немного иначе.
Если вы хотите удалить все подпрограммы на вашем 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
сообщение removeFromSuperview
будет отправлено всем объектам массива. (Очевидно, что удаление последнего элемента не приведет к сбою)
Поэтому код
[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
НЕ следует использовать.
Цитата из документации Apple о makeObjectsPerformSelector:
Посылает каждому объекту в массиве сообщение, идентифицированное данным селектором, начиная с первого объекта и продолжая через массив до последнего объекта.
(что было бы неправильным направлением для этой цели)
Попробуйте этот способ swift 2.0
view.subviews.forEach { $0.removeFromSuperview() }
Используйте следующий код, чтобы удалить все подзаголовки.
for (UIView *view in [self.view subviews])
{
[view removeFromSuperview];
}
Если вы используете Swift, это просто:
subviews.map { $0.removeFromSuperview }
Это похоже на философию подходом makeObjectsPerformSelector
, однако с немного большей безопасностью типа.
Использование расширения Swift UIView
:
extension UIView {
func removeAllSubviews() {
for subview in subviews {
subview.removeFromSuperview()
}
}
}
В 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)
view.subviews.forEach { $0.removeFromSuperview() }
Для 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 были установлены ограничения, которые очищались.
В 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--;
}