I have an array with images presented in a scrollView. It works perfectly on the simulator however when i run it on the actual device (1st gen iPad) it crashes. At first i lowered the quality of the images to the lowest possible (<120kb each) but that didn't solved my problem. Then i reduced the number of images from 13 to 6 and it works. Is there any work you can think of?
Below is the code i use:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
images = [NSArray arrayWithObjects:[UIImage imageNamed:#"back1.jpg"], [UIImage imageNamed:#"back2.jpg"], [UIImage imageNamed:#"back3.jpg"], [UIImage imageNamed:#"back4.jpg"], [UIImage imageNamed:#"back5.jpg"], [UIImage imageNamed:#"back6.jpg"], [UIImage imageNamed:#"back7.jpg"], [UIImage imageNamed:#"back8.jpg"],[UIImage imageNamed:#"back9.jpg"],[UIImage imageNamed:#"back10.jpg"],[UIImage imageNamed:#"back11.jpg"],[UIImage imageNamed:#"back12.jpg"],[UIImage imageNamed:#"back13.jpg"], nil];
pageControl.numberOfPages=images.count;
for (int i = 0; i < images.count; i++) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
subview = [[UIImageView alloc] initWithFrame:frame];
subview.contentMode = UIViewContentModeScaleAspectFit;
subview.image = [images objectAtIndex:i]; //problima sthn eikona
[self.scrollView addSubview:subview];
}
pageControlBeingUsed = NO;
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * images.count, self.scrollView.frame.size.height);}
Related
Right guys, I have scroll view in my SKScene running from a SKAction with the following code -
for (int i=0; i<[listOfImages count]; i++) {
NSDictionary *myDic = [listOfImages objectAtIndex:i];
NSString *urlImage = [myDic objectForKey:#"product_image"];
NSURL *imageURL = [NSURL URLWithString:urlImage];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *cacheImage = [UIImage imageWithData:imageData];
UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(SCREEN_WIDTH/4+leftMargin, 0, cacheImage.size.width/2, cacheImage.size.height/2)];
[image setImage:cacheImage];
image.tag = tag;
image.contentMode = UIViewContentModeScaleAspectFit;
[scrollView addSubview:image];
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
recognizer.numberOfTapsRequired = 1;
recognizer.numberOfTouchesRequired = 1;
recognizer.delegate = self;
[image addGestureRecognizer:recognizer];
[image setUserInteractionEnabled:YES];
leftMargin += SCREEN_WIDTH;
tagValue += 1;
tag += 1;
}
I need to understand how to load the images in the background as there are almost 140 images to load and its taking 5 minutes to load everything and show. Please help me out !!
You could have a queue where one load ending triggers another, as opposed to triggering all the loads at once.
I did a google search and got this if you need help with applying the concept :
http://khanlou.com/2012/08/asynchronous-downloaded-images-with-caching/
What I have
For my game I'm creating several animations using view.animationImages = imagesArray; [view startAnimating];
In my animation helper class I use this
- (UIImage *)loadRetinaImageIfAvailable:(NSString *)path
{
NSString *retinaPath = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:[NSString stringWithFormat:#"%##2x.%#", [[path lastPathComponent] stringByDeletingPathExtension], [path pathExtension]]];
if ([UIScreen mainScreen].scale == 2.0 && [[NSFileManager defaultManager] fileExistsAtPath:retinaPath] == YES)
return [[UIImage alloc] initWithCGImage:[[UIImage imageWithData:[NSData dataWithContentsOfFile:retinaPath]] CGImage] scale:2.0 orientation:UIImageOrientationUp];
else
return [UIImage imageWithContentsOfFile:path];
}
- (NSMutableArray *)generateCachedImageArrayWithFilename:(NSString *)filename extension:(NSString *)extension andImageCount:(int)count
{
_imagesArray = [[NSMutableArray alloc] init];
_fileExtension = extension;
_imageName = filename;
_imageCount = count;
for (int i = 0; i < count; i++)
{
NSString *tempImageNames = [NSString stringWithFormat:#"%#%i", filename, i];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:tempImageNames ofType:extension];
UIImage *frameImage = [self loadRetinaImageIfAvailable:imagePath];
UIGraphicsBeginImageContext(frameImage.size);
CGRect rect = CGRectMake(0, 0, frameImage.size.width, frameImage.size.height);
[frameImage drawInRect:rect];
UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[_imagesArray addObject:renderedImage];
if (_isDoublingFrames)
{
[_imagesArray addObject:renderedImage];
}
else if (_isTriplingFrames)
{
[_imagesArray addObject:renderedImage];
[_imagesArray addObject:renderedImage];
}
NSLog(#"filename = %#", filename);
}
return _imagesArray;
}
Problem and facts
Without caching images I got retina versions of images byt my animations are not fluent
If I cache images this way, animations are ok, but uses non-retina versions of images
Please is there some other way to cache and get retina versions?
Are these images located in your application bundle? If so this logic is all unnecessary because the imageWithContentsOfFile: method will already detect and load the #2x image on a retina device.
Also, you'd be better off using the [UIImage imageNamed:] method instead because this automatically caches the image for re-use, and decompresses it immediately, avoiding the need for manually caching the images, or for that trickery with drawing it into an offscreen CGContext.
I am trying to make a slideshow in an imageview that uses also fade-in fade-out effects.
so far ive done this:
- (void)viewDidLoad
{
[super viewDidLoad];
animationView = [[UIImageView alloc] initWithFrame:self.view.frame];
animationView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"photo1.jpg"],
[UIImage imageNamed:#"photo2.jpg"],
[UIImage imageNamed:#"photo3.jpg"], nil];
animationView.animationDuration = 5;
animationView.animationRepeatCount = 0;
[animationView startAnimating];
[self.view addSubview:animationView];
}
images do appear one after the other, in a 5 sec delay, what i want now is to make them fade-in and fade-out each time an image appears, any suggestions on that?
Thanks in advance for your help
I was trying to do something similar. What I did was setup a timer that called a UIView transitionWithView on a UIImageView that was incrementing through the array of my slideshow photos.
- (void)viewDidLoad{
[super viewDidLoad];
self.welcomePhotos = [NSArray arrayWithObjects:#"welcome_1.png",#"welcome_2.png", #"welcome_3.png", nil];
self.imageView1.image = [UIImage imageNamed:[self.welcomePhotos objectAtIndex:0]];
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:#selector(transitionPhotos) userInfo:nil repeats:YES];
}
-(void)transitionPhotos{
if (photoCount < [self.welcomePhotos count] - 1){
photoCount ++;
}else{
photoCount = 0;
}
[UIView transitionWithView:self.imageView1
duration:2.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{ self.imageView1.image = [UIImage imageNamed:[self.welcomePhotos objectAtIndex:photoCount]]; }
completion:NULL];
}
I create i uiscrollview, when i run my app, touch the scrollview but the scrollview does not scroll.
help me!
think you!
The code as:
for (int i=0; i<imageCounts; i++)
{
GalleryProperty *itemVo = [itemList objectAtIndex:i];
//1 button
UIImageView *imageview = [[UIImageView alloc] initWithFrame:CGRectMake(0,20,320,460)];
UIImage *image = [UIImage imageWithContentsOfFile:itemVo.pic];
[imageview setImage:image];
[scrollView addSubview:imageview ];
[imageView release];
}
You have to set the content size:
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * 3, scrollView.frame.size.height);
When initializing set scrollView frame size equal to your View Size.
and setContent offset size according to the no of images you're showing in the scrollView.
In your case
UIScrollView *yourScrollView=[[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];//init scroll view
for (int i=0; i<imageCounts; i++)
{
GalleryProperty *itemVo = [itemList objectAtIndex:i];
//1 button
UIImageView *imageview = [[UIImageView alloc] initWithFrame:CGRectMake(0,20,320,460)];
UIImage *image = [UIImage imageWithContentsOfFile:itemVo.pic];
[imageview setImage:image];
[scrollView addSubview:imageview ];
yourScrollView.contentSize=CGSizeMake(320*i, 460);//set content size here
[imageView release];
}
Almost sorted with my 1st app, just a simple news app but when I load it onto my iPhone the scroll seems jerky can someone have a look at my function and see if i'm doing something wrong.
I need the image on the right hand side thats why i'm using custom cells.
Thanks
For any help
#define DATELABEL_TAG 1 #define MAINLABEL_TAG 2 #define PHOTO_TAG 3
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MainNewsCellIdentifier = #"MainNewsCellIdentifier";
UILabel *mainLabel, *dateLabel;
UIImageView *photo;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: MainNewsCellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier: MainNewsCellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
dateLabel = [[[UILabel alloc] initWithFrame:CGRectMake(15.0,15.0,170.0,15.0)] autorelease];
dateLabel.tag = DATELABEL_TAG;
dateLabel.font = [UIFont systemFontOfSize:10.0];
dateLabel.textAlignment = UITextAlignmentLeft;
dateLabel.textColor = [UIColor darkGrayColor];
dateLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin; //| UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:dateLabel];
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(15.0,28.0,170.0,60.0)] autorelease];
mainLabel.tag = MAINLABEL_TAG;
mainLabel.font = [UIFont boldSystemFontOfSize:14.0];
mainLabel.textColor = [UIColor blackColor];
mainLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
mainLabel.numberOfLines = 0;
//mainLabel.backgroundColor = [UIColor greenColor];
[cell.contentView addSubview:mainLabel];
photo = [[[UIImageView alloc] initWithFrame:CGRectMake(190.0,15.0,85.0,85.0)] autorelease];
photo.tag = PHOTO_TAG;
photo.contentMode = UIViewContentModeScaleAspectFit;//UIViewContentModeScaleAspectFit; //
[cell.contentView addSubview:photo];
}
else {
dateLabel = (UILabel *)[cell.contentView viewWithTag:DATELABEL_TAG];
mainLabel = (UILabel *)[cell.contentView viewWithTag:MAINLABEL_TAG];
photo = (UIImageView *)[cell.contentView viewWithTag:PHOTO_TAG];
}
NSUInteger row = [indexPath row];
NSDictionary *stream = (NSDictionary *) [dataList objectAtIndex:row];
NSString *title = [stream valueForKey:#"title"];
NSString *titleString = #"";
if( ! [title isKindOfClass:[NSString class]] )
{
titleString = #"";
}
else
{
titleString = title;
}
CGSize maximumSize = CGSizeMake(180, 9999);
UIFont *dateFont = [UIFont fontWithName:#"Helvetica" size:14];
CGSize dateStringSize = [titleString sizeWithFont:dateFont
constrainedToSize:maximumSize
lineBreakMode:mainLabel.lineBreakMode];
CGRect dateFrame = CGRectMake(15.0, 28.0, 170.0, dateStringSize.height);
mainLabel.frame = dateFrame;
mainLabel.text = titleString;
dateLabel.text = [stream valueForKey:#"created"];
NSString *i = [NSString stringWithFormat:#"http://www.website.co.uk/images/%#", [stream valueForKey:#"image"]];
NSData *imageURL = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:i]];
UIImage *newsImage = [[UIImage alloc] initWithData:imageURL];
photo.image = newsImage;
[imageURL release];
[newsImage release];
return cell;
}
The problem is this:
NSString *i = [NSString stringWithFormat:#"http://www.website.co.uk/images/%#", [stream valueForKey:#"image"]];
NSData *imageURL = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:i]];
UIImage *newsImage = [[UIImage alloc] initWithData:imageURL];
You effectively say here, that as soon as the cell needs to be displayed, the image must be fetched and presented. This will cost some time - too much for a good user experience.
You should fetch the images before or while you present the table view, and cache them, e.g. in an array. Or you must handle things asynchronously, meaning that you do the loading in the background, and not wait with return cell; until the image is actually downloaded. This will be a little harder to get right.
Even if you asynchronously download images, you'll still have a jerky scroll.
Why? It's lazy image decompression. ios performs decompression at the moment it will be displayed on the screen. You have to manually decompress the images in a background thread.
Decompression does not merely mean instantiating a UIImage object. It can be somewhat complicated. The best solution, is to download SDWebImage and use the image decompressor that's included. SDWebImage will asynchronously download and perform decompression for you.
To read more about the issue see: http://www.cocoanetics.com/2011/10/avoiding-image-decompression-sickness/