하위보기가보기에 있는지 확인


97

내가 사용하여 뷰에 하위 뷰를 추가 응용 프로그램 만들고있어 addSubview:온을 IBAction. 같은 방식으로 버튼 IBAction이 다시 터치되면 removeFromSuperview해당 하위 뷰를 호출해야 합니다 IBAction.

PSEUDO 코드

-(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를 찾고있을 것입니다 .

반환 값 수신자가 뷰의 즉각적이거나 먼 하위 뷰이거나 뷰가 수신자 자체 인 경우 YES; 그렇지 않으면 아니오.

다음과 같은 코드가 생성됩니다.

목표 -C

- (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 2011-09-14

@ zad0xsis-실제 사례를 이해하지 못합니다. 사용 두 번째보기를 추가 한 경우 addSubview:, 다음에 (아마도 경우는 이번이 처음이다) 방법을 두 번째보기는 이제 때문에, 당신은 다른 부분에 도달 할 것 입니다 최초의 서브 뷰. 당신이하려고했던 것이 아닌가요? 뷰 컨트롤러를 모달로 표현하는 것과 같은 또 다른 메카니즘을 찾고 있습니까?

음, popoverViewrootView (rootViewController)의 하위보기입니다. 그렇지 않은 경우, 나는 (이 수퍼로 rootView있는 경우)가 화면에 있는지 확인하고 만약 그렇다면하여 제거하거나 다른 추가 할
pmerino

되어 [self popoverView]새로마다 팝 오버 생성 갈까요? 동일한보기 인 경우 "위에"보기를 추가 할 수 없으며 이미 작동하지 않는보기를 추가합니다. popoverView메소드가 매번 새로운 것을 생성 한다면, 항상 뷰 계층 구조에 있지 않을 것입니다
bshirley

1
여기에서 저를 괴롭힌 한 가지 중요한 고려 사항 : IBOutlet 속성 (또는 ivar)으로 유지하고있는 하위 뷰를 제거하고 추가 할 때 속성 (ivars)이 강력한 지 또는 (ARC 이전) 유지 되는지 확인해야합니다. . 기본적으로 뷰에서 컨트롤러로 ctrl-drag하여 출력을 생성 하면 펜촉에서 생성 된 뷰가이를 소유하므로 강력한 참조가 필요하지 않다고 가정하므로 약한 것으로 생성됩니다. 그러나 프로그래밍 방식으로 제거하면 컨트롤의 할당이 해제되고 참조가 ARC에서 nil로 설정됩니다.
Rhubarb

18

이 시도:

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

대박! 때로는 myView.view.superview가 필요하지만 마술처럼 작동했습니다. 감사 @MarkGranoff
리 오르 Frenkel

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

작동하지 않고보기 만 추가하면됩니다. 실제 사례를 보여주기 위해 코드를 편집하겠습니다 – zad0xsis 1 분 전 edit
pmerino 2011-09-14

12
@pmerino "zad0xsis 1 min ago edit"도 복사 한 게으르다는 것을 축하합니다. :-)
Thomas

솔직히 말하면 모든 하위보기를 반복해야하기 때문에 다른 솔루션보다 비용이 더 많이 든다고 생각합니다
SimplyKiwi

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];

}

이것은 Michael Frederick의 대답을 약간 수정 한 것입니다. 사용하는 Vincent의 코드와 다른 결과를 제공합니까 isDescendantOfView:?
paulmelnikow

그것은 절대적으로 다른 결과를 낳습니다. 이 단지 검사가 아이 뷰,하지 등 손자 나 증손자 인 경우
사미 Samhuri

0

여기에서는 두 가지 다른보기를 사용했습니다. 상위보기는 하위보기를 검색하고 상위보기에 추가되었는지 여부를 확인하는보기입니다.

if parentView.subviews.contains(descendantView) {
   // descendant view added to the parent view.
}else{
  // descendant view not added to the parent view.
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.