3

I have a UIViewController. The root UIView contains a custom UIScrollView I'm using for displaying thumbnail images in a grid (ThumbnailGrid class). This grid can contain a lot of UIViews which display images (GridTile class). Because there are so many grid tiles, the user can scroll down the ThumbnailGrid. I want to only load images for grid tiles which the user can actually see, I don't want to load ones for grid tiles which are off the edges of the screen.

How do I determine whether or not one of these GridTile UIViews is being displayed on the screen or not?

I've tried the following but it always seems to return false.

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

Am I missing something?

Thanks in advance for any help!

EDIT

THE SOLUTION

Turns out the coordinate systems were wrong, so I was getting some strange occurrences where the method should have returned true and instead it returned false, and vice versa.

- (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;
}
David Omid
  • 647
  • 6
  • 19
  • is the ThumbnailGrid class a custom class you created or a framework that you are using? – JiuJitsuCoder Mar 06 '13 at 15:37
  • It's a subclass of UIScrollView which I made myself. It's nothing special, just contains methods for manipulating its subviews in a certain way. – David Omid Mar 06 '13 at 15:39

5 Answers5

7

You also need to convert rect to the correct coordinate system:

- (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;
}
Mark Kryzhanouski
  • 7,251
  • 2
  • 22
  • 22
  • Thanks very much! This answer helped me get a solution (edited my question, added the solution I used). Essentially I wasn't converting my rect to the correct coordinate system (silly me). – David Omid Mar 06 '13 at 16:13
0

I know it doesn't directly answer your question, but still: why don't you use a UICollectionView? It's able to handle most of the heavy parts for you. You don't have to care about the ones they are outside of the screen. You just to care about the behavior (delegation) and the content (data source).

Rui Peres
  • 25,741
  • 9
  • 87
  • 137
  • I've tried using UICollectionView but it doesn't do things the way I want them to. Hard to explain my exact reasons but basically UICollectionView is out of the question for this project. – David Omid Mar 06 '13 at 15:44
  • @DavidOmid fair enough. It was just a recommendation. – Rui Peres Mar 06 '13 at 15:46
0

Honestly, I think you are going about this the wrong way. There are a ton of existing frameworks designed to do exactly this. I don't know if I would spend the time to hand roll my own solution and handle all of the memory and view management. Check out this post: Grid of images in iOS

Community
  • 1
  • 1
JiuJitsuCoder
  • 1,866
  • 14
  • 13
0

You could do a compare like this:

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

So in the end your outArray will contain all the views which are partially/fully out of super view and inArray will have all those views which is completely inside the super view. If you want to check for a single view using a method (say -(bool)isViewDisplayed:(UIView*)vw ), the same code inside the for loop would suffice, only thing is you would have to return true/false instead of adding to an array

PS: If you want to get only views completely out of your super view then instead of comparing against zero check against -vw.frame.size.width & -vw.frame.size.height.

Rakesh
  • 3,370
  • 2
  • 23
  • 41
-4

Make use of tags pretty easy to manage. something like this

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

];

and to check

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

see if this helps

Prajwal Udupa
  • 860
  • 5
  • 28
  • if mainView is a UIView. mainView.view is not right. And its possible that the view is a subview even if out of frame of parent view. – Rakesh Mar 06 '13 at 15:40