managing images in UIScrollView - iphone

i'm not understanding where in my code i write in the image names and in what order to appear. Here is my code
// 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:#"image%d.jpg", i];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
I have images that are titled "image0.jpeg, image1.jpg." how to i insert this into my code and order them in a certain way?

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html
use %d for signed int
and %u for unsigned

Your code snippet is already doing what you want - at least partially.
If you have an image numbered 0, then you need to start your loop with i = 0 instea of i = 1, and adjust the constraint appropriately:
for (NSUInteger i = 0; i < kNumImages; i++) {
NSString *imageName = [NSString stringWithFormat:#"image%u.jpg", i];
// create the image and insert into imageview
// add imageview to the containing view
}
The order is quite straight forward, as the images will be added 0, 1, 2.. and so forth

With the code from your first post, you create multiple (kNumImages, to be more specific) ImageViews, and load in them JPG files from your project directory, called "imageN.jpg", where N is integer between 1 and kNumImages.
To display these newly created views in your UIScrollView, you have to add them to it as subviews.
Something like
for (int i = 0; i < pageCount; i++) {
UIView *view = [pageViews objectAtIndex:i];
if (!view.superview)
[scrollView addSubview:view];
view.frame = CGRectMake(pageSize.width * i, 0, pageSize.width, pageSize.height);
}
The most straightforward way to do this is in UIScrollView's UIViewController. You may want to add them in some sort of collection (it's likely that the collection retains them, so don't forget to release the views, when you add them).
As you get more comfortable with your application, you may want to lazy-load the views or use simple UIViewControllers for the different images.
In iPhone OS 3.0 and above, there are significant improvements in UIScrollView, and you can find excellent code samples in the ScrollViewSuite tutorial project on ADC's iPhone section.

Related

How to assign values to images [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Alright, so I have 5 custom images total.
Heres the values I need to set each image to:
Image1 = 1
Image2 = 2
Image3 = 3
Image4 = 4
Image5 = 5
I need values assigned to these because I want to have xcode randomly place them on the view until it reaches a value of 50. So im assuming I need some kind of loop that adds up the values until 50 is reached?
How do I assign values to these images since it brings up a warning when trying to assign an int value to a UIImage. Also, on a side note what method would I use to randomly place the images on the view without overlapping?
Thanks for any and all help!
Your app will be placing UIImageViews, not UIImages onto a view. Like all UIView subclasses, UIImageView has an NSInteger tag property, but if I understand the problem correctly, I don't think you need that, either.
// add count randomly selected images to random positions on self.view
// (assumes self is a kind of UIViewController)
- (void)placeRandomImages:(NSInteger)count {
for (NSInteger i=0; i<count; ++i) {
UIImage *image = [self randomImage];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = [self randomFrameForImage:image];
[self.view addSubview:imageView];
// add a tag here, if you want, but I'm not sure what for
// imageView.tag = i;
}
}
// answer a random image from the app's bundle
// assumes the images are named image-x where x = 0..4
- (UIImage *)randomImage {
NSInteger imageNumber = arc4random() % 5;
NSString *imageName = [NSString stringWithFormat:#"image-%d", imageNumber];
return [UIImage imageNamed:imageName];
}
// answer a random position for the passed image, keeping it inside the view bounds
- (CGRect)randomFrameForImage:(UIImage *)image {
CGFloat imageWidth = image.width;
CGFloat imageHeight = image.height;
CGFloat maxX = CGRectGetMaxX(self.view.bounds) - imageWidth;
CGFloat maxY = CGRectGetMaxY(self.view.bounds) - imageHeight;
// random location, but always inside my view bounds
CGFloat x = arc4random() % (NSInteger)maxX;
CGFloat y = arc4random() % (NSInteger)maxY;
return CGRectMake(x,y,imageWidth,imageHeight);
}
If want to assign an arbitrary integer value, I would use the tag property on UIImageView.
NSInteger currentTag = 50;
while (currentTag > 0) {
UIImageView *imageView = [UIImageView alloc initWithImage:image];
imageView.tag = currentTag;
[self.view addSubView:imageView];
currentTag--;
}
Put the images into an NSArray then from NSHipster:
How Do I Pick a Random Element from an NSArray
Use arc4random_uniform(3) to generate a random number in the range of a non-empty array.
if ([array count] > 0) {
id obj = array[arc4random_uniform([array count])];
}

UIScrollview containing many images

I'm using UIScrollview in Xcode 4.6. I want to insert around 30 images into the scrollview. Within the storyboard I can't add this many as it doesn't actually let you scroll down on the storyboard to add more images, hence all the images overlap each other.
The answer is probably quite simple so sorry if this is a dumb question. How do I add this many images to the scrollview, is there a way to code it like in Android xml? Or is there anyway to not have the images overlap?
Also consider using a UITableView. It may be a more efficient way of handling that many images. You can load them as they're displayed, rather than all at once.
You won't want to do this in Interface Builder - that will make it a creation and maintenance nightmare.
Instead, do it in code. You'll want to Google UIScrollView tutorial to get started. It's really quite easy - much easier than dragging out a bunch of image views by hand.
So this is problem that I have solved before. There are a few ways that you could solve this I think the new preferred way at least in iOS 6.x you could opt to use UICollectionView.
UICollectionView View Apple Docs
This is a great tutorial site that has loads of helpful information
UICollectionView Tutorial
Also one solution I came up with was loading and placing the images manually. And then based on the size needed width wise I set my UIScrollView setcontentSize property.
//Clean Up and remove old buttons
for(int i=0; i < _localButtonArray.count; i++){
[(CategoryButton*)[_localButtonArray objectAtIndex:i] removeFromSuperview];
}
[_localButtonArray removeAllObjects];
CGFloat baseX = 10,
X = 0,
Y = 0;
int xPadding = 20,
yPadding = 12,
index = 0,
maxRow = 4,
maxCol = 4,
colCount = 0;
CGRect buttonFrame;
buttonFrame.size.height = 137;
buttonFrame.size.width = 137;
buttonFrame.origin.y = X;
buttonFrame.origin.x = Y;
for(int i = 0;i < _localInfoArray.count ; i++){
id object = [_localInfoArray objectAtIndex:i];
if(index >= maxRow){
index = 0;
X = baseX;
Y += buttonFrame.size.height + yPadding;
if(colCount >= (maxRow * maxCol)){
colCount=0;
baseX += 637;
Y = 0;
}
}
X = baseX + (index * (buttonFrame.size.width + xPadding));
index++;
colCount++;
buttonFrame.origin.x = X;
buttonFrame.origin.y = Y + yPadding;
/*
* Custom button class
*/
CategoryButton * categoryButton = [[CategoryButton alloc]initWithFrame:buttonFrame Object:object];
//Add action
[categoryButton addTarget:self action:#selector(categoryButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[categoryButton.titleLabel setNumberOfLines:3];
[categoryButton.titleLabel setLineBreakMode:NSLineBreakByWordWrapping];
[categoryButton.titleLabel setFont:[UIFont fontWithName:#"Helvetica-Bold" size:19]];
[categoryButton.titleLabel setTextAlignment:NSTextAlignmentCenter];
[categoryButton setMultipleTouchEnabled:NO];
[_localButtonArray addObject:categoryButton];
[self.view addSubview:categoryButton];
}
There is a lot of other code that isn't here, but laying out the page is handled here.
Even this isn't an optimal solution, but hopefully it will help you.
Best of luck ^_^

UIImage Frame Null in NSMutableArray

I am trying to display star rating images, and I have three star images: full star, half star and an unselected grey-ed out star.
I have an array which holds the stars: so for rating 4.5, it would hold 4 selected and 1 half. I am adding the same star objects into the array so that I do not have to create multiple instances of the stars. I have just three instances and in my calculations I am just using addObject on those three different images as follows:
for (int i = 0; i < ratingCount; i++) {
if (rating >= 1)
[self.imageViews addObject:self.selected];
else
[self.imageViews addObject:self.halfSelected];
rating--;
}
I am having an issue drawing these images. In a subsequent loop, I am trying to draw them out as follows:
for (int i = 0; i < self.imageViews.count; ++i) {
UIImageView *imageView = [self.imageViews objectAtIndex:i];
imageView.frame = CGRectMake(i * (5 + imageWidth), 0, imageView.frame.size.width, imageView.frame.size.height);
[self.view addSubview:imageView];
}
This crashes because imageView.frame is coming out as null. When I debugged it, it prints out null <0x00000000>. Why is the frame coming out as null? The images are not printing as null and I know that they are added to the array properly.
When removing imageView.frame, I also get an [UIImage superview]: unrecognized selector sent to instance 0x8644590
The images are instantiated using imageNamed in the init method. Would that cause an issue? Do they get allocated early? That should print null when trying to see the image in the debugger using po so I don't think that is the issue.
You're confusing a UIImage with a UIImageView. Your array contains images, which do not have frames, since they are not views.
You need a separate set of image views, which have the images assigned to them.

Preloading a UIImageView animation using objective c for the iphone

I have an animated image which works great. It consists of 180 high quality images and it plays fine and loops continuously. My problem is that the first time I load the view containing these images it takes a long time to load. Every subsequent time after that it loads immediately as I am assuming that the images have been cached or preloaded!!! I come from a flash background and as I am sure you aware preloaders are as common as muck so I don't feel this should be difficult to find but after countless googling I cannot find any good examples on preloading or any articles on why there is a delay and what to do about it.
So my question(s) is this:
Is there a checkbox in the info.plist to preload all my images at the start of the app?
How can you preload images and are there any simple example projects that I could look at?
Is this the best way to implement what is essentially a video but has been output to a png sequence?
Is there another method as viewDidLoad does not work as I expect it to do. It traces "FINISHED LOADING IMAGES" (see code below) but the view does not show for a second or two after the images have been loaded so if the view does not show until the images have loaded then neither will the UIActivityIndicatorView which is also in the same view.
How do you do event listening in objective c?
Below is the code in the viewDidLoad which I believe is fairly standard:
Any help is greatly appreciated as I am banging my head on a brick wall on something that seems so basic in ui development. Help :)
- (void)viewDidLoad {
[super viewDidLoad];
imageArray = [[NSMutableArray alloc] initWithCapacity:IMAGE_COUNT];
NSLog(#"START LOADING IMAGES");
// Build array of images, cycling through image names
for (int i = 0; i < IMAGE_COUNT; i++){
[imageArray addObject:[UIImage imageNamed: [NSString stringWithFormat:#"Main_%d.png", i]]];
}
animatedImages = [[UIImageView alloc] initWithFrame:CGRectMake(0,20,IMAGE_WIDTH, IMAGE_HEIGHT)];
animatedImages.animationImages = [NSArray arrayWithArray:imageArray];
animatedImages.animationDuration = 6.0;
animatedImages.animationRepeatCount = 0;
[self.view addSubview:animatedImages];
animatedImages.startAnimating;
[animatedImages release];
NSLog(#"FINISH LOADING IMAGES");
}
Cheers
M
In case someone finds this question, I have an answer, which is to pre-render the images like this.
NSMutableArray *menuanimationImages = [[NSMutableArray alloc] init];
for (int aniCount = 1; aniCount < 21; aniCount++) {
NSString *fileLocation = [[NSBundle mainBundle] pathForResource: [NSString stringWithFormat: #"bg%i", aniCount + 1] ofType: #"png"];
// here is the code to load and pre-render the image
UIImage *frameImage = [UIImage imageWithContentsOfFile: fileLocation];
UIGraphicsBeginImageContext(frameImage.size);
CGRect rect = CGRectMake(0, 0, frameImage.size.width, frameImage.size.height);
[frameImage drawInRect:rect];
UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// then add the resulting image to the array
[menuanimationImages addObject:renderedImage];
}
settingsBackground.animationImages = menuanimationImages;
I have tried multiple other methods of pre-loading images, and this is the only thing I've found that works.
My problem is that the first time I load the view containing these images it takes a long time to load. Every subsequent time after that it loads immediately as I am assuming that the images have been cached or preloaded
you are right at this point ...... as you are using method imageNamed: for this method document quotes.....
This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method loads the image data from the specified file, caches it, and then returns the resulting object.
so in my opinion, rather than doing following stuff in viewDidLoad, you should do it earlier where delay is of not considerable......
for (int i = 0; i < IMAGE_COUNT; i++)
{
[imageArray addObject:[UIImage imageNamed: [NSString stringWithFormat:#"Main_%d.png", i]]];
}
another approach
- (void)spinLayer:(CALayer *)inLayer duration:(CFTimeInterval)inDuration
direction:(int)direction
{
CABasicAnimation* rotationAnimation;
// Rotate about the z axis
rotationAnimation =
[CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
// Rotate 360 degress, in direction specified
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 * direction];
// Perform the rotation over this many seconds
rotationAnimation.duration = inDuration;
rotationAnimation.repeatCount = 100;
//rotationAnimation.
// Set the pacing of the animation
//rotationAnimation.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
// Add animation to the layer and make it so
[inLayer addAnimation:rotationAnimation forKey:#"rotationAnimation"];
}
this method will help in animation call it as follow(I am assuming that you are putting above method in same class where you have imageView.
[self spinLayer:yourImageView.layer duration:5.0
direction:<-1 or 1 for anti clockwise or clockwise spin>];
remember just set only one image to that imageView(which you wish to animate.
thanks,

Loading more than 10 images on iPhone?

I'm trying to add more than 10 pictures on ScrollView.
NSUInteger i;
for (i = 1; i <= numberOfImage; i++)
{
NSString *imageName = [NSString stringWithFormat:#"d%dimage%d.png", imageSection, 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
[scrollView addSubview:imageView];
[imageView release];
}
This code is from Apple example and it works fine. But if the variable 'i' is bigger than 10, 'UIImage *image' is empty. The imageName seems to correct. But I don't know why it does not load image. Does anybody sees the problem??
And one more thing. If I do like that, does iOS controls memory automatically? I mean it's kind of wasting memory if all (more than 10) images are loaded on memory even they are not displayed. I've heard that iOS loads images only displayed on screen and free images those are not displayed. Is that right?
Thanks for reading.
UIimage imageNamed: does cache file contents. I recommend you to use UIImage +imageWithContentsOfFile: that doesn't cache at all in such situation.
You have to make sure the images have the correct name (like 0dimage11.jpg) and are added to the XCode project.
You probably have to set the contentSize accordingly.
IOS will not do that magic memory management thing unless you are using a CATiledLayer based UIView.
If UIImage is not created, it because the name does not refer to an image in the resource folder and you should have an exception.
You need to have the correct file names. You said you think the file names are correct.
NSLog(#"Loop %d: d%dimage%d.png", i,imageSection, i]);
Log out the file names so you can see what the names actually are. Place that line in your loop.
NSUInteger i;
for (i = 1; i <= numberOfImage; i++)
{
NSString *imageName = [NSString stringWithFormat:#"d%dimage%d.png", imageSection, i];
NSLog(#"Loop %d: d%dimage%d.png", i,imageSection, 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
[scrollView addSubview:imageView];
[imageView release];
}
Then monitor the filenames in the debugger and see if those image files exist, and in the same directory where Apple put their image files.
Hey,Its not good way to load 10 images at once.All things you have done correct and still you'r image display empty then please check log may be there is memory warning.You can you apple's sample code photoscroller. It will do all thing that you want and also manages good memory.there are two method one is using CATieldLayer and another one directly load images. I recommended you to use method that uses CATieldLayer.
Sorry guys. This is turned out to be my fault. well, not exactly MY fault. Designers throw me many files with wrong filenames like d1imgae11.png... Anyway tips from all you guys gave me different view to see the problem and I got another hint about not to cache images. Thanks.