I've implemented a scrollview with paging to scroll between some images (graphs) at full page (like the Photo app installed in the iPhone).
I found the code below that use the classical 3 pages solution (I made some small modification for my application) but, even if it "works", the scrolling seems to be slow and often after I've scrolled some images the application crashes.
I'm using Xcode 4.2 with ARC option enabled and testing both on an iPad device.
Images (10 jpg) are 2048x1539 with a mean dimension of 200/250Kb each.
Is there anyone that can help me in finding the cause of the problem ?
Thanks,
Corrado
const int numImages = 10;
const float kPageWidth = 1024.0f;
const float kPageHeight = 768.0f;
- (void)viewDidLoad {
[super viewDidLoad];
scroll.contentSize = CGSizeMake(kPageWidth * numImages, kPageHeight);
imageview1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kPageWidth, kPageHeight)];
imageview2 = [[UIImageView alloc] initWithFrame:CGRectMake(kPageWidth, 0, kPageWidth, kPageHeight)];
imageview3 = [[UIImageView alloc] initWithFrame:CGRectMake(kPageWidth * 2, 0, kPageWidth, kPageHeight)];
scroll.contentOffset = CGPointMake(0, 0);
[imageview1 setImage:[UIImage imageNamed:#"grafico_0.jpg"]];
imageview1.contentMode = UIViewContentModeScaleAspectFit;
[imageview1 setTag:1];
imageview2.contentMode = UIViewContentModeScaleAspectFit;
[imageview2 setTag:2];
imageview3.contentMode = UIViewContentModeScaleAspectFit;
[imageview3 setTag:3];
[scroll addSubview:imageview1];
[scroll addSubview:imageview2];
[scroll addSubview:imageview3];
}
- (void)scrollViewDidScroll:(UIScrollView*)scrollView {
const CGFloat currPos = scrollView.contentOffset.x;
const NSInteger selectedPage = lroundf(currPos * (1.0f / kPageWidth));
const NSInteger zone = 1 + (selectedPage % 3);
const NSInteger nextPage = selectedPage + 1;
const NSInteger prevPage = selectedPage - 1;
/// Next page
if (nextPage < numImages)
{
NSInteger nextViewTag = zone + 1;
if (nextViewTag == 4)
nextViewTag = 1;
UIImageView* nextView = (UIImageView*)[scrollView viewWithTag:nextViewTag];
nextView.frame = (CGRect){.origin.x = nextPage * kPageHeight, .origin.y = 0.0f, kPageHeight, kPageWidth};
NSString *str = [NSString stringWithFormat:#"grafico_%d.jpg", nextPage];
UIImage* img = [UIImage imageNamed:str];
nextView.image = img;
}
/// Prev page
if (prevPage >= 0)
{
NSInteger prevViewTag = zone - 1;
if (!prevViewTag)
prevViewTag = 3;
UIImageView* prevView = (UIImageView*)[scrollView viewWithTag:prevViewTag];
prevView.frame = (CGRect){.origin.x = prevPage * kPageHeight, .origin.y = 0.0f, kPageHeight, kPageWidth};
NSString *str = [NSString stringWithFormat:#"grafico_%d.jpg", prevPage];
UIImage* img = [UIImage imageNamed:str];
prevView.image = img;
}
}
You should not use imageNamed: for the loading of your large images, because that method caches the images and should only be used for small images that you use multiple times in your App (like images for buttons etc.). That method is notorious for causing memory problems when used with many large images.
Switch to imageWithContentsOfFile: instead. Loading your images with that methods secures that the images are not cached and the memory is freed after you do not use that images any more.
If the scrolling seems to be sluggish you can move the loading of the image to a background thread using performSelectorInBackground:
[self performSelectorInBackground:#selector(retrieveImageData:) withObject:imagePath];
the loading of the UIImage happens in this method:
- (void)retrieveImageData:(NSString *)imagePath {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
[self performSelectorOnMainThread:#selector(imageDataRetrieved:) withObject:image waitUntilDone:NO];
[pool release];
}
and the attachment of the image to the UIImageView on the main thread (UI manipulations must not happen on a background Thread):
- (void)imageDataRetrieved:(UIImage)*image {
yourImageView.image = image;
}
Related
I am implementing a sliding image demo on UITableView, and also I am using UIPageControl for that. When I slide image on first row, the page control changes properly but when I slide image of second row page control starts from where it was left at first row.
Here is my code
-(void)seePhotosBtnClicked:(UIButton *)sender
{
photoView.hidden = NO;
CGPoint touchPoint = [sender convertPoint:CGPointZero toView:addressTable]; // maintable --> replace your tableview name
NSIndexPath *clickedButtonIndexPath = [addressTable indexPathForRowAtPoint:touchPoint];
NSString *areaToSearch = [[addressInfoArray valueForKey:#"IMAGEPATH"]objectAtIndex:clickedButtonIndexPath.row];
NSArray *urlArray = [areaToSearch componentsSeparatedByString: #","];
for (int i = 0; i<=2; i++)
{
NSURL *imageURL = [NSURL URLWithString:[urlArray objectAtIndex:i]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
CGRect frame;
frame.origin.x =pagedScrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = pagedScrollView.frame.size;
UIImageView *imgView=[[UIImageView alloc]initWithFrame:frame];
imgView.image = image;
[pagedScrollView addSubview:imgView];
}
pagedScrollView.contentSize = CGSizeMake(pagedScrollView.frame.size.width * 3, pagedScrollView.frame.size.height);
[pageControl addTarget:self action:#selector(changePage:) forControlEvents:UIControlEventValueChanged];
}
- (void)changePage:(id)sender
{
// update the scroll view to the appropriate page
CGRect frame;
frame.origin.x = pagedScrollView.frame.size.width * pageControl.currentPage;
frame.origin.y = 0;
frame.size = pagedScrollView.frame.size;
[pagedScrollView scrollRectToVisible:frame animated:YES];
}
Got it, where you stop scrolling photos add this code.
pageControl.currentPage=0;
pagedScrollView.contentSize = CGSizeMake(0, pagedScrollView.frame.size.height);
Now your scrollview will start with first image and page control start with first tick
I am showing around 50 Images In a scroll view and I am facing the memory issue, every time the Controller loads the memory usage increases and it goes over 200MB in the Instruments App.
.h file of my custom class
#import
#class AnimalGrid;
#protocol AnimalGridViewDelegate <NSObject>
-(void)animalGrid:(AnimalGrid*)animalgridview tappedAtIndex:(int)index andName:(NSString*)animalName;
#end
#interface AnimalGrid : UIView
#property(nonatomic, strong) UIImage *animalImage;
#property(nonatomic, copy) NSString *animalName;
#property(nonatomic) int animalTag;
#property (nonatomic, assign) id <AnimalGridViewDelegate> Delegate;
-(id)initGridWithFrame:(CGRect)frame andAnimalImage:(UIImage*)image andAnimalName:(NSString*)animalname andTag:(int)tag;
-(void)setFont:(UIFont*)font;
#end
.m file of my Custom Class
#import "AnimalGrid.h"
#implementation AnimalGrid
{
UIImageView *_contentView;
UILabel *_accessoryView;
UIImage *displayImage;
NSString *displayText;
}
#synthesize Delegate = _Delegate;
-(id)initGridWithFrame:(CGRect)frame andAnimalImage:(UIImage*)image andAnimalName:(NSString*)animalname andTag:(int)tag
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.animalName = animalname;
self.animalTag = tag;
displayImage = image;
displayText = animalname;
CGFloat contentHeight = frame.size.height * 0.8;
if ( animalname == nil || animalname.length == 0)
contentHeight = frame.size.height;
CGFloat margin = 0;
if (displayImage.size.height < contentHeight)
{
margin = contentHeight - displayImage.size.height;
}
UIView *placeholderView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, contentHeight)];
placeholderView.backgroundColor = [UIColor clearColor];
if (image.size.height > placeholderView.frame.size.height)
{
_contentView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, placeholderView.frame.size.height)];
}else if (image.size.height < placeholderView.frame.size.height){
CGFloat margin = placeholderView.frame.size.height - image.size.height;
_contentView = [[UIImageView alloc]initWithFrame:CGRectMake(0, margin, frame.size.width, placeholderView.frame.size.height - margin)];
}
_contentView.backgroundColor = [UIColor clearColor];
_accessoryView = [[UILabel alloc]initWithFrame:CGRectMake(0, frame.size.height * 0.7, frame.size.width, frame.size.height-frame.size.height * 0.7)];
_accessoryView.numberOfLines = 2;
_accessoryView.backgroundColor = [UIColor clearColor];
_accessoryView.font = [UIFont fontWithName:#"HFFAirApparent" size:23];
_accessoryView.textColor = [UIColor orangeColor];
[placeholderView addSubview:_contentView];
[self addSubview:placeholderView];
if ( animalname != nil || animalname.length > 0)
[self addSubview:_accessoryView];
if(image)
_contentView.image = image;
_contentView.contentMode = UIViewContentModeScaleAspectFit;
_accessoryView.text = animalname;
_accessoryView.numberOfLines = 0;
[_accessoryView sizeToFit];
CGFloat w = self.bounds.size.width/2;
_accessoryView.frame = CGRectMake(w - (_accessoryView.frame.size.width/2), _accessoryView.frame.origin.y, _accessoryView.frame.size.width, _accessoryView.frame.size.height);
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapedOnImage:)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[_contentView addGestureRecognizer:singleTap];
_contentView.userInteractionEnabled = YES;
self.userInteractionEnabled = YES;
}
return self;
}
-(void)setFont:(UIFont*)font
{
_accessoryView.font = font;
}
-(void)tapedOnImage:(id)sender
{
if ([_Delegate respondsToSelector:#selector(animalGrid:tappedAtIndex:andName:)]) {
[_Delegate animalGrid:self tappedAtIndex:self.animalTag andName:self.animalName];
}
}
#end
And this is how I am creating the Object of my custom class and showing them over Scroll View, In my Controller file I am using following methods
-(void)setGridAnimals
{
#try {
[self creatingGridsWithCompletion:^(BOOL done, NSMutableArray *arr)
{
for (int i = 0; i < arr.count; i++)
{
UIView *gView = [arr objectAtIndex:i];
[gridScrollView addSubview:gView];
}
gridScrollView.scrollEnabled = YES;
gridScrollView.pagingEnabled = YES;
gridScrollView.bounces = YES;
gridScrollView.contentSize = CGSizeMake(gridScrollView.frame.size.width, gridScrollView.frame.size.height*arr.count);
[aView hideIndicatorView:YES];
}];
}
#catch (NSException *exception) {
NSLog(#" Exception is = %# ",exception.description);
}
#finally {
}
}
-(void)creatingGridsWithCompletion:(completionBlock)complete
{
#autoreleasepool {
NSMutableArray *pageArray = [NSMutableArray new];
int rowcount = 3;
int columncount = 5;
CGFloat width = gridScrollView.frame.size.width/columncount - 5;
CGFloat height = gridScrollView.frame.size.height/rowcount - 5;
int pagecount = gridAnimalArray.count/(rowcount*columncount);
if (gridAnimalArray.count%(rowcount*columncount))
{
pagecount += 1;
}
//pagecount = 1;
int x = 0;
for (int i = 0; i < pagecount; i++)
{
UIView *page = [[UIView alloc]initWithFrame:CGRectMake(0, x, gridScrollView.frame.size.width, gridScrollView.frame.size.height)];
for (int j = 0; j < rowcount; j++)
{
for (int k = 0; k < columncount; k++)
{
int tag = (i*(rowcount*columncount))+(j*columncount)+k+1;
if (tag > gridAnimalArray.count)
{
break;
}
YEAnimal *animal = [gridAnimalArray objectAtIndex:tag-1];
NSString *name = [[animal.GridName componentsSeparatedByString:#"."] objectAtIndex:0];
UIImage *gridImg;
if ([[NSFileManager defaultManager]fileExistsAtPath:[[NSBundle mainBundle] pathForResource:name ofType:#"png"]])
{
NSString * imgpath= [ [ NSBundle mainBundle] pathForResource:name ofType:#"png"];
gridImg=[UIImage imageWithContentsOfFile: imgpath];
}else if ([[NSFileManager defaultManager]fileExistsAtPath:[[NSBundle mainBundle] pathForResource:name ofType:#"jpg"]])
{
NSString * imgpath= [ [ NSBundle mainBundle] pathForResource:name ofType:#"jpg"];
gridImg=[UIImage imageWithContentsOfFile: imgpath];
}
AnimalGrid *grid = [[AnimalGrid alloc]initGridWithFrame:CGRectMake((k * width)+5, (j*height), width, height) andAnimalImage:gridImg andAnimalName:animal.SpeciesName andTag:tag];
grid.backgroundColor = [self getColor];
[grid setDelegate:self];
[page addSubview:grid];
}
}
[pageArray addObject:page];
x += gridScrollView.frame.size.height;
}
complete(YES,pageArray);
}
}
This is how the Grid Looks : http://s17.postimg.org/x9xdfl4j3/i_OS_Simulator_Screen_Shot_Mar_3_2015_1_54_45_P.png
So, far I came to know that I should use [UIImage imageWithContentsOfFile:] instead of [UIImage imageNamed:] to load the image, but still it does not help me.
Is there any way that I can free the Memory by releasing the ImageViews
Thanks.
There are several aproaches possible, depending on the layout of your view. How does it look like?
However, you can use a table to display the pictures in or use a collection. Actually a collection is made for that.
If you want to stick with the scroll view, then these 50 views are hardly visible at once. You could actually set their images just before the each view comes into sight and remove the images (set .image to nil) when the view moves off screen.
An App that I made recenly it is designed in a way that only one and exactly one of the images is visible full screen. When the user scrolls its neighbour image comes into view. (paging mechanism)
In my view the number of possible views is inpredictable. Although that is achievable with a collection too, I went for a scroll view.
In that view I designed the hosting scroll view in a way that it is just large enough to hold three views. The middle view of them is visible on screen. (Which exceptions applied when the very first or last - if any - view is displayed).
When the users scrolls just far enough for the neighbour view to be fully visible then I reset the scrollview so that its middle is visible again, move the view to the middle that just became visible, move the formerly visible view to the outer end and fill the other incoming end with a new view.
That allows for endless scrolling with not need to hold more than 4 images in memory at once. (4: the one that just moved off, the two that are shifted within the scroll view and the new one are allocated within the same method at a time.)
I am interested in obtaining an animation that not only animates from point A to point B but also changes the background image.
Say the initial position is 0,0 and the finis one is 0,100 ; the duration is 1 second, and i have 4 images for the background, then i want the background to change every 0/4 seconds and 25 px.
Until now I have the next code that animates the images but i still need to implement the movement and I don't know how to do just that.
Thanks in advance and here is what code I have until now:
UIImageView * animatedImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 50,50)];
testArray = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"test_1.png"], [UIImage imageNamed:#"test_2.png"], [UIImage imageNamed:#"test_3.png"],nil];
animTime =3.0;
[animatedImageView setAnimationImages:testArray] ;
animatedImageView.animationDuration = animTime;
animatedImageView.animationRepeatCount = 1;
[self.view addSubview: animatedImageView];
[animatedImageView startAnimating];
UPDATE:
I have implemented the answer of Mobile Project Lab into my code
// I have a pathArray that is in C style and is bidimensional, that stores the path in reverse
// the maps is a 2d tile map
// the dimensions of the tiles are 64x64 px
//thes size of the character is 128x128
for (int possitionInThePathArray = sizeOfPathArray - 1; possitionInThePathArray >= 0; possitionInThePathArray--) {
xWalkingDirection = pathArray[possitionInThePathArray-1][1] - pathArray[possitionInThePathArray][1];
yWalkingDirection = pathArray[possitionInThePathArray-1][0] - pathArray[possitionInThePathArray][0];
if (xWalkingDirection== 0 && yWalkingDirection == -1){
//walking animation to North for 1 tile
NSArray *testArray;
float animTime;
testArray = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"scientist_s0.png"],
[UIImage imageNamed:#"scientist_s1.png"],
[UIImage imageNamed:#"scientist_s2.png"],
[UIImage imageNamed:#"scientist_s3.png"],
[UIImage imageNamed:#"scientist_s4.png"],
[UIImage imageNamed:#"scientist_s5.png"],
[UIImage imageNamed:#"scientist_s6.png"],
[UIImage imageNamed:#"scientist_s7.png"],
[UIImage imageNamed:#"scientist_s8.png"],
[UIImage imageNamed:#"scientist_s9.png"], nil]; // 4th image added
animTime = 10.0; // time is changed to 10.0
[myCharacterFrame setAnimationImages:testArray];
myCharacterFrame.animationDuration = animTime;
myCharacterFrame.animationRepeatCount = 1;
[myCharacterFrame startAnimating];
[UIView animateWithDuration:animTime
animations:^{
myCharacterFrame.frame = CGRectOffset(myCharacterFrame.frame, 0.0f, -64.0f); // move 100 on x axis, 0 on y axis
}
completion:^(BOOL finished){
NSLog(#"animation done");
}];
yMyCharacterFrame = yMyCharacterFrame-64.0;
myCharacterFrame.frame = CGRectMake(xMyCharacterFrame, yMyCharacterFrame, 128, 128);
myCharacterFrame.image = [UIImage imageNamed:#"scientist_s0.png"];
}else if (xWalkingDirection== 1 && yWalkingDirection == 0){
//walking animation to Est for 1 tile
.....
//and so on for all the four directions of walking
The issue that I am facing now is that the animation are not triggered correctly, so that one animation takes places before the code moves on
NSArray *testArray;
float animTime;
UIImageView *animatedImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
testArray = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"test_001.png"], [UIImage imageNamed:#"test_002.png"],[UIImage imageNamed:#"test_001.png"], [UIImage imageNamed:#"test_002.png"], nil]; // 4th image added
animTime = 1.0; // time is changed to 1.0
[animatedImageView setAnimationImages:testArray];
animatedImageView.animationDuration = animTime;
animatedImageView.animationRepeatCount = 1;
[self.view addSubview: animatedImageView];
[animatedImageView startAnimating];
[UIView animateWithDuration:animTime
animations:^{
animatedImageView.frame = CGRectOffset(animatedImageView.frame, 100.0f, 0.0f); // move 100 on x axis, 0 on y axis
}
completion:^(BOOL finished){
NSLog(#"animation done");
}];
I'm creating some kind of image gallery. User can swipe between photo's. (Its just the concept, i know there are good library's out there that can handle this, but it's just to explain the concept).
I'm loading in 3 UIImageView, and i'm constantly reusing them. (Lazy loading). Problem is, when i change the image dynamiccaly from one imageview, and keep changing it, the memory is filling up. It's like it does not releases previous attached images. I'm using an array of UIImages that I already downloaded from some kind of web service.
As i load my view, i'm allocing and init my UIImageView, then I add it to the view.
UIImageView* _imgView;
NSArray* _imgArray;
So this array contains UIImage
-(void)changeImageIndex: (int) i
{
_imgView.image = [_imgArray objectAtIndex:i];
}
if i keep changing the imageindex, memory just gets filled up and filled up.. :s.
My project is ARC enabled.
Somebody has a clue how to solve it?
The image is added (actually changed) by this method:
-(void)setCurrentMovie:(GFilm*)film
{
_currentMovie = nil;
_currentMovie = film;
_posterView.image = nil;
[_youtubeView loadHTMLString:#"" baseURL:nil];
[_youtubeView stopLoading];
[_youtubeView setDelegate:nil];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[_scrollView setContentOffset:CGPointMake(0, 0) animated:NO];
CGFloat leftHeight = 0.f;
_leftView.frame = CGRectMake(10, 10, 110, 205);
leftHeight += _leftView.frame.size.height;
_posterView.frame = CGRectMake(0, 0, _leftView.frame.size.width, _leftView.frame.size.height - 40);
GImage* img = (GImage*)[_currentMovie.imageList objectAtIndex:0];
//_posterView.image = img.localImage;
//#autoreleasepool {
_posterView.image = [UIImage imageWithData:UIImagePNGRepresentation(img.localImage)];
_btnVertoningen.frame = CGRectMake(0, _posterView.frame.origin.y + _posterView.frame.size.height + 5, _leftView.frame.size.width, 35);
_posterView.userInteractionEnabled = YES;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(posterClick)];
singleTap.numberOfTapsRequired = 1;
[_posterView addGestureRecognizer:singleTap];
[_leftView addSubview:_posterView];
CGFloat rightHeight = 0.f;
_rightView.frame = CGRectMake(_leftView.frame.origin.x + _leftView.frame.size.width + 5, _leftView.frame.origin.y, self.view.frame.size.width - (_leftView.frame.size.width + _leftView.frame.origin.x) - 15, 1);
_lblRegie.frame = CGRectMake(0, rightHeight, 48, 16);
NSMutableString* text = [[NSMutableString alloc]init];
NSArray* arr = _currentMovie.directorList;
etc.....
}
Probably your app have memory leak. Try use imageWithContentsOfFile instead of imageNamed:
_imgView.image = [UIImage imageWithContentsOfFile:imagePath];
Another possibility to have memory leaks with ARC is using a separate thread without an autorelease pool set up. Check this link:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html:
I'm having trouble getting my head around this; I've looked around for answers on here but either nothing directly applies to my question or I just can't make sense of it. (I am relatively new to this, so apologise if there is an obvious answer.)
I am inserting an array of UIImages (contained within a UIImageView) into a UIScrollView. I can programmatically scroll to points in the ScrollView, but I need to be able to identify by name which image is currently being shown after scrolling (so I can compare the image to one in another ScrollView).
How I have created my arrays and added the images to the ImageView and ScrollView is below.
ViewController.m
-(void)viewDidLoad {
...
// Store the names as strings
stringArr = [[NSMutableArray arrayWithObjects:
#"img0",
#"img1",
#"img2",
#"img3",
nil] retain];
// Add images to array
dataArr = [[NSMutableArray arrayWithObjects:
[UIImage imageNamed:[stringArr objectAtIndex:0]],
[UIImage imageNamed:[stringArr objectAtIndex:1]],
[UIImage imageNamed:[stringArr objectAtIndex:2]],
[UIImage imageNamed:[stringArr objectAtIndex:3]],
nil] retain];
// Use a dictionary to try and make it possible to retrieve an image by name
dataDictionary = [NSMutableDictionary dictionaryWithObjects:dataArr forKeys:stringArr];
i = 0;
currentY = 0.0f;
// Set up contents of scrollview
// I'm adding each of the four images four times, in a random order
for (imageCount = 0; imageCount < 4; imageCount++) {
// Add images from the array to image views inside the scroll view.
for (UIImage *image in reelDictionary)
{
int rand = arc4random_uniform(4);
UIImage *images = [dataArr objectAtIndex:rand];
imgView = [[UIImageView alloc] initWithImage:images];
imgView.contentMode = UIViewContentModeScaleAspectFit;
imgView.clipsToBounds = YES;
// I have tried to use this to tag each individual image
imgView.tag = i;
i++;
CGRect rect = imgView.frame;
rect.origin.y = currentY;
imgView.frame = rect;
currentY += imgView.frame.size.height;
[scrollReel1 addSubview:reel1_imgView];
[reel1_imgView release];
}
}
scrollReel.contentSize = CGSizeMake(100, currentY);
[self.view addSubview:scrollReel];
...
}
This is how I am working out where I am in the ScrollView (currentOffset), and also exactly which image I need to retrieve (symbolNo). The value of symbolNo is correct when I test it, but I am unsure how to use the value with respect to image name retrieval.
NSInteger currentOffset = scrollReel.contentOffset.y;
NSInteger symbolNo = (currentOffset / 100) + 1;
Thanks in advance for any assistance.
There is no way to do this. The UIImage object doesn't store its name once it's loaded.
You could get around this by using the tag property on the image views if all your images have numerical names.
Otherwise you'll need to find a new way to model your data.
You basically need the reverse mapping of what you had. Here is a quick and dirty solution
NSMutableDictionary *indexToImageMap = [NSMutableDictionary new];
for (imageCount = 0; imageCount < 4; imageCount++) {
// Add images from the array to image views inside the scroll view.
for (UIImage *image in reelDictionary)
{
int rand = arc4random_uniform(4);
UIImage *images = [dataArr objectAtIndex:rand];
imgView = [[UIImageView alloc] initWithImage:images];
imgView.contentMode = UIViewContentModeScaleAspectFit;
imgView.clipsToBounds = YES;
// I have tried to use this to tag each individual image
imgView.tag = i;
i++;
[indexToImageMap setObject:imgView forKey:[NSNumber numberWithInt:i];
CGRect rect = imgView.frame;
rect.origin.y = currentY;
imgView.frame = rect;
currentY += imgView.frame.size.height;
[scrollReel1 addSubview:reel1_imgView];
[reel1_imgView release];
}
}
And to look it up you do
NSInteger currentOffset = scrollReel.contentOffset.y;
NSInteger symbolNo = (currentOffset / 100) + 1;
NSImage *image = [indexToImageMap objectForKey:[NSNumber numberWithInt:symbolNo]];
Subclass image view and add imageName property. if i understand what you are asking this should work.
#import <UIKit/UIKit.h>
#interface myImageView : UIImageView
{
__strong NSString *imageName;
}
#property (strong) NSString *imageName;
#end
#import "myImageView.h"
#implementation myImageView
#synthesize imageName;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
#end
then use a dictionary to keep everything instead of array + dictionary.
myImageView *imgView1 = [[myImageView alloc] init];
[imgView1 setImageName:#"image_name_here"];
[imgView1 setImage:[UIImage imageNamed:#"image_name_here"]];
NSMutableDictionary *dicti = [[NSMutableDictionary alloc] init];
[dicti setObject:imgView1 forKey:#"image_name_here_1"];
[dicti setObject:imgView2 forKey:#"image_name_here_2"];
[dicti setObject:imgView... forKey:#"image_name_here_..."];
when you find the imageView you can search image in dictionary. because you know name of the imageView now.