Перевірте, чи є підзор у перегляді


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 .

Повернене значення ТАК, якщо одержувач - це негайне або віддалене подання перегляду або якщо подання є самим приймачем; інакше НІ.

Ви отримаєте такий код:

Ціль-С

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

Стрімкий 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:методу (що, мабуть, трапляється в перший раз), наступного разу ви дістанетесь до іншої частини, оскільки другий вид тепер є підпереглядом першого. Це не те, що ви намагалися зробити? Ви, можливо, шукаєте іншого механізму, як модальне представлення контролера перегляду?

ну, popoverViewце підвид rootView (rootViewController). Я хочу перевірити, чи він на екрані (якщо він має rootView як нагляд), і якщо так, видаліть його чи ще додайте, якщо його немає
pmerino

це [self popoverView]повертає новостворений поповеров кожен раз? він не може додати подання "над ним", якщо це той самий вигляд, додавши подання, яке вже є, немає. якщо popoverViewметод створює новий щоразу, то він завжди не буде в ієрархії перегляду
bshirley

1
Одне важливе міркування, яке мене тут спонукало: при видаленні, а потім доданні підпроектів, які ви тримаєте за допомогою властивостей IBOutlet (або ivars), потрібно переконатися, що властивості (ivars) сильні , або що вони зберігаються (до ARC) . За замовчуванням, якщо ви натискаєте ctrl-перетягування з подання на контролер, щоб створити розетку, він створить його як слабкий, оскільки він передбачає, що представлення, створене в перо, буде ним володіти, тому вам не потрібні сильні посилання. Але якщо ви потім видалите його програмним способом, він вимкне елемент керування та встановить ваше посилання на нуль (у ARC).
Ревінь

18

Спробуйте це:

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

приголомшливий! іноді йому потрібен myView.view.superview, але він працював як магія для мене. Дякую @MarkGranoff
Lior

11
    UIView *subview = ...;
    if([self.view.subviews containsObject:subview]) {
        ...
    }

Не працює, просто додає погляд над ним. Я відредагую код, щоб показати справжній випадок - zad0xsis 1 хв тому редагувати
pmerino

12
@pmerino Вітаю за те, що ти лінивий, що ти також скопіював "zad0xsis 1 хв. тому редагувати" :-)
Thomas Kekeisen

Я думаю, що це дорожче, ніж інші рішення, якщо чесно, тому що він повинен повторити всі
підзагляди

4

Свіфт-еквівалент виглядатиме приблизно так:

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 (!([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.