tile arrangement of images in UIScrollView or UITableView - iphone

I have an application like photo share in which i need to display images in tile view like GOOGLE IMAGE SEARCH.
Photos should be arranged in tile manner depending upon the size of an image
For better explanation i have attached example of google image search..
And
If you have any idea about this, Please share your knowledge.

Here is the source code of an iOS library similar to what you are asking for. You can get the basic idea about how this can be done from the Source Code.

Use Scrollview.
Set two parameters, called xOffset and yOffset and UIScrollview *scrollView
int yOffset = 0;
int xOffset = 0;
for (int height=0; height < [y count]; height++)
{
for (int width=0; width < [x count]; width++)
{
NSString *imageName =
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(xOffset, yOffset, imageView.frame.size.width, imageView.frame.size.height);
[scrollView addSubview:imageView];
xOffset += imageView.frame.size.width;
}
yOffset += imageView.frame.size.height;
}
[scrollView setContentSize:CGSizeMake(xOffset,yOffset)];
Hope this helps...

Related

How to properly remove an UIImageView from UIScrollView?

I'm developing an app that i need to load many images in a view using Xcode 4.5.2
So, At the top, I have a UIView, inside of this UIView, i have UIScrollView to display many images,i'm using this UIScrollView in pagingEnabled mode. As i have many images to load, i know that it cannot be possible to load at once. So, i decided to add or remove if need be.
When the app starts, i've loaded three images in UIScrollView, when user passes to image 2,
i want to remove image 0 from UIScrollView.When i try to remove the image 0,i got totally white screen.The funny part is that if i dont try to remove image 0,when user passes to image 3, i want to load a new image(image 4) to UIScrollView, and remove image 1.So far, I'm able to do this. Basically,my apps works just fine, but when i want to remove the first(at index 0)image,I got totally white screen on the screen.
Do you have any idea why i'm getting this behaviour ? I got neither warning,nor error. How is it possible that i'm able to remove all the other images but not the image 0 ?
Thank you.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
static NSInteger currentPage = 0 ;
CGFloat pageWidth = self.scrollView.frame.size.width ;
float fractionalPage = self.scrollView.contentOffset.x / pageWidth ;
NSLog(#"%f",fractionalPage);
if(fractionalPage == currentPage+1)
{
NSLog(#"Swipe Left");
currentPage++;
NSLog(#"Current page :%d",currentPage);
[self setLayoutImages:kLeft] ;
}
else if(fractionalPage+1 ==currentPage)
{
NSLog(#"Swipe Right");
currentPage--;
NSLog(#"Current page :%d",currentPage);
[self setLayoutImages:kRight];
}
}
-(void)setLayoutImages:(Direction )direction
{
int currentPage = self.scrollView.contentOffset.x / scrollViewWidth ;
if(direction == kLeft)
{
self.scrollView.contentSize = CGSizeMake(((currentPage+2) * scrollViewWidth), 350.0f);
if(![self.scrollView viewWithTag:currentPage+1])
{
NSString *imageName = #"iPhone.png" ;
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc]initWithImage:image ] ;
imageView.tag = currentPage+1 ;
CGRect frame = imageView.frame ;
frame.size.height = imageHeight;
frame.size.width = scrollViewWidth ;
frame.origin.x = (currentPage+1) * scrollViewWidth ;
frame.origin.y = 0 ;
imageView.frame = frame ;
if (currentPage>2) { //To be able to remove the first image,i need to add equal here,but i got white screen.
[[self.scrollView viewWithTag:(currentPage -2)]removeFromSuperview ] ; }
[self.scrollView addSubview:imageView ] ;
}
}
else if(direction == kRight)
{
if(![self.scrollView viewWithTag:currentPage-1] && currentPage >0)
{
NSString *imageName = #"gs.jpeg";
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc]initWithImage:image ];
imageView.tag = currentPage-1 ;
CGRect frame = imageView.frame ;
frame.size.height = imageHeight ;
frame.size.width = scrollViewWidth ;
frame.origin.x = (currentPage-1)*scrollViewWidth ;
frame.origin.y = 0 ;
imageView.frame = frame ;
[[self.scrollView viewWithTag:currentPage+2]removeFromSuperview ] ;
[self.scrollView addSubview:imageView ];
}
}
}
Try making your views start with a tag of 1 not 0, as 0 is the default for an untagged view if i remember correctly, and this might be causing the problem
You can Give each one of three deferant Tag and reuse it by [[view viewWithtag:tag] removeFromSuperView] or you can try ready project called iCarousel made by nicklockwood it is an wonderful project.
it can be horizontal and vertical

Horizontal UIScrollView and hundreds of thumbnail images in iOS?

I need to create a horizontal UIScrollView which to hold hundreds of thumbnail images, just like a slide of thumbnails.
For example, there will be 10 thumbnails showing in a single screen, each of them are horizontally adjacent to each other.
My problem is that I don't know how to make a horizontal UIScrollView to hold the multiple thumbnails which showing at the same time ?
A sample photo is as below. See the bottom part of the screen.
Thanks.
You can add all the thumbnails programatically to your scrollview and use the setContentSize method of UIScrollView. you have to pass 2 values in contentOffset. 1 for width and 1 for height. Please follow link to explore more on this. If you need further help please leave a comment.
Hope it helps.
Please consider Following example.
- (void)setupHorizontalScrollView
{
scrollView.delegate = self;
[self.scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = NO;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
NSUInteger nimages = 0;
NSInteger tot=0;
CGFloat cx = 0;
for (; ; nimages++) {
NSString *imageName = [NSString stringWithFormat:#"image%d.jpg", (nimages + 1)];
UIImage *image = [UIImage imageNamed:imageName];
if (tot==15) {
break;
}
if (4==nimages) {
nimages=0;
}
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect rect = imageView.frame;
rect.size.height = 40;
rect.size.width = 40;
rect.origin.x = cx;
rect.origin.y = 0;
imageView.frame = rect;
[scrollView addSubview:imageView];
[imageView release];
cx += imageView.frame.size.width+5;
tot++;
}
self.pageControl.numberOfPages = nimages;
[scrollView setContentSize:CGSizeMake(cx, [scrollView bounds].size.height)];
}
I suggest you to look at nimbus
Check out bjhomer's HSImageSidebarView project. It lets you load a scrollview horizontally or vertically and load in the images. Super easy to implement.
First of all, at storyboard drag and drop the scroll view and make the outlet of scrollview named scrollView. Two array one is mutable and one is immutable.
#property(nonatomic,strong)IBOutlet UIScrollView *scrollView;
#property(nonatomic,strong)NSMutableArray *images;
#property(nonatomic,strong)NSArray *imagesName;
The immutable array only store the images which we want to show on the scroll view.Make sure UIscrollview delegate is defined.
In viewcontoller.m file in didload function do following code:
imagesName = [[NSArray alloc]initWithObjects:#"centipede.jpg",#"ladybug.jpg",#"potatoBug.jpg",#"wolfSpider.jpg", #"ladybug.jpg",#"potatoBug.jpg",#"centipede.jpg",#"wolfSpider.jpg",nil];
// mutable array used to show the images on scrollview dynamic becaus after one
// image when scroll other will come
images = [[NSMutableArray alloc]init];
scrollView.delegate = self;
scrollView.scrollEnabled = YES;
int scrollWidth = 120;
scrollView.contentSize = CGSizeMake(scrollWidth,80);
int xOffset = 0;
//the loop go till all images will load
for(int index=0; index < [imagesName count]; index++)
{
UIImageView *img = [[UIImageView alloc] init];
// make the imageview object because in scrollview we need image
img.frame = CGRectMake(5+xOffset, 0, 160, 110);
// the offset represent the values, used so that topleft for each image will
// change with(5+xOffset, 0)and the bottomright(160, 110)
NSLog(#"image: %#",[imagesName objectAtIndex:index]);
img.image = [UIImage imageNamed:[imagesName objectAtIndex:index]];
// The image will put on the img object
[images insertObject:img atIndex:index];
// Put the img object at the images array which is mutable array
scrollView.contentSize = CGSizeMake(scrollWidth+xOffset,110);
//scroll view size show after 125 width the scroll view enabled
[scrollView addSubview:[images objectAtIndex:index]];
// set images on scroll view
xOffset += 170;
}
You can calculate content size width of the scrollview as width = number of images * size of each image. Then set contentSize of the scrollview to this width and the height that you want (scrollView.contentSize = CGSizeMake(width, height))

Reuse cells of a scroll view

I am using a scrollview to display various items in a horizontal fashion.
How can I "reuse the cells" to conserve memory:
Edit: Apologies for not being clear. I plan to place a few labels and and another ImageView inside each ImageView so I am keen to reuse this each time instead of instantiating new items each time. e.g. change the image's and update the labels instead of re-create it.
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
// load all the images from our bundle and add them to the scroll view
// NSUInteger i;
for (int i = 0; i <= 150; i++)
{
NSString *imageName = #"tempImage.jpg";
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = imageView.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
imageView.frame = rect;
imageView.tag = i; // tag our images for later use when we place them in serial fashion
[self.bestSellScrollView addSubview:imageView];
[imageView release];
}
[self layoutScrollImages]; // now place the photos in serial layout within the scrollview
}
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [self.bestSellScrollView subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
// set the content size so it can be scrollable
[self.bestSellScrollView setContentSize:CGSizeMake((150 * kScrollObjWidth),
[self.bestSellScrollView bounds].size.height)];
}
If you mean like what happens with respect UITableViewCell in a UITableView, then its not possible in the horizontal scroller.
The reusable cells property for a table view is provided by the system and it not applicable for horizontal scroller.
You have to write on your own logic in order to achieve it, perhaps! Its a good question though. Will be tuned to other answers just in case if anything is possible.
If you mean you'd like to keep the UIImageView(s) where they are in the scrollview, but you'd like to change the UIImage that they show, try something like this:
-(void)changeImageViewWithTag:(NSInteger)aTag toImage:(UIImage *)anImage
{
UIImageView *theView = [self.bestSellScrollView viewWithTag:aTag];
if (theView)
{
[theView setImage:anImage];
}
}
I am assuming that you intend to reuse the UIImageView cell instances in the UIScrollView.
I hope that Daniel Tull's implementation may be helpful--
https://github.com/danielctull/DTGridView
You may like to see an Apple sample code on UIScrollView as well(I don't have the link, but u can easily find it on the web)
Thanks!
Ishank

How to get the UIScrollView to be shown in between adding imageView to it?

I have a UIScrollView and I add 9 imageview to it using the following code.
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"some url"]];
frame = [imageView frame];
frame.origin.x = x;
frame.origin.y = y;
[imageView setFrame:frame];
imageView.userInteractionEnabled = YES;
imageView.multipleTouchEnabled = YES;
[myScrollView addSubview:imageView];
}
}
I thought the UIScrollView will be shown and then we will see each image being loaded in tiles. But what happens is only after loading all the images only the UIScrollView comes into appearance with all the images.
How can i make UIScrollView come first, then show each of the images being loaded?
You are blocking the runloop until this whole block of code is executed. Therefore your app doesn't get a chance to update its drawing. You need to do the drawing (more specifically, the downloading of your images) asynchronously. Once an image is downloaded, you can then add it to your UIScrollView. Note that you want to do this drawing on the main thread using a method like performSelectorOnMainThread....

iPhone UIScrollView - how to get an image title

I'm ATTEMPTING to learn UIScrollview using Apple's Docs and their sample code http://developer.apple.com/iphone/library/samplecode/Scrolling/index.html but something SO simple is escaping me.
How do you tell what image is currently on the screen, so that if I selected one of the images in the horizontal scrolling view, how would I get the filename of the image, or even a pointer in the array, to then do something further with the image?
I thought with Page Control enable I might be able to find a page # and map it to the image. I thought about counting deceleration to count pages, but a flick no full enough will increment it and give a false number.
The last thing I could think of is to get contentOffSet and divide by image size which will give a 1, 2, 3 and I could point to the array (too tired to try tonight... thought I might ask before I waste a lot more time ;-) ).
Any other ideas? I thought there would be a method somewhere that they use in the photo album app.
PS: Here's the code:
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [scrollView1 subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
// set the content size so it can be scrollable
[scrollView1 setContentSize:CGSizeMake((kNumImages * kScrollObjWidth), [scrollView1 bounds].size.height)];
}
- (void)viewDidLoad
{
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
// 1. setup the scrollview for multiple images and add it to the view controller
//
// note: the following can be done in Interface Builder, but we show this in code for clarity
[scrollView1 setBackgroundColor:[UIColor blackColor]];
[scrollView1 setCanCancelContentTouches:NO];
scrollView1.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView1.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView1.scrollEnabled = YES;
// pagingEnabled property default is NO, if set the scroller will stop or snap at each photo
// if you want free-flowing scroll, don't set this property.
scrollView1.pagingEnabled = YES;
// load all the images from our bundle and add them to the scroll view
//NSUInteger i;
for (i = 1; i <= kNumImages; i++)
{
NSString *imageName = [NSString stringWithFormat:#"Card %d.png", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = imageView.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
imageView.frame = rect;
imageView.tag = i; // tag our images for later use when we place them in serial fashion
[scrollView1 addSubview:imageView];
[imageView release];
}
[self layoutScrollImages]; // now place the photos in serial layout within the scrollview
This was easy after a good sleep!
CGPoint p = scrollView1.contentOffset;
NSLog(#"x = %f, y = %f", p.x, p.y);
Now just divide by 320 (if horizontal and full screen image) and add 1 (because it starts at 0).
Hope this helps someone else!
Paul