Проверить, находится ли подвид в представлении

97

Я делаю приложение , где я добавить подвид к виду , используя addSubview:на условиях IBAction. Точно так же, когда кнопка с этим IBActionснова нажата, должна вызвать removeFromSuperviewэто подпредставление, добавленное к нему IBAction:

Псевдокод

-(IBAction)showPopup:(id)sender 
{
    System_monitorAppDelegate *delegate = (System_monitorAppDelegate *)[[UIApplication sharedApplication] delegate];
    UIView *rootView = delegate.window.rootViewController.view;

    if([self popoverView] is not on rootView) 
    { 
        [rootView addSubview:[self popoverView]];
    } 
    else 
    {
        [[self popoverView] removeFromSuperview];
    }

}
пмерино
источник

Ответы:

271

Вероятно, вы ищете UIView, -(BOOL)isDescendantOfView:(UIView *)view;взятый в справочнике по классу UIView .

Возвращаемое значение ДА, если получатель является непосредственным или удаленным подвидом представления или если представление является самим получателем; в противном случае НЕТ.

В итоге вы получите такой код:

Цель-C

- (IBAction)showPopup:(id)sender {
    if(![self.myView isDescendantOfView:self.view]) { 
        [self.view addSubview:self.myView];
    } else {
        [self.myView removeFromSuperview];
    }
}

Swift 3

@IBAction func showPopup(sender: AnyObject) {
    if !self.myView.isDescendant(of: self.view) {
        self.view.addSubview(self.myView)
    } else {
        self.myView.removeFromSuperview()
    }
}
пальма
источник
2
Не работает, просто добавляет вид. Я отредактирую код, чтобы показать реальный случай
pmerino
@ zad0xsis - я не понимаю настоящего дела. Если вы добавили второе представление с помощью addSubview:метода (что, вероятно, имеет место в первый раз), в следующий раз вы перейдете к части else, потому что второе представление теперь является подпредставлением первого. Разве это не то, что вы пытались сделать? Возможно, вы ищете другой механизм, например, модальное представление контроллера представления?
ну, popoverViewэто подвид rootView (rootViewController). Я хочу проверить, отображается ли он на экране (если у него есть rootView в качестве супервизора), и если да, удалите его или добавьте, если его нет
pmerino
это [self popoverView]возвращает вновь созданный поповер каждый раз? он не может добавить представление «поверх него», если это то же самое представление, добавляя представление, которое уже существует, без операции. если popoverViewметод каждый раз создает новый, то он всегда не будет в иерархии представлений
bshirley
1
Одно важное соображение, которое меня здесь сбило с толку: при удалении и добавлении подпредставлений, которые вы держите с помощью свойств IBOutlet (или ivars), вам необходимо убедиться, что свойства (ivars) сильны или что (до ARC) они сохраняются . По умолчанию, если вы перетаскиваете с нажатой клавишей Ctrl из представления на контроллер для создания выхода, он будет создавать его как слабый, поскольку предполагает, что представление, созданное в пере, будет владеть им, поэтому вам не нужна сильная ссылка. Но если вы затем удалите его программно, он освободит элемент управления и установит для вашей ссылки значение nil (в ARC).
Rhubarb
18

Попробуй это:

-(IBAction)showPopup:(id)sender
{
    if (!myView.superview)
        [self.view addSubview:myView];
    else
        [myView removeFromSuperview];
}
Марк Гранофф
источник
здорово! иногда ему нужен myView.view.superview, но для меня это сработало как по волшебству. Спасибо @MarkGranoff
Лиор Френкель
11
    UIView *subview = ...;
    if([self.view.subviews containsObject:subview]) {
        ...
    }
Майкл Фредерик
источник
Не работает, просто добавляет вид. Я отредактирую код, чтобы показать реальный случай - zad0xsis 1 минуту назад отредактировать
pmerino
12
@pmerino Поздравляю с такой ленивой, что вы также скопировали "zad0xsis 1 минуту назад редактировать" :-)
Thomas Kekeisen
Я думаю, что это дороже, чем другие решения, если честно, потому что он должен проходить через все
подпредставления
4

Эквивалент Swift будет выглядеть примерно так:

if(!myView.isDescendantOfView(self.view)) {
    self.view.addSubview(myView)
} else {
    myView.removeFromSuperview()
}
JaySH
источник
2

Проверьте супервизор подпредставления ...

-(IBAction)showPopup:(id)sender {
    if([[self myView] superview] == self.view) { 
        [[self myView] removeFromSuperview];           
    } else {
        [self.view addSubview:[self myView]];         
    }
}
Джейсон Харвиг
источник
1

Ваше условие if должно выглядеть как

if (!([rootView subviews] containsObject:[self popoverView])) { 
    [rootView addSubview:[self popoverView]];
} else {
    [[self popoverView] removeFromSuperview];

}
Саран
источник
Это небольшая модификация ответа Майкла Фредерика. Отличаются ли результаты от кода Винсента, который использует isDescendantOfView:?
paulmelnikow
Это дает совсем другой результат. Это только проверяет, является ли это детским представлением, а не внуком или правнуком и т. Д.
Сами Самхури
0

Здесь мы использовали два разных взгляда. Родительское представление - это представление, в котором мы ищем представление-потомок и проверяем, добавлено ли оно к родительскому представлению или нет.

if parentView.subviews.contains(descendantView) {
   // descendant view added to the parent view.
}else{
  // descendant view not added to the parent view.
}
Шубхам
источник