0

The following files load a series of shapes into a UIViewController. Each shape is placed randomly on the screen. I can use the following code to change the shape of the image horizontally, but I cannot move the x and y coordinates of the image on the UIView. How can I move the shape to a different location on screen? The following changes the width of the UIView:

 [UIView animateWithDuration:0.5f animations:^{[[timer userInfo] setBounds:CGRectMake(0, 0, 100, 5)];}];

ViewController.h

#import <UIKit/UIKit.h>
#import "Shape.h"

@interface ViewController : UIViewController

@end

ViewController.m

#import "ViewController.h"

@implementation ViewController

UIView *box;
int screenHeight;
int screenWidth;
int x;
int y;
Shape * shape;
- (void)viewDidLoad
{
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    screenHeight = screenRect.size.height;
    screenWidth = screenRect.size.width;
    box = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 5)];     
    [self.view addSubview:box];
    for (int i = 0; i<3; i++) {
        x = arc4random() % screenWidth;
        y = arc4random() % screenHeight;
        shape =[[Shape alloc] initWithX:x andY:y];
        [box addSubview:shape];     
        [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(moveTheShape:) userInfo:shape repeats:YES];     
    }
}
-(void) moveTheShape:(NSTimer*)timer
{
    //[UIView animateWithDuration:0.5f animations:^{[[timer userInfo] setBounds:CGRectMake(100, 0, 100, 5)];}];
    [UIView animateWithDuration:0.5f animations:^{[[timer userInfo] setBounds:CGRectMake(0, 0, 100, 5)];}];
}
@end

Shape.h

#import <UIKit/UIKit.h>

@interface Shape : UIView; 

- (id) initWithX: (int)xVal andY: (int)yVal;

@end

Shape.m

#import "Shape.h"

@implementation Shape 

- (id) initWithX:(int )xVal andY:(int)yVal {
    self = [super initWithFrame:CGRectMake(xVal, yVal, 5, 5)];  
    self.backgroundColor = [UIColor redColor];  
    return self;
}

@end
SimonRH
  • 1,409
  • 2
  • 13
  • 23

1 Answers1

1

In your moveTheShape method, you need to set the frame, not the bounds, and set the x and y values in the CGRectMake to something other than 0.

You can get your original x and y values in the moveTheShape method like this:

 -(void) moveTheShape:(NSTimer*)timer {
        CGRect frame = [timer.userInfo frame];
        float frameX = frame.origin.x;
        float frameY = frame.origin.y;
        NSLog(@"X component is:%f   Y component is:%f",frameX,frameY);
        [UIView animateWithDuration:0.5f animations:^{[[timer userInfo] setFrame:CGRectMake(200, 100, 5, 5)];}];
    }
rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • 1
    The 0's in his `CGRectMake` specify that the CGRect's top left corner should be at the top left corner of the screen, so they are perfectly fine, and do not have to be changed. However, I believe you are correct in saying that the OP must set the frame and not the bounds in the `moveTheShape` method. This is because the bounds represent the view's location and size relative to it's own coordinate system, while its frame is it's location and size relative to the coordinate system of the superview it is inside. – pasawaya Jun 07 '12 at 22:51
  • For example, if you have a view located at (0,0), it's frame and bounds are equal, but if you move it one pixel to the right, then it's bounds is still the same, but the frame's x coordinate would be one greater. See here for more info: http://stackoverflow.com/questions/1210047/iphone-development-whats-the-difference-between-the-frame-and-the-bounds – pasawaya Jun 07 '12 at 22:53
  • Perfect. Thank you. Can I ask you a follow up? In the method moveTheShape I want successive instances of shape to change their positions (e..g. x+=5). Is there an object that allows me to extract a CGRect that will allow me to read the current x, y values? I tried CGRect oldVals = [(Shape *)timer frame]; int oldX = oldVals.origin.x; int oldY = oldVals.origin.y; but that gave me an error. – SimonRH Jun 08 '12 at 00:40
  • I don't understand the question. Do you want successive instances to start out at a different position? – rdelmar Jun 08 '12 at 00:46
  • Yes. I want to transform the coordinates to move them to different locations. I need to move each instance relative to its original position. – SimonRH Jun 08 '12 at 01:04
  • You're passing the shape in the user info of the timer, so you should be able to get the shape's original frame from that, and change it accordingly in moveTheShape: – rdelmar Jun 08 '12 at 01:17
  • My problem is finding it! I tried putting the objects into a mutable array to read out using a for-in loop, but couldn't load them. Where can I find the original frame? – SimonRH Jun 08 '12 at 01:51
  • As I said, you're passing the Shape object in your user info. In the moveTheShape method, if you add the line, NSLog(@"%@",timer.userInfo); you will see that it logs the frame of each shape. You can get it from there, no need to put anything into an array. – rdelmar Jun 08 '12 at 02:20
  • see my edited answer, for how to extract the values of x and y – rdelmar Jun 08 '12 at 02:31