Access position of UIButton objects in Array - iphone

I have an array of UIButtons. What I want to do is with another button, randomly set the positions of each of the buttons in the array.
So I initialize the array with the UIButtons:
buttonArray = [[NSMutableArray alloc] initWithObjects:button1,button2,button3,button4,button5,button6,button7, nil];
Then I have a randomize method to set each of the button's positions.
this is the part where I'm stuck. I've found some threads about having to cast the type of the object in the array so the compiler understands. but I can't seem to make it work.
- (IBAction)randomizePositions:(id)sender
{
for (int i = 0; i < [buttonArray count]; ++i)
{
float xPos = arc4random() % 1000;
float yPos = arc4random() % 700;
CGRect randomPosition = CGRectMake(xPos, yPos, button1.frame.size.width, button1.frame.size.width);
(UIButton *)[buttonArray objectAtIndex:i].frame = randomPosition;
}
}
It's this part here that I can't seem to get right. It's pretty obvious by now that I'm a beginner so any help would be much appreaciated.
(UIButton *)[buttonArray objectAtIndex:i].frame = randomPosition;

You may want to grab a pointer to the UIButton in the array earlier, as it might be easier to consider what you are working with.
- (IBAction)randomizePositions:(id)sender
{
for (int i = 0; i < [buttonArray count]; ++i)
{
UIButton *currentButton = (UIButton *)[buttonArray objectAtIndex:i];
float xPos = arc4random() % 1000;
float yPos = arc4random() % 700;
[currentButton setFrame:CGRectMake(xPos, yPos, currentButton.frame.size.width, currentButton.frame.size.height)];
}
}
Unless, of course, you want to always be working with button1 size.

Related

Mechanism to assign UIImages their own Rect inside a CALayer?

I have one or more CALayers which represent/fill the whole screen.
I want to fill those CALayers from a grid structure, using a lot of small Rects with images.
What i tried was assigning each Rect its own CALayer and an UIImage.
With over 6000 CALayers the result was very slow. Now i am looking for a way not to use that much CALayer. Maybe only the top level ones.
So ist there a mechanism to assign UIImages their own Rect inside a CALayer ?
Slow / bad code Example:
- (void)createLayer{
CALayer *currentLayer = self.layer;
_layerArray = [[NSMutableArray alloc] initWithCapacity:WIDTH*HEIGHT];
int cellSize = self.bounds.size.width / WIDTH;
double xOffset = 0;
CGRect cellFrame = CGRectMake(0, 0, cellSize, cellSize);
NSUInteger cellIndex = 0;
cellFrame.origin.x = xOffset;
for (int i = 0; i < WIDTH; i++)
{
cellFrame.origin.y = 0;
for (int j = 0; j < HEIGHT; j++, cellIndex++)
{
if([[self.levelState.boardChanges objectAtIndex:(i*HEIGHT)+j] intValue]==1){
{
NSNumber *currentCell = [self.levelState.board objectAtIndex:cellIndex];
CALayer *sublayer = [CALayer layer];
sublayer.frame = cellFrame;
if (currentCell.intValue == 1)
{
[[_layerArray objectAtIndex:(i*HEIGHT)+j ] setContents:(id) [UIImage imageNamed:#"image1.png"].CGImage];
}
else if (currentCell.intValue == 0)
{
[[_layerArray objectAtIndex:(i*HEIGHT)+j ] setContents:(id) [UIImage imageNamed:#"image2.png"].CGImage];
}
[currentLayer addSublayer:sublayer];
[_layerArray addObject:sublayer];
}
}
cellFrame.origin.y += cellSize;
}
cellFrame.origin.x += cellSize;
}
}
I would recommend a very different approach.
subclass a uiview and use it as your background
in your uiview subclass, override
-(void)drawRect:(CGRect)rect
inside, you can draw your uiimages within rectangles you define
[[UIImage imageNamed:#"image1.png"]drawInRect:CGRectMake(0,0,10,10)]; //first square
[[UIImage imageNamed:#"image2.png"]drawInRect:CGRectMake(10,0,10,10)]; // and another right beside it
you can study core graphics more to get a better idea

Programmatically create UIButtons on CircleImage

I need to create Arch shaped UIButtons, on a circle image.(the O/p need to look like Concentric Circles),
At present I am using 5 images, but in future I may add some more Images, Dynamically I need to fil the circle Image with the added images.
I had a sample Piece of code and O/P is the below image
int numberOfSections = 6;
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, 2.0f)];
sectionLabel.backgroundColor = [UIColor redColor];
sectionLabel.layer.anchorPoint = CGPointMake(1.0f, 0.5f);
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];
}
I have tried with this piece of code and the O/P is the below image
int numberOfSections = 5;
CGFloat angleSize = 2*M_PI/numberOfSections;
for (int j = 0; j<numberOfSections; ++j) {
UIImage *imageframe = [imagesArray objectAtIndex:j];
OBShapedButton *button = [[OBShapedButton alloc] initWithFrame:CGRectMake(0.0f, 150.0f, 150.0f, 128.0f)];
button.transform = CGAffineTransformMakeRotation(angleSize*j);
[container addSubview:button];
}
I need my output as the below image
How can i Achieve that
O/P after I Tried with Sarah Zuo's code
same width and height buttons
AnyKind of Help is more Appreciated
I can answer only last part,
If you are able to get images for buttons, then you can refer this tutorial. This might help you. Provided, your image formed is having transparent background.
float radius = container.bounds.size.width / 2;
int numberOfSections = 5;
CGFloat angleSize = 2*M_PI/numberOfSections;
for (int j = 0; j<numberOfSections; ++j) {
UIImage *imageframe = [imagesArray objectAtIndex:j];
OBShapedButton *button = [[OBShapedButton alloc] initWithFrame:CGRectMake(0.0f, 150.0f, 150.0f, 128.0f)];
button.transform = CGAffineTransformMakeRotation(2*M_PI-angleSize*j);
button.center = CGPointMake(radius + radius * sin(angleSize * j) / 2, radius + radius * cos(angleSize * j) / 2);
[container addSubview:button];
}
Try this code.
You can use your UIImageView instead. You can give different tag to image view and add Gesture Recognizer. Now you can get touch events like button click event on image views.
If all buttons' image look like the one (same direction), the transform value may be work.
button.transform = CGAffineTransformMakeRotation(2*M_PI-angleSize*j);
button.center = CGPointMake(radius + radius * sin(angleSize * j) / 2, radius + radius * cos(angleSize * j) / 2);

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

EXC_BAD_ACCESS in for loop

In this code, in the second for loop, i get an EXC_BAD_ACCESS if I use an identifier other than i and j.
if (UIDeviceOrientationIsPortrait(deviceOrientation)){
numRows = 4;
numCols = 3;
}else {
numRows = 6;
numCols = 1;
}
for (int row = 0; row < numRows; row++){
for (int col = 0; col < numCols; col++) {
keysArray[row][col] = [[[keys objectAtIndex:0] retain] autorelease];
if (col < numRows)
[keys removeObjectAtIndex:0];
}
}
//Here is the crash
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++){
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
b.frame = CGRectMake(i * kKeyGap, j * kKeyGap, 57, 57);
[b setImage: [UIImage imageNamed:keysArray[j][i]]
forState:UIControlStateNormal];
[self.view addSubview:b];
}
}
Why would this cause such an error? I tried using Edit All In Scope to avoid missing one, but it still crashes.
Thanks
Your line:
keysArray[row][col] = [[[keys objectAtIndex:0] retain] autorelease];
I'm not an Objective-C expert or anything, but I'm not certain you need to autorelease that object because you haven't allocated memory for it. What happens when you try and remove that autorelease?
My suspicion is that after you autorelease the object and then attempt to assign the array value here:
[b setImage: [UIImage imageNamed:keysArray[j][i]]
forState:UIControlStateNormal];
you're getting the EXC_BAD_ACCESS.
I could be wrong, in which case I hope someone smarter than me can clear this up. :)
In your first loop you are referencing keysArray[row][col] in the second loop you seem to be using keysArray[col][row] which would cause it to crash if numRows and numCols are different

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?