obj c "for loop" road block - iphone

Im showing some data in a simple bar that charts some values, all is working, but now to build the scale for my Y axis, im having some problems with some basic stuff,
I get the ceiling value for my chart with scaleMaxInt in this case for testing = 900
then according to some simple test, I get for example 9 divisions [plus zero]...
so to make the thing work, I create the int pp=100
- (void) drawScaleLabels:(int)scaleMaxInt
{
//temp division for scale, NOTE WHERE TO USE 9 DIVISIONS!!
int scaleStep = scaleMaxInt/9;
NSLog(#"va ::%d", scaleStep);
// case scaleMax : 0 < scaleMax < 1000
float scaleDiv = 31.5;
for (int i = 0; i<9; i++)
{ // is 8, to 9 only for testing!!
int pp = 100;
self.divScaleLabel = [[[UILabel alloc] initWithFrame:CGRectMake(469, scaleDiv+286, 60, 14)]autorelease];
self.divScaleLabel.font = [UIFont fontWithName:#"FS Albert" size:14];
self.divScaleLabel.textColor = [UIColor whiteColor];
self.divScaleLabel.textAlignment = UITextAlignmentRight;
self.divScaleLabel.text =[NSString stringWithFormat:#"$%d",scaleMaxInt-scaleStep];
self.divScaleLabel.backgroundColor =[UIColor clearColor];
[self.view addSubview:self.divScaleLabel];
scaleDiv = scaleDiv + 31.5;
scaleStep = scaleStep+pp;
}
}
wich shows the list of values in my Y axis: 900 , 800 , 700 ,600... 0
but if I use the result of the int scaleStep = scaleMaxInt/9
it gives me the list but with the value*2
- (void) drawScaleLabels:(int)scaleMaxInt
{
//temp division for scale, NOTE WHERE TO USE 9 DIVISIONS!!
int scaleStep = scaleMaxInt/9;
NSLog(#"va ::%d", scaleStep);
// case scaleMax : 0 < scaleMax < 1000
float scaleDiv = 31.5;
for (int i = 0; i<9; i++)
{ // is 8, to 9 only for testing!!
//int pp = 100;
self.divScaleLabel = [[[UILabel alloc] initWithFrame:CGRectMake(469, scaleDiv+286, 60, 14)]autorelease];
self.divScaleLabel.font = [UIFont fontWithName:#"FS Albert" size:14];
self.divScaleLabel.textColor = [UIColor whiteColor];
self.divScaleLabel.textAlignment = UITextAlignmentRight;
self.divScaleLabel.text =[NSString stringWithFormat:#"$%d",scaleMaxInt-scaleStep];
self.divScaleLabel.backgroundColor =[UIColor clearColor];
[self.view addSubview:self.divScaleLabel];
scaleDiv = scaleDiv + 31.5;
NSLog(#"va ::%d", scaleStep);
scaleStep = scaleStep+scaleStep;
}
}
so Y axis is, 900, 800 , 700, 500 , 100, -700 ...-24700
Im stupidly stuck with this!,
how can i generate the list for Y axis?, with a dynamic value, dependent of scaleMaxInt
that doesn't get confused??
thanks a lot!

You have this in your loop:
scaleStep = scaleStep+scaleStep;
That means you are doubling scaleStep on each pass through the loop. Remove that line. Instead, set self.divScaleLabel.text like this:
self.divScaleLabel.text =[NSString stringWithFormat:#"$%d", scaleMaxInt - scaleStep * i];

Related

To make 16 uilabels and align them in circular path.

NSMutableArray *views = [[NSMutableArray alloc]initWithCapacity:0];
for (NSInteger i = 0; i<16; i++)
{
UIView *circle = [[UIView alloc]init];
circle.backgroundColor = [UIColor clearColor];
UIImageView *circleImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 80, 80)];
circleImage.image = [UIImage imageNamed:#"circle"];
[circle addSubview:circleImage];
UILabel *labelInsideCircle = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 40, 40)];
labelInsideCircle.backgroundColor = [UIColor clearColor];
labelInsideCircle.textColor = [UIColor greenColor];
labelInsideCircle.font = [UIFont fontWithName:#"Helvetica" size:30.0];
labelInsideCircle.center = circleImage.center;
NSInteger int_ = [self getRandomNumber:0 to:(arrOfOptions.count-1)];
labelInsideCircle.text = [NSString stringWithFormat:#"%#",[arrOfOptions objectAtIndex:int_]];
labelInsideCircle.textAlignment = NSTextAlignmentCenter;
[arrOfOptions removeObjectAtIndex:int_];
[circle addSubview:labelInsideCircle];
[labelInsideCircle release];
[views addObject:circle];
[circle release];
[circleImage release];
}
/* Rotating circles with angles */
float curAngle = 0;
float incAngle = ( 360.0/(views.count) )*3.14/180.0;
CGPoint circleCenter = CGPointMake(380, 580); /* given center */
float circleRadius = 250; /* given radius */
for (UIView *view in views)
{
CGPoint viewCenter;
viewCenter.x = circleCenter.x + cos(curAngle)*circleRadius;
viewCenter.y = circleCenter.y + sin(curAngle)*circleRadius;
view.transform = CGAffineTransformRotate(view.transform, curAngle);
view.center = viewCenter;
[self.view addSubview:view];
curAngle += incAngle;
}
The problem is here the text of UILabel is also getting transformed, which is obvious. What I want is 16 circular views with labels on them without the label's text transformed. Can anyone please help me out with this ?
In this case, you just need to change their location coordinates, not rotate them.
NSMutableArray *views = [[NSMutableArray alloc] initWithCapacity:0];
for (NSInteger i = 0; i<16; i++)
{
UIView *circle = [[UIView alloc]init];
circle.backgroundColor = [UIColor clearColor];
UIImageView *circleImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 80, 80)];
circleImage.image = [UIImage imageNamed:#"circle"];
[circle addSubview:circleImage];
UILabel *labelInsideCircle = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 40, 40)];
labelInsideCircle.backgroundColor = [UIColor clearColor];
labelInsideCircle.textColor = [UIColor greenColor];
labelInsideCircle.font = [UIFont fontWithName:#"Helvetica" size:30.0];
labelInsideCircle.center = circleImage.center;
NSInteger int_ = arc4random()%[arrOfOptions count];
labelInsideCircle.text = [NSString stringWithFormat:#"%#",[arrOfOptions objectAtIndex:int_]];
labelInsideCircle.textAlignment = NSTextAlignmentCenter;
[arrOfOptions removeObjectAtIndex:int_];
[circle addSubview:labelInsideCircle];
[labelInsideCircle release];
[views addObject:circle];
[self.view addSubview:circle];
[circle release];
[circleImage release];
}
/* Rotating circles with angles */
float curAngle = 0;
float incAngle = ( 360.0/(views.count) )*3.14/180.0;
CGPoint circleCenter = CGPointMake(380, 580); /* given center */
float circleRadius = 250; /* given radius */
for (UIView *view in views)
{
CGPoint viewCenter;
viewCenter.x = circleCenter.x + cos(curAngle)*circleRadius;
viewCenter.y = circleCenter.y + sin(curAngle)*circleRadius;
//view.transform = CGAffineTransformRotate(view.transform, curAngle);
view.center = viewCenter;
[self.view addSubview:view];
curAngle += incAngle;
}
Some coding suggestions:
You can use arc4random() function if you don't have anything special in your own random number generator.
You can turn on ARC in xCode!
In a loop set their centers accordingly, don't rotate them nor their super view.
The following is not directly related to your question but may be helpful:
Aparaently you have got all the math available. I suggest to measure how much cpu time gets lost on the cos and sin etc. calls. If you find that significant then think about your algorithm. You will (most probably) find out that you call cos and sin hundrets or thousands of times for a limited number of angles.
You may then try it and find out that possible pre-calculations or just "caching and reusing" earlier results may save significant processing time.
Plus pre-calculating or caching of sinus would do. You can derrive cosinus values from sinus (and vice versa) by adding (or substracting respectively) an offset of pi/2 (or 90 degrees respectively) to the argument.
For similar tasks I was working with degrees (not radiants) and found out that I could not predict the angles but that a significant of full degrees (1°, 2°, 3°, ... and nothing in between) was exact enough for the job. Then I maintained an array of 360 sinus values and used that instead of calling the real function again and again. (Plus I only had to calculate 90 of them and mirrored the results of the other 270 degrees according to the nature of the sinus function) 180 floats is not too much of memory compared to the speed that I gained. Something like that can be suitable for you too. In your case your potenital agruments to sin and cos are limited to full-number multipilers of incAngle.
Which means there are only [views count] number of potential values each.

How to place arrange images dynamically in a circle

How can i dynamically arrange icons(UIButtons, with backgroundImages) in circle image.SOmething like it should like concentric circles.
I am using the following code,
UIImageView *container = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0f, 299.0f, 298.0f)];
container.image = [UIImage imageNamed:#"AR_RF004_circle.png"];
container.center = CGPointMake(self.view.bounds.size.width/2.0, self.view.bounds.size.height/2.0);
[self.view addSubview:container];
NSArray *imagesArray = [[NSArray alloc]initWithObjects:[UIImage imageNamed:#"AR1.png"],[UIImage imageNamed:#"AR2.png"],[UIImage imageNamed:#"AR3.png"],[UIImage imageNamed:#"AR4.png"],[UIImage imageNamed:#"AR5.png"], nil];
int numberOfSections = 5;
CGFloat angleSize = 2*M_PI/numberOfSections;
for (int j = 0; j < numberOfSections; ++j) {
UIButton *sectionLabel = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 150.0f, 128.0f)];
[sectionLabel setBackgroundImage:[imagesArray objectAtIndex:j] forState:UIControlStateNormal];
sectionLabel.layer.anchorPoint = CGPointMake(0.9f, 0.1f);
sectionLabel.layer.position = CGPointMake(container.bounds.size.width/2.0, container.bounds.size.height/2.0); // places anchorPoint of each label directly in the center of the circle.
sectionLabel.transform = CGAffineTransformMakeRotation(angleSize*j);
[container addSubview:sectionLabel];
NSLog(#"section label x and y is %f ,%f",sectionLabel.frame.origin.x,sectionLabel.frame.origin.y);
}
[container release];
Thanks in Advance
You can use this piece of code:
UIButton *currentButton;
int buttonCount = 20;
int radius = 200;
float angleBetweenButtons = (2 * M_PI) / buttonCount;
float x = 0;
float y = 0;
CGAffineTransform rotationTransform;
for (int i = 0; i < buttonCount; i++)
{
// get your button from array or something
currentButton = ...
...
x = radius + cosf(i * angleBetweenButtons) * radius;
y = radius + sinf(i * angleBetweenButtons) * radius;
rotationTransform = CGAffineTransformIdentity;
rotationTransform = CGAffineTransformRotate(rotationTransform, (i * angleBetweenButtons));
currentButton.center = CGPointMake(x, y);
currentButton.transform = rotationTransform;
}
I think you can do something like this
sectionLabel.center = container.center;
I have not checked other code.. Simplest way for this

How can I calculate NSString max length which UILabel can contain without truncate the text?

I have two UILabels, one above the other.
The top one has fixed size (2 Lines), and the bottom one can expand (0 lines).
The text which I using for the labels can be short and sometimes it can be very long.
How can I calculate the first UILabel max string length without cut a word in the middle?
//Here is the code which create the 2 labels.
titleView = [[UILabel alloc] initWithFrame:CGRectMake(70, 0, 200, 50)];
titleView.numberOfLines = 2;
titleView2 = [[UILabel alloc] initWithFrame:CGRectMake(20, 50, 250, 100)];
titleView2.numberOfLines = 0;
I've solved the problem with this method:
+ (int)getSplitIndexWithString:(NSString *)str frame:(CGRect)frame andFont:(UIFont *)font
{
int length = 1;
int lastSpace = 1;
NSString *cutText = [str substringToIndex:length];
CGSize textSize = [cutText sizeWithFont:font constrainedToSize:CGSizeMake(frame.size.width, frame.size.height + 500)];
while (textSize.height <= frame.size.height)
{
NSRange range = NSMakeRange (length, 1);
if ([[str substringWithRange:range] isEqualToString:#" "])
{
lastSpace = length;
}
length++;
cutText = [str substringToIndex:length];
textSize = [cutText sizeWithFont:font constrainedToSize:CGSizeMake(frame.size.width, frame.size.height + 500)];
}
return lastSpace;
}
CGSize textSize=[someString sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:sizeConstraint];
Then you can access the width and height:
float height=textSize.height;
float width=textSize.width;

How to create grid button on iphone. 10/10 matrix

How to create Grid of Buttons on iphone.
10/10 matrix...
I found NSMatrix for MAC ... Not for iphone...
any alternative way to create grid of button on my view.
#Thanks in advance.
Manually?
int rows = 10;
int cols = 10;
float gridWidth = 320.0;
float gridHeight = 320.0;
float buttonWidth = 28.0;
float buttonHeight = 28.0;
float gapHorizontal = (gridWidth - (buttonWidth * rows)) / (rows + 1);
float gapVertical = (gridHeight - (buttonHeight * cols)) / (cols + 1);
float offsetX;
float offsetY;
int count = 0;
do {
offsetX = gapHorizontal + ((count % rows) * (buttonWidth + gapHorizontal));
offsetY = gapVertical + ((count / rows) * (buttonHeight + gapVertical));
UIView *aView = [[UIView alloc] initWithFrame:CGRectMake(offsetX, offsetY, buttonWidth, buttonHeight)];
aView.backgroundColor = [UIColor redColor];
[self.view addSubview:aView];
[aView release];
offsetX+= buttonWidth + gapHorizontal;
count++;
} while(count < rows * cols);
Also check out AQGridView. I guess it's pretty much what you are looking for. And more.
As I usually use this to make grid.. Only you have to just replace with your row and column
#define MatrixRow 3
#define MatrixColumn 3
#define GRID_WIDTH 300
#define GRID_HEIGHT 300
UIView *grid = [[UIView alloc] initWithFrame:CGRectMake(10, 50, GRID_WIDTH, GRID_HEIGHT)];
grid.backgroundColor = [UIColor brownColor];
for (int i = 0; i< (MatrixColumn*MatrixRow); i++) {
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
view.backgroundColor = [UIColor yellowColor];
CGFloat xOrigin = GRID_WIDTH/(MatrixColumn*2) + (GRID_WIDTH/MatrixColumn)*(i%MatrixColumn);
CGFloat yOrigin = GRID_HEIGHT/(MatrixRow*2) + (GRID_HEIGHT/MatrixRow) *(i/MatrixColumn);
NSLog(#" (\"%.2f\" , \"%.2f\")",xOrigin,yOrigin);
view.center = CGPointMake(xOrigin, yOrigin);
[grid addSubview:view];
}
[self.view addSubview:grid];

Objective C speeding up animation / object creation

What kind of trick can I use to speed up and improve an image sequence animation?
I'm using the code below, but then just running through the codes below takes a couple of seconds to finish.
Once the animations have been created, my phone seems to get much slower too.
Please enlight.
Thanks,
Tee
NSMutableArray * sequenceArray;
sequenceArray = [[NSMutableArray alloc] init];
int k;
int xPos = 0;
int yPos = 50;
for (k = 1; k <= 48; k++)
{
UIImageView* dynamicView = [[UIImageView alloc] initWithFrame:self.view.frame];
[sequenceArray addObject:dynamicView];
int i;
NSMutableArray *a = [NSMutableArray array];
for (i = 1; i <= 102; i++)
{
[a addObject:[UIImage imageNamed:[NSString stringWithFormat:#"loop2 %d.png", i]]];
}
dynamicView.animationImages = a;
//[a release];
// all frames will execute in 1.75 seconds
dynamicView.animationDuration = 1.6;
// repeat the annimation forever
dynamicView.animationRepeatCount = 0;
CGRect frame1 = dynamicView.frame;
frame1.size.width = 34;
frame1.size.height = 34;
frame1.origin.x = xPos;
frame1.origin.y = yPos;
dynamicView.frame = frame1;
if (k % 8 == 0) {
xPos = 0;
yPos += 40;
}
xPos += 40;
NSLog(#"step last");
// start animating
[dynamicView startAnimating];
// add the animation view to the main window
[self.view addSubview:dynamicView];
[dynamicView release];
}
So, you're creating 48 UIImageViews, each with an animation of the same 102 frames? Am I reading that right?
The first thing that occurs to me is to pull this out of the other loop, since it's loading the same array each time, and just assign it to each view:
int i;
NSMutableArray *a = [NSMutableArray array];
for (i = 1; i <= 102; i++)
{
[a addObject:[UIImage imageNamed:[NSString stringWithFormat:#"loop2 %d.png", i]]];
}
But, really, why are you doing this?