【问题标题】:Check if a subview is in a view检查子视图是否在视图中
【发布时间】:2011-11-17 06:57:08
【问题描述】:

我正在制作一个应用程序,我在 IBAction 上使用 addSubview: 将子视图添加到视图中。同样,当再次触摸带有IBAction 的按钮时,应在添加到IBAction 的子视图上调用removeFromSuperview

伪代码

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

}

【问题讨论】:

    标签: ios cocoa-touch uiview uikit


    【解决方案1】:

    这里我们使用了两种不同的视图。父视图是我们在其中搜索后代视图并检查是否添加到父视图的视图。

    if parentView.subviews.contains(descendantView) {
       // descendant view added to the parent view.
    }else{
      // descendant view not added to the parent view.
    }
    

    【讨论】:

    • 我觉得这里的问题是如果一个view是一个subview的子view,就找不到了。
    【解决方案2】:

    您可能正在寻找在UIView class reference 中拍摄的UIView 的-(BOOL)isDescendantOfView:(UIView *)view;

    返回值 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()
        }
    }
    

    【讨论】:

    • 不起作用,只是在上面添加视图。我将编辑代码以显示真实案例
    • @zad0xsis - 我不明白真实情况。如果您使用addSubview: 方法添加了第二个视图(这可能是第一次的情况),下一次,您将到达 else 部分,因为第二个视图现在 第一的。这不是你想要做的吗?您可能正在寻找另一种机制,例如以模态方式呈现视图控制器?
    • 好吧,popoverView是rootView(rootViewController)的一个子视图。我想检查它是否在屏幕上(如果它有 rootView 作为超级视图),如果是,则删除它,如果不是则添加它
    • [self popoverView] 是否每次都返回一个新创建的弹出框?如果它是相同的视图,它不能在“上面”添加一个视图,添加一个已经存在的视图是无操作的。如果popoverView 方法每次都创建一个新的,那么它永远不会在视图层次结构中
    • 一个重要的考虑因素让我在这里绊倒:当删除然后添加您使用 IBOutlet 属性(或 ivars)持有的子视图时,您需要确保属性(ivars)是 strong ,或者他们保留的那个(ARC 之前)。默认情况下,如果您从视图按住 ctrl 并拖动到控制器以创建插座,它会将其创建为 weak 因为它假定在 nib 中创建的视图将拥有它,因此您不需要强大的参考。但是,如果您随后以编程方式将其删除,它将释放控件并将您的引用设置为 nil(在 ARC 中)。
    【解决方案3】:

    等效的 Swift 如下所示:

    if(!myView.isDescendantOfView(self.view)) {
        self.view.addSubview(myView)
    } else {
        myView.removeFromSuperview()
    }
    

    【讨论】:

      【解决方案4】:

      你的 if 条件应该是这样的

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

      【讨论】:

      • 这是对 Michael Frederick 答案的轻微修改。它是否与使用 isDescendantOfView: 的文森特代码给出不同的结果?
      • 它绝对会产生不同的结果。这仅检查它是否是子视图,而不是孙子或曾孙等。
      【解决方案5】:
          UIView *subview = ...;
          if([self.view.subviews containsObject:subview]) {
              ...
          }
      

      【讨论】:

      • 不起作用,只是在上面添加视图。我将编辑代码以显示真实案例 – zad0xsis 1 分钟前编辑
      • @pmerino 恭喜你这么懒,还复制了“zad0xsis 1 min ago edit”:-)
      • 老实说,我认为这比其他解决方案更昂贵,因为它必须遍历所有子视图
      【解决方案6】:

      检查子视图的父视图...

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

      【讨论】:

        【解决方案7】:

        试试这个:

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

        【讨论】:

        • 太棒了!有时它需要 myView.view.superview,但它对我来说就像魔术一样。谢谢@MarkGranoff
        猜你喜欢
        • 2015-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-08
        • 1970-01-01
        • 1970-01-01
        • 2012-11-22
        • 1970-01-01
        相关资源
        最近更新 更多