Enlarging image when tapped ios - ios

I have an app that implements horizontal gallery. In my story board when a job (cell in a tableview) is tapped it will redirect and display job details. In my Job Details Scene : I have index 0 : for company logo and name, salary and the position. in index 1 : i have the horizontal gallery - I created a scrollview programmatically and created a imageviews inside the scrollview.
Here's how I created the scrollview and imageviews:
else if (indexPath.section == 1)
{
[self getImages];
[cell.contentView addSubview:self.scrollView];
return cell;
}
- (void)getImages
{
mutableURLstorage = [[NSMutableArray alloc] init];
imagesArray = [[NSMutableArray alloc]init];
NSInteger noOfImages = (unsigned long)[mutableStorage count];
NSString* strURL;
//store image_paths (company and branch) in a mutable array
for (int i = 0; i < noOfImages; i++)
{
NSDateFormatter *df=[[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
NSDate *date = [NSDate date];
NSDate *oneMinLater = [date dateByAddingTimeInterval:1444];
NSString *hmac_body =[NSString stringWithFormat:#"%#\n%lld\n%#",METHOD,[#(floor([oneMinLater timeIntervalSince1970])) longLongValue],CONTAINER_PATH] ;
// below get different string with shaA diagest
const char *cKey2 = [KEY cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData2 = [hmac_body cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC2[CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, cKey2, strlen(cKey2), cData2, strlen(cData2), cHMAC2);
NSData *HMAC2 = [[NSData alloc] initWithBytes:cHMAC2 length:sizeof(cHMAC2)];
NSString *HMACStr = [[HMAC2 description] stringByReplacingOccurrencesOfString:#"<" withString:#""];
HMACStr = [HMACStr stringByReplacingOccurrencesOfString:#">" withString:#""];
HMACStr = [HMACStr stringByReplacingOccurrencesOfString:#" " withString:#""];
strURL = [NSString stringWithFormat:#"%#%#?temp_url_sig=%#&temp_url_expires=%lld", URLstorage, CONTAINER_PATH, HMACStr, [#(floor([oneMinLater timeIntervalSince1970])) longLongValue]];
[mutableURLstorage addObject:strURL];
[imagesArray addObject:[[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]]]];
}
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGSize pageSize = CGSizeMake(ITEM_WIDTH, self.scrollView.frame.size.height);
_pgCtr = [[UIPageControl alloc] initWithFrame:CGRectMake(0, screenRect.size.height-30, 320, 36)];
_pgCtr.backgroundColor=[UIColor grayColor];
int numberofPage=ceil((float)[imagesArray count]/3.5);
_pgCtr.numberOfPages= numberofPage;
self.scrollView.contentSize = CGSizeMake(320*numberofPage, pageSize.height);
int imgCurrentX = 10;
for (UIImageView* image in imagesArray) {
#autoreleasepool {
imageview = [[UIImageView alloc] initWithFrame:CGRectMake(imgCurrentX, 0, 70, 70)];
imageview.image = (UIImage*)image;
[imageview setUserInteractionEnabled:YES];
[self.scrollView addSubview:imageview];
imgCurrentX = imgCurrentX+80;
}
}
}
I am able to display the horizontal gallery but the images are all for thumbnails.
Now I implemented this code in my viewDidLoad to determine whether an imageview is tapped:
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapAction:)]];
In my singleTapAction method i am using LeveyPopListView to display the enlarged iamges.
- (void)singleTapAction:(UIGestureRecognizer *)singleTap_
{
[self createLeveyPopList];
}
- (void)createLeveyPopList
{
NSString *jobs_name = #"JOBSD";
if(self.lplv.delegate != nil)
return;
self.lplv = [[LeveyPopListView alloc] initWithTitle:#"The following jobs are located here:" options:imagesArray jobName:jobs_name handler:^(NSInteger anIndex) {
}];
self.lplv.delegate = self;
[self.lplv showInView:self.view animated:YES];
}
What I did in my pop up is redisplay the original image gallery (the one in job details scene) but the images are enlarged. My app is successfully implementing the horizontal image gallery. Now my problem is, for example image 2 is tapped, I need to display the image 2 first instead of displaying image 1 first.
I hope someone can help me with this. Thank you!

Add a method to change the size of your ImageView that contains the image, like so:
- (IBAction)buttonTapped:(id)sender {
// Use this Sender property to your advantage
[yourImageViewName setFrame:CGRectMake(0, 0, 100, 100)];
}
Of course, adjust the coordinates to however you would like them. You can also play around in the image view's settings in IB to make sure that your picture does not become distorted upon enlargement.
Now, you could also add tags to your images and enlarge the image view based upon which tag you've pressed. If you want to go that route instead, let me know and I'll post the code. I hope I helped!

Related

UIpagecontrol Need Animation Rigth to Left

Using UIControlpage in my application. load the image and display in page control successfully. but i want to display the images animation like right to left move. Using timer call page control and increase the array count.
//// using NSTimer to call function to show the animation.
[NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:#selector(loadNextController)
userInfo:nil
repeats:YES];
ScrollViewPage = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 20, frameX, frameY)];
ScrollViewPage.pagingEnabled = YES;
ScrollViewPage.backgroundColor=[UIColor redColor];
ScrollViewPage.delegate = self;
ScrollViewPage.backgroundColor = [UIColor clearColor];
ScrollViewPage.contentSize = CGSizeMake(frameX, frameY);
ScrollViewPage.showsHorizontalScrollIndicator = NO;
ScrollViewPage.pagingEnabled = YES;
pageControl = [[UIPageControl alloc] init];
pageControl.frame = CGRectMake(100,self.view.frame.size.height-100,self.view.frame.size.width-200,100);
pageControl.numberOfPages = [_pageImages count];
pageControl.currentPage = 0;
[self.view addSubview: ScrollViewPage];
for(int i = 0; i < [_pageImages count]; i++)
{
NSURL *url = [NSURL URLWithString:[_pageImages objectAtIndex:i]];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
UIImage *tmpImage = [UIImage imageWithData:data];
_backgroundImageView = [[UIImageView alloc] initWithImage:tmpImage];
_backgroundImageView.frame = CGRectMake(frameX * i, 0.0, frameX, frameY);
[ScrollViewPage addSubview:_backgroundImageView];
}
ScrollViewPage.contentSize = CGSizeMake(frameX*[_pageImages count], frameY);
pageControl.backgroundColor=[UIColor orangeColor];
[self.view addSubview:pageControl];
[pageControl addTarget:self action:#selector(pageTurn:) forControlEvents:UIControlEventValueChanged];
///// Here call the timer function
- (void)loadNextController
{
pageControl.currentPage = (pageControl.currentPage+1)%self.pageImages.count;
ScrollViewPage.contentOffset = CGPointMake(pageControl.currentPage * self.view.bounds.size.width, 0);
}
Here i need to show left to right move in uipagecontrol. help me..
In general you should always write what is your current result, what is the expected result and what have you tried.
I can only guess the issue you are facing is there are no animations.
The scroll view has a method setContentOffset:animated which you can use to animate the transition. Another approach is to use UIView animateWithDuration and sett the offset in the method block.
Try any or both of these...
[ScrollViewPage setContentOffset:CGPointMake(pageControl.currentPage * self.view.bounds.size.width, 0) animated:YES];
Or
[UIView animateWithDuration:0.2 animations:^{
ScrollViewPage.contentOffset = CGPointMake(pageControl.currentPage * self.view.bounds.size.width, 0);
}];
EDIT: Loop images.
To loop images you really only need 2 images on the scroll view at the time. I will show you the concept with 3 and you can try and play around with it.
NSArray *allImages;
NSInteger currentIndex = 0;
UIScrollView *scrollView;
UIImageView *imageViews[3];
- (void)begin {
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width*3.0, scrollView.frame.size.height); // always have 3 images at the time
scrollView.contentOffset = CGPointMake(scrollView.frame.size.width, 0.0); // put to center
for(int i=0; i<3; i++) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(scrollView.frame.size.width*i, 0.0, scrollView.frame.size.width, scrollView.frame.size.height)];
[scrollView addSubview:imageView];
imageView[i] = imageView;
}
[self layoutForIndex:currentIndex];
}
- (void)nextImage {
currentIndex++;
[self layoutForIndex:currentIndex];
scrollView.contentOffset = CGPointZero;
[scrollView setContentOffset:CGPointMake(scrollView.frame.size.width, 0.0) animated:YES]
}
- (void)layoutForIndex:(NSInteger)index {
if(allImages.count > 0) { // we need at least one image to do something
for(int i=0; i<3; i++) {
// do the circling
NSInteger imageIndex = index-1+i;
while(imageIndex < 0) imageIndex+=allImages.count;
while(imageIndex >= allImages.count) imageIndex-=allImages.count;
imageViews[i].image = imageViews[imageIndex];
}
}
}
But in general for what you are doing you do not even need a scroll view. On next you can simply add another image view next to the current one and then use the UIView animation to reposition both of the image views.

Reload UIScrollView by tapping a UIButton

Let me explain my project first. I have some data in my SQLIte DB table called "note".
In "note" table I have these fields: id, noteToken, note.
What I am doing here is load all the note in an NSMUtableArray from that table. And create UIButton according to that array content number and add those buttons in a UIScrollView as subView. The number of buttons and width of scrollview generate auto according to the number of content of that array. Now, when some one tap one of those Buttons, it will bring him to a next viewController and show him the corresponding note details in that viewController.
I do the same thing with another NSMUtableArray, but these time it read all the id from the "note" table. It equally generate new delete button in the same UIScrollView. But if some one tap on these delete button it will delete that particular note from the table "note" of SQLIte DB. AND RELOAD THE UIScrollView. All are done except the RELOAD THE UIScrollView part. This is what I want. I tried with all exist solution but don't know why it's not working.
Here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.noteToken = [NSString stringWithFormat:#"%#%#", fairId, exibitorId];
scrollViewNoteWidth = 100;
[scrollViewNote setScrollEnabled:YES];
[scrollViewNote setContentSize:CGSizeMake((noteButtonWidth * countNoteButtonArray) + scrollViewNoteWidth, 100)];
sqLite = [[SQLite alloc] init];
[self.sqLite callDataBaseAndNoteTableMethods];
self.noteButtonArrayy = [[NSMutableArray alloc] init];
noteButtonArrayy = [self.sqLite returnDataFromNoteTable:noteToken];
[self LoadNoteButtonAndDeleteButton:noteButtonArrayy];
}
//////////////*----------------------- Note Section (Down) -----------------------*//////////////
-(void) LoadNoteButtonAndDeleteButton:(NSMutableArray *) noteButtonArray
{
sQLiteClass = [[SQLiteClass alloc] init];
noteButtonArrayToShowNoteButton = [[NSMutableArray alloc] init];
/*--------------- Load the noteButton & pass note (Down)---------------*/
for (int i = 0; i < [noteButtonArray count]; i++)
{
sQLiteClass = [noteButtonArray objectAtIndex:i];
// NSString *ids = [NSString stringWithFormat:#"%d", sQLiteClass.idNum];
NSString *nt = sQLiteClass.note;
[noteButtonArrayToShowNoteButton addObject:nt];
}
[self ShowNoteButtonMethod:noteButtonArrayToShowNoteButton];
/*--------------- Load the noteButton & pass note (Up)---------------*/
/*--------------- Load the deleteButton & pass id (Down)---------------*/
noteButtonArrayToDeleteNoteButton = [[NSMutableArray alloc] init];
for (int i = 0; i < [noteButtonArray count]; i++)
{
sQLiteClass = [noteButtonArray objectAtIndex:i];
// Convert int into NSString
NSString *ids = [NSString stringWithFormat:#"%d", sQLiteClass.idNum];
[noteButtonArrayToDeleteNoteButton addObject:ids];
}
[self ShowNoteDeleteButtonMethod:noteButtonArrayToDeleteNoteButton];
/*--------------- Load the deleteButton & pass id (Down)---------------*/
}
-(void) ShowNoteButtonMethod:(NSMutableArray *) btnarray
{
countNoteButtonArray = [btnarray count];
// For note button
noteButtonWidth = 60;
noteButtonXposition = 8;
for (NSString *urls in btnarray)
{
noteButtonXposition = [self addNoteButton:noteButtonXposition AndURL:urls];
}
}
-(int) addNoteButton:(int) xposition AndURL:(NSString *) urls
{
noteButton =[ButtonClass buttonWithType:UIButtonTypeCustom];
noteButton.frame = CGRectMake(noteButtonXposition, 8.0, noteButtonWidth, 60.0);
[noteButton setImage:[UIImage imageNamed:#"note.png"] forState:UIControlStateNormal];
[noteButton addTarget:self action:#selector(tapOnNoteButton:) forControlEvents:UIControlEventTouchUpInside];
[noteButton setUrl:urls];
noteButton.backgroundColor = [UIColor clearColor];
[self.scrollViewNote addSubview:noteButton];
noteButtonXposition = noteButtonXposition + noteButtonWidth + 18;
return noteButtonXposition;
}
-(void)tapOnNoteButton:(ButtonClass*)sender
{
urlNote = sender.url;
[self performSegueWithIdentifier:#"goToNoteDetailsViewController" sender:urlNote];
}
-(void) ShowNoteDeleteButtonMethod:(NSMutableArray *) btnarray
{
countNoteButtonArray = [btnarray count];
// For delete button
deleteNoteButtonWidth = 14;
deleteNoteButtonXposition = 31;
for (NSString *idNumber in btnarray)
{
deleteNoteButtonXposition = [self addDeleteButton:deleteNoteButtonXposition AndURL:idNumber];
}
}
-(int) addDeleteButton:(int) xposition AndURL:(NSString *) idNumber
{
deleteNoteButton =[ButtonClass buttonWithType:UIButtonTypeCustom];
deleteNoteButton.frame = CGRectMake(deleteNoteButtonXposition, 74.0, deleteNoteButtonWidth, 20.0);
[deleteNoteButton setImage:[UIImage imageNamed:#"delete.png"] forState:UIControlStateNormal];
[deleteNoteButton addTarget:self action:#selector(tapOnDeleteButton:) forControlEvents:UIControlEventTouchUpInside];
[deleteNoteButton setIdNum:idNumber];
deleteNoteButton.backgroundColor = [UIColor clearColor];
[self.scrollViewNote addSubview:deleteNoteButton];
deleteNoteButtonXposition = deleteNoteButtonXposition + deleteNoteButtonWidth + 65;
return deleteNoteButtonXposition;
}
-(void)tapOnDeleteButton:(ButtonClass*)sender
{
idNumb = sender.idNum;
[self.sqLite deleteData:[NSString stringWithFormat:#"DELETE FROM note WHERE id IS '%#'", idNumb]];
// NSLog(#"idNumb %#", idNumb);
//[self.view setNeedsDisplay];
//[self.view setNeedsLayout];
//[self LoadNoteButtonAndDeleteButton];
//[self viewDidLoad];
// if ([self isViewLoaded])
// {
// //self.view = Nil;
// //[self viewDidLoad];
// [self LoadNoteButtonAndDeleteButton];
// }
}
//////////////*----------------------- Note Section (Up) -----------------------*//////////////
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"goToNoteDetailsViewController"])
{
NoteDetailsViewController *noteDetailsViewController = [segue destinationViewController];
[noteDetailsViewController setUrl:sender];
}
}
Here's the screen shot:
Here we can feel the difference between UIScrollView and UICollectionView, however UICollectionView is made up of UIScrollView, UICollectionView can be reload and adjust its content accordingly, where UIScrollView can't.
Ok, now in your case, you've to reload (refresh) your scroll view, which is not possible as we can with UICollectionView or UITableView.
You've two options,
Best option (little tough) : replace UIScrollView with UICollectionView - will take some of your time, but better for reducing code complexity and good performance of your app.
Poor option (easy) : Stay as it with UIScrollView - when you want to reload, delete each subview from it, and then again show and load everything. Highly not recommended.
IMHO, you should go with best option.

i want show different images continuously without user touch the button

when the user touch the button the below code show the image.i want show different images like "bear,cat,cow,dog" continuously without user touch the button.can any one help me.
NSMutableArray *dashBoy = [NSMutableArray array];
for (i = 1; i<= 12; i++)
{
butterfly = [NSString stringWithFormat:#"bear_%d.png", i];
if ((image = [UIImage imageNamed:butterfly]))
[dashBoy addObject:image];
}
[stgImageView setAnimationImages:dashBoy];
[stgImageView setAnimationDuration:4.0f];
[stgImageView setAnimationRepeatCount:2];
[stgImageView startAnimating];
You could do as below:-
Firstly, create a UIImageView property like below,
#property (nonatomic,weak) IBOutlet UIImageView *imageView; //Also connect it with storyboard or xib.
Then you could write down IBAction as follow:-
- (IBAction)startTap:(id)sender {
[self.imageView setAnimationDuration:1.0f]; //You could change the duration for making animation fast or slow.
[self.imageView setAnimationImages:imageArray]; //imageArray is NSArray of images of which you want to show slide show.
[self.imageView startAnimating]; //simply to start animation.
}
- (IBAction)stopTap:(id)sender {
[self.imageView stopAnimating]; //To stop animation.
}
try this..
create two instance objects like
NSMutableArray * imagesArray; and UIImageView *animationImageView;
-(void)viewDidLoad
{
NSArray *imageNames = #[#"img1.png", #"img2.png", #"img3.png", #"img4.png",#"img5.png"];
imagesArray = [[NSMutableArray alloc]init];
NSMutableArray *images = [[NSMutableArray alloc] init];
for (int i = 0; i < imageNames.count; i++)
{
[imagesArray addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
animationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 95, 86, 193)];
animationImageView.animationImages = imagesArray;
animationImageView.animationDuration = 0.5; // set your own
[self.view addSubview:animationImageView];
}
and to start and stop two UIButton Actions
-(IBAction)startAnimation:(UIButton*)sender
{
[animationImageView startAnimating];
}
-(IBAction)stopAnimation:(UIButton*)sender
{
[animationImageView stopAnimating];
}

Controlling Load Ordering of UICollectionView cells with dispatch_async

In my iOS app, I have a UICollectionView where each cell contains an image. To prevent the view from taking a long time to load, I load each with a blank image and title before loading the image contents in a background task.
I logged which images are getting loaded through in the background async task, and it seems like the images of cells off screen get loaded first, followed by the cells at the top of the screen. This makes the app seem unresponsive, and I'd rather have the cells at the top take priority in terms of loading:
I also notice that once I start scrolling, the images in the cells suddenly start appearing, but they take much longer to appear on their own. Can anyone suggest strategies to control the ordering that UICollectionCells load in?
Here is my code:
Iterate over projects and add imageViews to an NSMutableArray projectContainers, which then gets turned into cells
for (NSDictionary *currentProject in projects)
{
// data entry
[projectIDs addObject: [currentProject objectForKey:#"id"]];
NSString *projectTitle = [currentProject objectForKey:#"title"];
id delegate = [[UIApplication sharedApplication] delegate];
self.managedObjectContext = [delegate managedObjectContext];
CustomLabel *cellLabel=[[CustomLabel alloc]init];
cellLabel.text = trimmedProjectTitle;
[titles addObject:projectTitle];
CGSize maxLabelSize = CGSizeMake(cellWidth,100);
CustomLabel *titleLabel = [[CustomLabel alloc]init];
// titleLabel styling
titleLabel.backgroundColor = [[UIColor blackColor]colorWithAlphaComponent:0.5f];
titleLabel.textColor =[UIColor whiteColor];
[titleLabel setFont: [UIFont fontWithName: #"HelveticaNeue" size:12]];
titleLabel.text = trimmedProjectTitle;
CGSize expectedLabelSize = [titleLabel.text sizeWithFont:titleLabel.font constrainedToSize:maxLabelSize lineBreakMode:NSLineBreakByWordWrapping];
CGRect labelFrame = (CGRectMake(0, 0, cellWidth, 0));
labelFrame.origin.x = 0;
labelFrame.origin.y = screenWidth/2 - 80 - expectedLabelSize.height;
labelFrame.size.height = expectedLabelSize.height+10;
titleLabel.frame = labelFrame;
// add placeholder image with textlabel
UIImageView *imagePreview = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, cellWidth, cellHeight)];
imagePreview.contentMode= UIViewContentModeScaleAspectFill;
imagePreview.clipsToBounds = YES;
[imagePreview setImage:[UIImage imageNamed:#"blank.png"]];
[imagePreview addSubview:titleLabel];
[imagePreview.subviews[0] setClipsToBounds:YES];
[projectContainers addObject: imagePreview];
// add project thumbnail images in async
dispatch_async(bgQueue, ^{
NSDictionary *imagePath = [currentProject objectForKey:#"image_path"];
NSString *imageUrlString = [imagePath objectForKey: #"preview"];
NSURL *imageUrl = [NSURL URLWithString: imageUrlString];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:(imageUrl)];
UIImage *image = [[UIImage alloc] initWithData:(imageData)];
if(image){
NSLog(#"project with image: %#", projectTitle);
[imagePreview setImage: image];
}
BOOL *builtVal = [[currentProject objectForKey:#"built"]boolValue];
if(builtVal){
UIImageView *builtBanner =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"built_icon.png"]];
builtBanner.frame = CGRectMake(screenWidth/2 -80, 0, 50, 50);
[imagePreview addSubview: builtBanner];
}
});
}
renders cells using the NSMutableArray projectContainers:
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
// NSLog(#"cellForItemAtIndexPath");
static NSString *identifier = #"NewCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
if(!reloadProjects){
UIImageView *preview = (UIImageView*) [cell.contentView viewWithTag:[[projectIDs objectAtIndex:indexPath.row]intValue]];
UIImageView *previewContent = [projectContainers objectAtIndex:indexPath.row];
// NSLog(#"fetching image tag %d", [[projectIDs objectAtIndex:indexPath.row]intValue]);
if (!preview)
{
previewContent.tag = [[projectIDs objectAtIndex:indexPath.row]intValue];
// NSLog(#"creating previewContent %li", (long) previewContent.tag);
[cell addSubview: previewContent];
}
[self.collectionView setBackgroundColor:collectionGrey];
cell.contentView.layer.backgroundColor = [UIColor whiteColor].CGColor;
return cell;
}
return cell;
}
EDIT: Working Solution
Thanks to rob mayoff for helping me come out with a solution. This is what I ended up doing, which loads the images much faster:
// add project thumbnail images in async
dispatch_async(imageQueue, ^{
NSDictionary *imagePath = [currentProject objectForKey:#"image_path"];
NSString *imageUrlString = [imagePath objectForKey: #"preview"];
NSURL *imageUrl = [NSURL URLWithString: imageUrlString];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:(imageUrl)];
UIImage *image = [[UIImage alloc] initWithData:(imageData)];
if(image){
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"project with image: %#", projectTitle);
[imagePreview setImage: image];
});
}
BOOL *builtVal = [[currentProject objectForKey:#"built"]boolValue];
if(builtVal){
UIImageView *builtBanner =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"built_icon.png"]];
builtBanner.frame = CGRectMake(screenWidth/2 -80, 0, 50, 50);
dispatch_async(dispatch_get_main_queue(), ^{
[imagePreview addSubview: builtBanner];
});
}
});
There are several things that code be improved in your code, but your chief complaint (“once I start scrolling, the images in the cells suddenly start appearing, but they take much longer to appear on their own”) is because you violated the commandment:
Thou shalt only access
thy view hierarchy
from the main thread.
Look at your code:
dispatch_async(bgQueue, ^{
...
[imagePreview addSubview: builtBanner];
You're manipulating the view hierarchy from a background thread. This is not allowed. For example, see the note at the bottom of this page, or the “Threading Considerations” in the UIView Class Reference.
You need to dispatch back to the main thread to update the view hierarchy.
Watch the Session 211 - Building Concurrent User Interfaces on iOS video from WWDC 2012. It talks in depth about how to do what you're trying to do, efficiently. See also this answer.

Loading images into a UIScrollView

I'm hoping somebody can help me out here, I'm not sure what else to do. I have a UIScrollView that loads a set of 44 images, and then allows the user to page through them. My code was working, then suddenly it stopped. I have no idea what I have changed so any help would be much appreciated:
The previous view is a UITableView, it passes a string along with the name of the cell that was selected. Here is the ViewDidLoad Method from the ScrollView:
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:#"Answer"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(answerPressed:)];
self.navigationItem.rightBarButtonItem = rightButton;
if([questionSetName isEqualToString:#"Limitations"]){
[self limitationsView];
}
}
Here is the limitationsView:
-(void)limitationsView{
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, -44, self.view.frame.size.width, self.view.frame.size.height)];
scroll.pagingEnabled = YES;
NSArray *unsortedArray = [[NSBundle mainBundle] pathsForResourcesOfType:#"png" inDirectory:#"Images/Limitations"];
NSMutableArray *limitationImages = [[NSMutableArray alloc] init];
for (int x = 0; x<[unsortedArray count]; x++) {
NSString *fileName = [[unsortedArray objectAtIndex:x] lastPathComponent];
[limitationImages insertObject:fileName atIndex:x];
}
NSArray *sortedArray = [limitationImages sortedArrayUsingFunction:finderSortWithLocal
context:(__bridge void *)([NSLocale currentLocale])];
for(int i = 0; i< [sortedArray count]; i++){
CGFloat xOrigin = i * self.view.bounds.size.width;
UIImageView *limitationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(xOrigin, 0, self.view.frame.size.width, self.view.frame.size.height)];;
[limitationImageView setImage:[UIImage imageNamed:[sortedArray objectAtIndex:i]]];
limitationImageView.contentMode = UIViewContentModeScaleAspectFit;
[scroll addSubview:limitationImageView];
}
scroll.contentSize = CGSizeMake(self.view.frame.size.width * [sortedArray count], self.view.frame.size.height);
[self.view addSubview:scroll];
}
When I get to the end of the LimitationsView method the sortedArray contains all 44 images, and the proper names, if I try and set the background color of the scrollview I can successfully do that. but my images are not loading and I am at a loss as to why?
I would suggest using
NSLog(#"image:%#",[UIImage imageNamed:[limitationsArray objectAtIndex:i]]);
to see if the image is null at that point. If that's the case, then there is a problem with the strings you are storing in that array i.e., they are not identical to the actual names of your images

Resources