multiple uiimageviews from for loop - iphone

I am writing a game in which a Uiimageview needs to be 'spawned,' if you will. every time the character hits the end box. Everything else is working except that. Could someone check my code and see what I'm doing wrong? Thanks!
for (int i = 1; i <= level; i++) {
int xPos = rand() % 316;
int yPos = rand() % 450;
UIImageView *mine = [[UIImageView alloc] initWithFrame:CGRectMake(xPos, yPos, 10, 10)];
}

You are not adding the views that you create in a loop as subviews to your main view. That's why they do not become visible.
As a side note, I think you would be better off using CALayer objects instead of UIImageView: they are lighter-weight, and require about the same amount of work.

Related

Why is UIView drawRect causing first pass of UIScrollview to be choppy/jerky/slow?

EDIT: It looks like the problem code is in a procedural background that I am drawing in a UIView which I am then adding as a subview to UIScrollView. The procedural code is below. It draws box shapes, which look sort of like a skyline. Any Ideas why this is slowing down the first pass of my UIScrollView? It can be as much as a thousand pixels wide or more at times. See image...
- (void)drawRect:(CGRect)rect
{
UIBezierPath *vertLine = [[UIBezierPath alloc] init];
[vertLine moveToPoint:CGPointMake(0,self.frame.size.height)];
int detail = 10;
int ranNum = 0;
int count = self.bounds.size.width/detail;
CGFloat heightIncrement = 0.0;
CGFloat minHeight = self.frame.size.height;
CGFloat xPos = 0;
CGFloat yPos = self.frame.size.height-20;
for (int i =0; i<count; i++)
{
ranNum += (arc4random() % 9)-5;
yPos -= (arc4random() % 30);
[vertLine addLineToPoint:CGPointMake(xPos,yPos)];
xPos += (arc4random() % 20)+10;
[vertLine addLineToPoint:CGPointMake(xPos,yPos)];
yPos += (arc4random() % 30);
[vertLine addLineToPoint:CGPointMake(xPos,yPos)];
xPos += (arc4random() % 30);
[vertLine addLineToPoint:CGPointMake(xPos,yPos)];
if (yPos>self.frame.size.height-10) {
yPos = self.frame.size.height-10;
}
if (yPos<self.frame.size.height-50) {
yPos = self.frame.size.height-50;
}
}
[vertLine addLineToPoint:CGPointMake(count*20,(self.frame.size.height))];
[[UIColor colorWithRed:0.0/255.0 green:38.0/255.0 blue:51.0/255 alpha:1] setFill];
[vertLine fill];
}
I have a jerky scroll view, but ONLY on the first pass. After all the views have been viewed in the scroll view, it is very smooth.
First Pass: During the first pass it appears that when each UIImageView is coming into view (from right to left) There is a jerk right when it is entering the visible area. So if you reference the attached image, you'll see UIImageView 5 entering from right to left. When this happens there is a small pause as if the scroll view is telling the image view to load/prepare to be on stage. I have tried to profile this but I don't see any problems in my code and im not sure how I can profile the methods etc. that I have not overridden. So a sub question would be... What methods are called on a subview of UIScrollView when it is entering the visible area?
As I mention I tried to do the async and other concurrent approaches, but it seems that no matter how the images are loaded, the first pass is always jerky, then its as if the UIScrollView caches the subviews. Is it possible to do this caching/loading up front...
[scrollView cacheSubViews]; I would rather have a slower startup than it to be clunky on the first scroll.
Thanks for any ideas on this or information about how the UIScrollView works with its subviews. I have seen many questions and some solutions about jerky UIScrollViews with UIImageViews as subviews. I have tried many of them, but still have a slow scrollview.
austin
imageWithContentsOfFile is a synchronous process takes a lot of tile.Use some asynchronous way to load the images and the smoothness can be achieved

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 ^_^

Can not draw NSString using drawInRect to display in a popover

In my application I have an array of strings that I am trying to draw in a pop over. Previously, I have been able to draw images in the pop over, but trying to convert this to show text I have not been successful. Listed below is the function I just to get the images from the array, and draw them.
CGRect b = self.bounds;
CGFloat columnWidth = b.size.width / columnCount;
CGFloat rowHeight = b.size.height / rowCount;
for (NSUInteger rowIndex = 0; rowIndex < rowCount; rowIndex++) {
for (NSUInteger columnIndex = 0; columnIndex < columnCount; columnIndex++) {
CGRect r = CGRectMake(b.origin.x + columnIndex * columnWidth,
b.origin.y + rowIndex * rowHeight,
columnWidth, rowHeight);
UIImage *image = [self.colors objectAtIndex:rowIndex * columnCount + columnIndex];
[image drawInRect:r];
}
}
In this function (for the text, not the one above), the row and column count have sometimes changes - for the text display, columns is always 1, and the rows are always equal to the amount of items in the array (for our testing purposes, there is 1 string in the array currently) I have tried to make the image a UIlabel instead, and changing the test of the label to the item in the string - but it still does not display when using drawInRect. Does anyone have a solution to this? I basically need to find any way to draw this text in the rect, even if its not using a label and another method (like placing the text in an image, which I also was not able to figure out). Thanks for your help.

CGRect Grid on screen?

I want to create a grid of rectangles at the centre of screen leaving some space on the edges. The need of that arises because I am spewing different sprites at random points and they keep spawning on top of eat other. So i thought if there is a way of creating a class that creates the grid and returns me with a random rect and mark it occupied as long at the sprite stays in that rect and make it free after.
If i can get some help or any tips it will be great. Any other solutions to achieve this are welcome too.
Thanks.
You could nest two for loops, one for rows and one for columns, make them both run 5 times, and in each loop increment the x position and y position by one-fifth the width and height of the screen and put these coordinates into a CGRrect. That would do what you want.
Thanks #andrewx for your help. This will create CGRect in the given range and then return a random one.
-(void) makeCGRectArray{
rectsArray = [[NSMutableArray alloc] init];
for (int x = 30; x<=420; x= x+60) {
for (int y=40; y<=280; y=y+40) {
CGRect newRect = CGRectMake(x, y, 60, 40);
[rectsArray addObject:[NSValue valueWithCGRect:newRect]];
}
}
[self getRandomCgrect:rectsArray];
}
-(CGRect) getRandomCgrect:(NSMutableArray*) rectArray{
NSInteger randomPoint = (arc4random() % (49));
CGRect randomRect = [[rectsArray objectAtIndex:randomPoint] CGRectValue];
self.isOccupied = YES;
return randomRect;
}

managing images in UIScrollView

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.