サブビューがビュー内にあるかどうかを確認する


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を探しています

戻り値 YESは、レシーバがビューの即時または遠方のサブビューである場合、またはビューがレシーバ自体である場合。それ以外の場合はNO。

あなたは次のようなコードになるでしょう:

Objective-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

@ zad0xsis-実際のケースが理解できません。あなたが使用して2番目のビューを追加した場合はaddSubview:、次回(おそらくケースは初めてです)メソッドを2番目のビューは、今ので、あなたは他の部分に到達う最初のサブビュー。あなたがやろうとしていたことではありませんか?あなたはたぶんビューコントローラをモーダルに提示するような別のメカニズムを探していますか?

まあ、popoverViewrootView(rootViewController)のサブビューです。画面上にあるかどうか(スーパービューとしてrootViewがある場合)を確認し、そうでない場合は削除するか、そうでない場合は追加します
pmerino

され[self popoverView]、新しく作成されたポップオーバーを毎回返しますか?同じビューの場合、「その上に」ビューを追加することはできません。すでに存在するビューを追加しても何もできません。popoverViewメソッドが毎回新しいメソッドを作成している場合、そのメソッドは常にビュー階層には含まれません
bshirley

1
ここで私をつまずかせた重要な考慮事項の1つ:IBOutletプロパティ(またはivars)で保持しているサブビューを削除して追加する場合、プロパティ(ivars)が強いか、または(ARC以前)保持されていることを確認する必要があります。 。デフォルトでは、ビューからコントローラにctrlキーを押しながらドラッグしてアウトレットを作成すると、ニブで作成されたビューがそれを所有すると想定しているため、強い参照を必要としないため、弱いものとして作成されます。ただし、プログラムで削除すると、コントロールの割り当てが解除され、参照がnil(ARC)に設定されます。
ルバーブ

18

これを試して:

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

驚くばかり!myView.view.superviewが必要になることもありますが、私にとっては魔法のように機能しました。ありがとう@MarkGranoff
Lior Frenkel

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

機能せず、ビューを追加するだけです。実際のケースを表示するようにコードを編集します– zad0xsis 1分前の編集
pmerino

12
@pmerino「zad0xsis 1分前に編集」もコピーしたので、怠惰でおめでとうございます:-)
Thomas Kekeisen

正直に言うと、すべてのサブビューを反復処理する必要があるため、これは他のソリューションよりも費用がかかると思います
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];

}

これは、マイケルフレデリックの回答を少し変更したものです。使用するVincentのコードとは異なる結果が得られますisDescendantOfView:か?
paulmelnikow 2011

それは絶対に異なる結果をもたらします。これだけをチェックし、それはなど、子ビューではなく、孫や偉大な孫、ある場合
サミSamhuri

0

ここでは、2つの異なるビューを使用しました。親ビューは、子孫ビューを検索し、親ビューに追加されているかどうかを確認するビューです。

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.