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


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()
}

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.
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.