UIScrollView setNeedsDisplay not working, or something else? - objective-c

Final solution to this issue is given below the question
My goal is to create an image picker that initially creates each image view inside of a scroll view, and then passes a reference for that image view to a method that will asynchronously update the imageview.image with the appropriate image.
This works great as is.
The issue I run into is that the scroll view only shows the image views in a batch at the end of the method, whereas I'd like for them to print one by one as they are created (image available or not).
If I touch the scroll view to scroll, it works the way I want it to, but if I make no touch at all, the screen stays white until all of the images, not just image views, have finished loading.
I've tried placing setNeedsDisplay everywhere, for every view, including self.view, scrollview, and each individual imageview. What's going on?
- (void)viewDidLoad {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
[self setGridView];
});
}
- (void)setGridView {
// begin loading images
NSString * retina = ([[MVProject sharedInstance] settings_retina]) ? #"2" : #"";
CGRect scrollframe = CGRectMake(0, 0, 300, 275);
UIScrollView * newscrollview;
newscrollview = [[UIScrollView alloc] initWithFrame:scrollframe];
newscrollview.scrollEnabled = YES;
newscrollview.delegate = self;
[newscrollview setContentSize:CGSizeMake(300, (((ceilf([[NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:#"Flickr_Dictionary"]] count]/4)) * (58+15)) + 15 + 58 + 15))];
[picsMVContentCell.contentView addSubview:newscrollview];
float currentx = 11;
float currenty = 17;
NSInteger index = 0;
for (NSDictionary * d in [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:#"Flickr_Dictionary"]]) {
// create button
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(currentx, currenty, 58, 58);
button.imageView.backgroundColor = [UIColor colorWithRed:(241/255.0) green:(241/255.0) blue:(241/255.0) alpha:1];
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.layer.cornerRadius = 6;
button.imageView.layer.masksToBounds = YES;
button.imageView.accessibilityLabel = [d objectForKey:#"id"];
button.imageView.accessibilityValue = [d objectForKey:#"full"];
button.imageView.tag = index++;
[button addTarget:self action:#selector(imageClick:) forControlEvents:UIControlEventTouchUpInside];
UIImage * image = [MVImage imageWithImage:[UIImage imageNamed:#""] covertToWidth:58.0f covertToHeight:58.0f];
[button setImage:image forState:UIControlStateNormal];
[newscrollview addSubview:button];
[newscrollview bringSubviewToFront:button];
[newscrollview setNeedsDisplay];
// calculate next image view position
currentx += (button.imageView.frame.size.width+15);
if (currentx >= 289) {
currentx = 11;
currenty += (button.imageView.frame.size.height+15);
}
// set image
NSString * nsuserdefault = [NSString stringWithFormat:#"Settings_SFThumbs%#_%#", retina, [d objectForKey:#"id"]];
if ([NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]]) {
MVImage * thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]];
[button setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f] forState:UIControlStateNormal];
} else {
[MVProject asynchronousImageLoad:button.imageView urlpath:[d objectForKey:#"thumb"] nsuserdefaultpath:nsuserdefault];
}
}
}
Edit on Feb 7, 2012 3:26 PM
these changes fixed all issues related to the code given in the question
thanks to #Eugene for pointing me in the right direction
/* ---------- ---------- ---------- ---------- ---------- */
- (void)viewDidLoad {
[super viewDidLoad];
[[MVProject sharedInstance] syncLoadSF:0];
self.newscrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 300, 275)];
self.newscrollview.scrollEnabled = YES;
self.newscrollview.delegate = self;
[self.newscrollview setContentSize:CGSizeMake(300, (((ceilf(([[NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:#"Flickr_Dictionary"]] count]-1)/4)) * (58+15)) + 15 + 58 + 15))];
[picsMVContentCell.contentView addSubview:self.newscrollview];
[self setGridView];
}
/* ---------- ---------- ---------- ---------- ---------- */
- (void)setGridView {
NSString * retina = ([[MVProject sharedInstance] settings_retina]) ? #"2" : #"";
[self.newscrollview setNeedsDisplay];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSInteger index = 0;
for (NSDictionary * d in [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:#"Flickr_Dictionary"]]) {
// create button
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake((11 + ((index%4)*(58+15))), (17 + ((floorf(index/4))*(58+15))), 58, 58);
button.imageView.backgroundColor = [UIColor colorWithRed:(241/255.0) green:(241/255.0) blue:(241/255.0) alpha:1];
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.layer.cornerRadius = 3;
button.imageView.layer.masksToBounds = YES;
button.imageView.accessibilityLabel = [d objectForKey:#"id"];
button.imageView.accessibilityValue = [d objectForKey:#"full"];
button.imageView.tag = index++;
[button addTarget:self action:#selector(imageClick:) forControlEvents:UIControlEventTouchUpInside];
dispatch_sync(dispatch_get_main_queue(), ^ {
[button setImage:[MVImage imageWithImage:[UIImage imageNamed:#""] covertToWidth:58.0f covertToHeight:58.0f] forState:UIControlStateNormal];
[self.newscrollview addSubview:button];
[self.newscrollview bringSubviewToFront:button];
[self.newscrollview setNeedsDisplay];
// set image
NSString * nsuserdefault = [NSString stringWithFormat:#"Settings_SFThumbs%#_%#", retina, [d objectForKey:#"id"]];
if ([NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]]) {
MVImage * thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]];
[button setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f] forState:UIControlStateNormal];
} else {
[MVProject asynchronousImageLoad:button.imageView urlpath:[d objectForKey:#"thumb"] nsuserdefaultpath:nsuserdefault];
}
});
}
});
[self.newscrollview setNeedsDisplay];
}

You cannot work with drawing on the background thread. Each time you add subview you should do this in the main thread. So the salvation for you would be to use your drawing code in a sync block, that's run on the main queue
dispatch_sync(dispatch_get_main_queue(), ^ {
[newscrollview addSubview:button];
[newscrollview bringSubviewToFront:button];
[newscrollview setNeedsDisplay];
// calculate next image view position
currentx += (button.imageView.frame.size.width+15);
if (currentx >= 289) {
currentx = 11;
currenty += (button.imageView.frame.size.height+15);
}
// set image
NSString * nsuserdefault = [NSString stringWithFormat:#"Settings_SFThumbs%#_%#", retina, [d objectForKey:#"id"]];
if ([NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]]) {
MVImage * thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]];
[button setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f] forState:UIControlStateNormal];
} else {
[MVProject asynchronousImageLoad:button.imageView urlpath:[d objectForKey:#"thumb"] nsuserdefaultpath:nsuserdefault];
}
});

The problem your having is with setting the images. What your trying to do is add all the image containers to the scrollview. Then as the images are ready load them into their container. There are 2 ways to go about doing this.
First off add all the containers to the scrollview. (You might want some loading indicator or default image to show its loading)
1) Create a background thread for getting the images ready. When the image is ready add it to its container. (I find this way to be more work and kinda a pain)
2) Create a custom container, and let the custom container add its own image when its image is ready.
For example, I am loading images from a server. So I created AsyncImage class that is a custom class of UIImageView. And I created a function that I send the image url to and it handles the rest. It creates an NSURLConnection and when the data is loaded it calls self.image = [UIImage imageWithData:data];

Related

NSMutableArray not holding UIImages properly?

I have enabled my Cocoa Touch app to be navigable by swiping left or right to alter positions in history. The animation is kind of done like Android's "card" style. Where swiping to the left (<--) just moves the current screen image out of the way, while showing the previous view beneath it.
This works fine, but when I want to swipe the other way (-->), to go back, I need to get the previous image, and move that over the current view. Now, I had this working if I only store the previous image, but what if I go <-- a few times, then I will not have enough images.
So, the solution is obvious, use an NSMutableArray and just throw the latest image at the front of the array, and when you swipe the other way, just use the first image in the array. However, the image never shows when I start the animation. It just shows nothing. Here's the required methods you should see:
-(void)animateBack {
CGRect screenRect = [self.view bounds];
UIImage *screen = [self captureScreen];
[imageArray insertObject:screen atIndex:0]; //Insert the screenshot at the first index
imgView = [[UIImageView alloc] initWithFrame:screenRect];
imgView.image = screen;
[imgView setHidden:NO];
NSLog(#"Center of imgView is x = %f, y = %f", imgView.center.x, imgView.center.y);
CGFloat startPointX = imgView.center.x;
CGFloat width = screenRect.size.width;
NSLog(#"Width = %f", width);
imgView.center = CGPointMake(imgView.center.x, imgView.center.y);
[self.view addSubview: imgView];
[self navigateBackInHistory];
[UIView animateWithDuration:.3 animations:^{
isSwiping = 1;
imgView.center = CGPointMake(startPointX - width, imgView.center.y);
} completion:^(BOOL finished){
// Your animation is finished
[self clearImage];
isSwiping = 0;
}];
}
-(void)animateForward {
CGRect screenRect = [self.view bounds];
//UIImage *screen = [self captureScreen];
UIImage *screen = [imageArray objectAtIndex:0]; //Get the latest image
imgView = [[UIImageView alloc] initWithFrame:screenRect];
imgView.image = screen;
[imgView setHidden:NO];
NSLog(#"Center of imgView is x = %f, y = %f", imgView.center.x, imgView.center.y);
CGFloat startPointX = imgView.center.x;
CGFloat width = screenRect.size.width;
NSLog(#"Width = %f", width);
imgView.center = CGPointMake(imgView.center.x - width, imgView.center.y);
[self.view addSubview: imgView];
[UIView animateWithDuration:.3 animations:^{
isSwiping = 1;
imgView.center = CGPointMake(startPointX, imgView.center.y);
} completion:^(BOOL finished){
// Your animation is finished
[self navigateForwardInHistory];
[self clearImage];
isSwiping = 0;
}];
}
-(void)clearImage {
[imgView setHidden:YES];
imgView.image = nil;
}
-(void)navigateBackInHistory {
[self saveItems:self];
[self alterIndexBack];
item = [[[LEItemStore sharedStore] allItems] objectAtIndex:currentHistoryIndex];
[self loadItems:self];
}
-(void)navigateForwardInHistory {
[imageArray removeObjectAtIndex:0]; //Remove the latest image, since we just finished swiping this way.
[self saveItems:self];
[self alterIndexForward];
item = [[[LEItemStore sharedStore] allItems] objectAtIndex:currentHistoryIndex];
[self loadItems:self];
}
Note that imgView is a class-level UIImageView and imageArray is a class level array.
Any ideas? Thanks.
Edit
Here's the code at the top of my .m to initalize it. Still does not work.
.....
NSMutableArray *imageArray;
- (void)viewDidLoad
{
[super viewDidLoad];
imageArray = [imageArray initWithObjects:nil];
It looks like you forgot to create the array. Something like this at the appropriate time would do (assuming ARC):
imageArray = [NSMutableArray array];
Glad that worked out.

More than 1 image on a subview not loading

I'm trying to add images over a ScrollView. I have the x and y point in a plist file and they are called by an enum.
enum {
kLogoImage = 1,
kNewLogoImage,
};
#implementation
- (void) _setupStaticViews
{
UIButton *image = [UIButton buttonWithType:UIButtonTypeCustom];
[image setBackgroundImage:[UIImage imageNamed:#"logo.png"] forState:UIControlStateNormal];
[image addTarget:self action:#selector(_addContactButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
image.frame = CGRectMake(0.0 ,0.0, 150.0, 150.0);
image.tag = kLogoImage;
[_mapImageView addSubview:image];
_staticViews = #[image];
UIButton *image2 = [UIButton buttonWithType:UIButtonTypeCustom];
[image2 setBackgroundImage:[UIImage imageNamed:#"Time Bakground.png"] forState:UIControlStateNormal];
[image2 addTarget:self action:#selector(_addContactButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
image2.frame = CGRectMake(0.0 ,0.0, 250.0, 150.0);
image2.tag = kNewLogoImage;
[_mapImageView addSubview:image2];
_staticViews = #[image2];
for ( UIView *view in _staticViews ) {
CGPoint point = [self _basePositionForView:view];
CGRect frame = view.frame;
frame.origin = point;
view.frame = frame;
}
}
If I have only image showing, it works fine. But I need to add more than one and adding the second one causes the first one to be at xy point 0,0, and Image2 isn't visible.
How would I go about adding another image?
- (CGPoint) _basePositionForView:(UIView *)view {
NSString *key = [NSString stringWithFormat:#"%d", view.tag];
NSString *stringValue = [_coordinates objectForKey:key];
NSArray *values = [stringValue componentsSeparatedByString:#":"];
if ( [values count] < 2 ) return CGPointZero;
CGPoint result = CGPointMake([[values objectAtIndex:0] floatValue], [[values objectAtIndex:1] floatValue]);
return result;
}
I noticed that you first make
_staticViews = #[image];
and later
_staticViews = #[image2];
Don't you rather mean to have
_staticViews = #[image, image2];
?
You should iterate and change x accordingly in the frame:
for ( int iterator=0; iterator< [[_staticViews subviews] count]; iterator++){
...
current_image.frame = CGRectMake(YOUR_IMG_WIDTH * iterator ,0.0, YOUR_IMG_WIDTH, 150.0);
...}

UIScrollView with UIImageview and gestures using transitionFromView acting strange

I made a view which holds a UIScrollview:
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(10, 65, 300, 188)];
//BackViews will hold the Back Image
BackViews = [[NSMutableArray alloc] init];
for (int i=0; i<BigPictures.count; i++) {
[BackViews addObject:[NSNull null]];
}
FrontViews = [[NSMutableArray alloc] initWithCapacity:BigPictures.count];
[self.pageControl setNumberOfPages:BigPictures.count];
Then I add several UIImageviews containing images:
//BigPictures holds objects of type UIImage
for (int i = 0; i < BigPictures.count; i++) {
UIImageView *ImageView = [[UIImageView alloc] initWithImage:[BigPictures objectAtIndex:i]];
ImageView.frame = [self.scrollView bounds];
[ImageView setFrame:CGRectMake(self.scrollView.frame.size.width * i, ImageView.frame.origin.y, ImageView.frame.size.width, ImageView.frame.size.height)];
//this saves the FrontView for later (flip)
[FrontViews insertObject:ImageView atIndex:i];
[self.scrollView addSubview:test];
}
// Detect Single Taps on ScrollView
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(flip)];
[self.scrollView addGestureRecognizer:tap];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * BigPictures.count, self.scrollView.frame.size.height);
self.scrollView.pagingEnabled = YES;
self.scrollView.delegate = self;
Ok so far so good. Now the method which does the flipImage part:
- (void)flip {
int currentPage = self.pageControl.currentPage;
UIView *Back = nil;
if ([BackViews objectAtIndex:currentPage] == [NSNull null]) {
//CreateBackView is just creating an UIView with text in it.
Back = [self CreateBackView];
[BackViews replaceObjectAtIndex:currentPage withObject:Back];
[UIView transitionFromView:[[self.scrollView subviews] objectAtIndex:currentPage] toView:[BackViews objectAtIndex:currentPage] duration:0.8 options:UIViewAnimationOptionTransitionFlipFromLeft completion:NULL];
} else {
[UIView transitionFromView:[[self.scrollView subviews] objectAtIndex:currentPage] toView:[FrontViews objectAtIndex:currentPage] duration:0.8 options:UIViewAnimationOptionTransitionFlipFromRight completion:NULL];
[BackViews replaceObjectAtIndex:currentPage withObject:[NSNull null]];
}
[self.view addSubview:Back];
[self rebuildScrollView];
}
This is what rebuildScrollView does:
- (void)rebuildScrollView
{
for (UIView *subview in self.scrollView.subviews) {
[subview removeFromSuperview];
}
for (int i = 0; i < BigPictures.count; i++) {
if ([BackViews objectAtIndex:i] == [NSNull null]) {
[self.scrollView addSubview:[FrontViews objectAtIndex:i]];
} else {
[self.scrollView addSubview:[BackViews objectAtIndex:i]];
}
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * BigPictures.count, self.scrollView.frame.size.height);
self.scrollView.pagingEnabled = YES;
self.scrollView.delegate = self;
}
So the behavior is the following:
If I click on the first image (1 of 3 in scrollview) the effect is the way I want it, meaning the frontimage turns around and shows the empty (white) back with some text in the middle
If I click on the second image, the image turns but the back is completely empty showing the grey background of the window. If I scroll to the other images, the still show the front image (as expected)
Now I click on the third image and its the same as 1) great.
Current layout is now [BackView, Nothing, Backview)
Lets run that again. But now I click on the last image and its the same as 2) :(
Any ideas whats going wrong here?
EDIT: Some new findings. I doubled the amount of pictures and this is how Front and Backviews are placed (after flipping each one). P = Picture & B = Backview.
P_1(B_1) - actually the only correct one
P_2(empty - should be B_2)
P_3(B_2 - should be B_3)
P_4(empty - should be B_4)
P_5(B_3 - should be B_5)
P_6(empty - should be B_6)
Did a complete rebuild and now it works. Really strange because I used the exact same code.

Issue with scroll view and accessing its subviews

I have a scroll view that contains image view sized 68x78:
As you could see, all that images except from the centered one have a shadow. It changes when user scrolls, center image is always clear. It goes perfect until for the left edge image:
Here is the code:
-(void) buildSlideView{
fotosJugadores = [[NSArray alloc] initWithObjects:#"cara5.png", #"cara7.png", #"cara8.png", #"cara9.png", #"cara11.png", #"cara13.png", #"cara14.png", #"cara15.png", #"cara18.png",#"cara19.png", #"cara20.png", #"cara32.png",#"cara44.png",#"cara51.png", #"cara100.png", #"cara101.png", #"cara102.png",#"cara103.png", #"cara104.png", #"cara105.png",#"cara106.png",#"cara107.png", nil];
numberOfViews = [fotosJugadores count];
for (int i = 0; i < [fotosJugadores count]; i++) {
UIImage *myImage = [UIImage imageNamed:[fotosJugadores objectAtIndex:i]];
CGFloat yOrigin = i * (myImage.size.width+3) + 120;
UIImageView *awesomeView = [[UIImageView alloc] initWithFrame:CGRectMake(yOrigin, 0, myImage.size.width, myImage.size.height)];
awesomeView.tag = i;
awesomeView.image = myImage;
awesomeView.alpha = 0.5f;
awesomeView.backgroundColor = [UIColor blackColor];
[self.jugadorSlide addSubview:awesomeView];
awesomeView=nil;
}
[jugadorSlide setBackgroundColor:[UIColor blackColor]];
jugadorSlide.contentSize = CGSizeMake(68 * numberOfViews+240,78);
jugadorSlide.layer.cornerRadius = 11;
jugadorSlide.layer.masksToBounds = YES;
[jugadorSlide setContentOffset:CGPointMake(((68 * numberOfViews)/2), 0)];
//jugadorSlide.decelerationRate = UIScrollViewDecelerationRateNormal;
[self scrollViewDidEndDragging:jugadorSlide willDecelerate:NO];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
currentIndex = roundf(scrollView.contentOffset.x / 68);
NSLog(#"current end %d", currentIndex);
UIImageView *currentImage = [scrollView viewWithTag:currentIndex];
if (currentIndex>0&&currentIndex<=21){
if (currentIndex==currentImage.tag){
currentImage.alpha=1.0f;
[self changePerfilImage:currentImage.tag];}
CGPoint pointZero= CGPointMake(scrollView.contentOffset.x, currentImage.frame.origin.y);
[jugadorSlide setContentOffset:pointZero animated:YES];
}else {
UIImageView *currentImage = [scrollView viewWithTag:0];
NSLog(#"end dragging image tag %d", currentImage.tag);
currentImage.alpha=1.0f;
[self changePerfilImage:currentImage.tag];}
CGPoint pointZero= CGPointMake(currentImage.frame.origin.x+15, 0);
//[jugadorSlide setContentOffset:pointZero animated:YES];
}
As you can see, in the scrollViewDidEndDragging: "else" , I forced the tag as a desesperate solution, but images doesn't get clear.
You are incrementing the tag twice...
awesomeView.tag = i++;
Should just be:
awesomeView.tag = i+1;
I use i+1 because I never use a tag of 0 since any subview that hasn't been assigned a tag will have a tag of 0.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
NSInteger currentIndex = roundf(scrollView.contentOffset.x / 68.0) + 1;
UIImageView *currentImage = [scrollView viewWithTag:currentIndex];
...
}
If this doesn't work you should NSLog the currentIndex each time you land on a new image and see what is happening when you land on the first one.

Activity Indicator while loading images inside UIScrollView

I have UIScrollView that contains images from the server.
I should put Activity Indicator while the image is currently loading.
UIScrollView contains dynamic number of images from the server.
May I know how can I add activity indicators on each page while the image is loading and remove once image is loaded.
Here's my code to retrieve images:
NSDictionary *items = [NSDictionary dictionaryWithObject:dictInfo forKey:#"images"];
imageList = [items objectForKey:#"images"];
NSArray *img = [imageList objectForKey:#"list"];
NSInteger imgCount = [img count];
buttonArray = [[NSMutableArray alloc] init];
for (int i=0; i<imgCount; i++) {
NSDictionary *imgDict = [img objectAtIndex:i];
// REQUEST FOR IMAGES
NSString *imgPath = [imgDict objectForKey:#"image_slot"];
NSString *imgURL = imgPath;
__block ASIHTTPRequest *requestImage = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:imgURL]];
[requestImage setCompletionBlock:^{
imgView = [UIImage imageWithData:[requestImage responseData]];
if (imgURL.length) {
[pendingRequests removeObjectForKey:imgURL];
}
scrollView.userInteractionEnabled = YES;
scrollView.exclusiveTouch = YES;
scrollView.canCancelContentTouches = YES;
scrollView.delaysContentTouches = YES;
scrollView.bounces = NO;
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
SWTUIButton *imgBtn = [[SWTUIButton alloc] initWithFrame:frame];
imgBtn.url = [requestImage.userInfo objectForKey:#"rURL"];
[imgBtn setImage:imgView forState:UIControlStateNormal];
imgBtn.backgroundColor = [UIColor clearColor];
[imgBtn addTarget:self action:#selector(buttonpushed:) forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:imgBtn];
[buttonArray addObject:imgBtn];
[imgBtn release];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * img.count, self.scrollView.frame.size.height);
}];
I highly suggest you use NINetworkImageView from https://github.com/jverkoey/nimbus project.
It's very light and useful.
It has a delegate method to let you know when an image is loaded.
What you basically need to do is:
1. create an NINetworkImageView for each page, just like you do with UIImageView, and call set
NINetworkImageView* networkImageView = [[[NINetworkImageView alloc] initWithImage:initialImage]
autorelease];
networkImageView.delegate = self;
networkImageView.contentMode = UIViewContentModeCenter;
[networkImageView setPathToNetworkImage:
#"http://farm3.static.flickr.com/2484/3929945380_deef6f4962_z.jpg"
forDisplaySize: CGSizeMake(kImageDimensions, kImageDimensions)];
https://github.com/jverkoey/nimbus/tree/master/examples/photos/NetworkPhotoAlbums
the add the indicator to the networkImageView as a subview.
implement the delegate as follows:
-(void)networkImageView:(NINetworkImageView *)imageView didLoadImage:(UIImage *)image {
[imageView removeAllSubviews];
}
the end result would be a much smaller code for doing the same thing.