【问题标题】:Is UIView being displayed?是否正在显示 UIView?
【发布时间】:2013-03-06 15:27:32
【问题描述】:

我有一个 UIViewController。根 UIView 包含一个自定义 UIScrollView,我用于在网格中显示缩略图(ThumbnailGrid 类)。该网格可以包含许多显示图像的 UIView(GridTile 类)。因为有很多网格图块,用户可以向下滚动 ThumbnailGrid。我只想加载用户实际可以看到的网格图块的图像,我不想为屏幕边缘之外的网格图块加载图像。

我如何确定这些 GridTile UIView 之一是否正在屏幕上显示?

我尝试了以下方法,但它似乎总是返回 false。

- (bool) isViewDisplayed:(UIView*)view
{
        CGRect viewFrame = view.frame;
        CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
        if (CGRectIntersectsRect(viewFrame, appFrame)) return true;
        return false;
}

我错过了什么吗?

提前感谢您的帮助!

编辑

解决方案

原来坐标系是错误的,所以我遇到了一些奇怪的情况,方法应该返回 true,但它返回 false,反之亦然。

- (bool) isViewDisplated:(UIView*)view
{
    CGRect viewFrame = [parentOfView convertRect:view.frame toView:nil]; 
    CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
    if (CGRectIntersectsRect(viewFrame, appFrame)) return true;
    return false;
}

【问题讨论】:

  • ThumbnailGrid 类是您创建的自定义类还是您正在使用的框架?
  • 这是我自己制作的 UIScrollView 的子类。它没什么特别的,只是包含了以某种方式操作其子视图的方法。

标签: ios objective-c uiview


【解决方案1】:

还需要将rect转换为正确的坐标系:

- (bool)isViewDisplayed:(UIView*)view
{
    if (view.window) {
        CGRect viewFrame = [view.window convertRect:view.frame fromView:view.superview];
        CGRect screenFrame = view.window.bounds;
        return CGRectIntersectsRect(viewFrame, screenFrame);
    }
    return false;
}

【讨论】:

  • 非常感谢!这个答案帮助我找到了解决方案(编辑了我的问题,添加了我使用的解决方案)。基本上我没有将我的矩形转换为正确的坐标系(我很傻)。
【解决方案2】:

我知道它不能直接回答您的问题,但仍然:您为什么不使用UICollectionView?它能够为您处理大部分重型部件。您不必关心它们在屏幕之外的那些。你只关心行为(委托)和内容(数据源)。

【讨论】:

  • 我尝试过使用 UICollectionView,但它并没有按照我想要的方式做事。很难解释我的确切原因,但基本上 UICollectionView 对这个项目来说是不可能的。
  • @DavidOmid 很公平。这只是一个建议。
【解决方案3】:

老实说,我认为你的做法是错误的。有大量现有的框架旨在做到这一点。我不知道我是否会花时间手动推出我自己的解决方案并处理所有的内存和视图管理。看看这个帖子:Grid of images in iOS

【讨论】:

    【解决方案4】:

    你可以这样比较:

      NSMutableArray *outArray = [NSMutableArray array];
      NSMutableArray *inArray = [NSMutableArray array];
    
    
    for (UIView *vw in rootView.subViews){
      if(vw.frame.origin.x <0 || vw.framew.origin.x >rootView.frame.size.width){
         [outArray addObject:vw];
      }else if(vw.frame.origin.y <0 || vw.framew.origin.y >rootView.frame.size.height){
         [outArray addObject:vw];
      }else{
         [inArray addObject:vw];
      }
    }
    

    所以最后你的 outArray 将包含所有部分/完全超出超级视图的视图,而 inArray 将包含所有完全在超级视图内的视图。 如果您想使用方法(例如 -(bool)isViewDisplayed:(UIView*)vw )检查单个视图,则 for 循环中的相同代码就足够了,唯一的事情是您必须返回 true/false 而不是添加到数组中

    PS:如果您只想完全从超级视图中获取视图,那么不要将零检查与-vw.frame.size.width-vw.frame.size.height 进行比较。

    【讨论】:

      【解决方案5】:

      使用标签非常容易管理。 像这样的

          UIView *view1 = [UIView]alloc]init];
      view1.tag = 1;
      [mainView addSubview:view1
      

      ];

      检查

      UIView *temp = [mainView.view viewWithTag:1];
      if(temp!=nil)return YES;
      else NO;
      

      看看有没有帮助

      【讨论】:

      • 如果 mainView 是 UIView。 mainView.view 不对。即使超出父视图的框架,视图也可能是子视图。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多