I am trying to make an app in Xcode 4.3.3 where one image is displayed when the z-axis using the accelerometer is positive. But, when the z-axis becomes negative, I would like a different image to appear. I'm a beginner, so if you could tell me the file in which I should write the code in that would be great.
Thank you!
Check out below links to understand UIAccelerometer
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAccelerometer_Class/Reference/UIAccelerometer.html
http://homepages.ius.edu/rwisman/C490/html/chapter22.htm
http://www.edumobile.org/iphone/iphone-programming-tutorials/how-to-use-accelerometer-in-iphone/
http://www.ifans.com/forums/threads/tutorial-simple-accelerometer-source-code.151394/
You would require to make changes in following function
- (void)accelerometer:(UIAccelerometer *)accelerometer
didAccelerate:(UIAcceleration *)acceleration
{
if(acceleration.z<0) {
imageview.image = //Display image to be displayed when z is negative
}
else {
imageview.image = //Display image to be displayed when z is positive
}
}
Related
I make an app that has many views that subclass from UIView. The size and the orientation of these views is random and the state of a screen of the app can be saved. When the user saves a screen on the same device that he opens it, then the screen state is OK. Everything is positioned correctly. But, if the user saves the screen state on an iPhone and opens it from an iPad the views are not positioned correctly. Actually the views appear shorter or longer, the center seems to be saved correctly, but the rotation of the views and their size (bounds property) are not working OK.
These are the two methods that save and restore the state of the view
- (void)encodeWithCoder:(NSCoder *)aCoder {
// Save the screen size of the device that the view was saved on
[aCoder encodeCGSize:self.gameView.bounds.size forKey:#"saveDeviceGameViewSize"];
// ****************
// ALL properties are saved in normalized coords
// ****************
// Save the center of the view
CGPoint normCenter = CGPointMake(self.center.x / self.gameView.bounds.size.width, self.center.y / self.gameView.bounds.size.height);
[aCoder encodeCGPoint:normCenter forKey:#"center"];
// I rely on view bounds NOT frame
CGRect normBounds = CGRectMake(0, 0, self.bounds.size.width / self.gameView.bounds.size.width, self.bounds.size.height / self.gameView.bounds.size.height);
[aCoder encodeCGRect:normBounds forKey:#"bounds"];
// Here I save the transformation of the view, it has ONLY rotation info, not translation or scalings
[aCoder encodeCGAffineTransform:self.transform forKey:#"transform"];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
// Restore the screen size of the device that the view was saved on
saveDeviceGameViewSize = [aDecoder decodeCGSizeForKey:#"saveDeviceGameViewSize"];
// Adjust the view center
CGPoint tmpCenter = [aDecoder decodeCGPointForKey:#"center"];
tmpCenter.x *= self.gameView.bounds.size.width;
tmpCenter.y *= self.gameView.bounds.size.height;
self.center = tmpCenter;
// Restore the transform
self.transform = [aDecoder decodeCGAffineTransformForKey:#"transform"];
// Restore the bounds
CGRect tmpBounds = [aDecoder decodeCGRectForKey:#"bounds"];
CGFloat ratio = self.gameView.bounds.size.height / saveDeviceGameViewSize.height;
tmpBounds.size.width *= (saveDeviceGameViewSize.width * ratio);
tmpBounds.size.height *= self.gameView.bounds.size.height;
self.bounds = tmpBounds;
}
return self;
}
What about separating the view states between your iPhone and iPad version? For each device, if a configuration for that device hasn't been saved, just use the default? I haven't seen your UI, but I think in general a solution like this would work well, be easier to implement, and also follow users' expectations.
Very much depends on when you apply your transformation. I would propose the following steps when you load your view:
1. load the view bounds
2. load the view centre
3. load the transformation
There is also a problem with this code. You set your bounds after you set the center. This is completely wrong, because the bounds property will not be working always. Try to do the steps I've described and report back please with the result, but it should work.
Can self.gameView.bounds change depending on what device you're using? If the answer is yes, I see a problem because you're storing the centre after normalisation by the gameView bounds size, but when you restore centre you're un-normalising it by multiplying it by the stored value of gameView.bounds, rather than the value of gameView.bounds for the current device.
Also, the bit of code for // Restore the bounds looks wrong, because in the line that sets tmpBounds.size.width = you're doing a calculation involving a width and ratio that is a ratio of two widths. In other words, there's no height involved which looks wrong. Maybe it should be the following?
// note: height, not width, used on RHS
tmpBounds.size.width *= (saveDeviceGameViewSize.height * ratio);
In order to generally proceed with fixing this (if the above doesn't help): you need to
a) verify that the thing you're implementing makes sense (i.e. the algorithm in your head), and
b) verify that you're doing it right by analysing your code and doing some judicious debugging/NSLogging on the save + restore code
Please can someone advice me on this.
I have a cocos2d-iphone +box2d body I wish to move only in one direction(movement only from left to right of the iphone screen) using only the accelerometer controls and parallax scrolling. Please how do I do this as at the moment the body moves both to the left and right once the device is tilted. I do not want to use forces or impulse since I will NOT be enabling touch controls.
This is my accelerometer code :
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration
*)acceleration {
float32 accelerationFraction = acceleration.y * 6;
if (accelerationFraction < -1) {
accelerationFraction = -1;
} else if (accelerationFraction > 1) {
accelerationFraction = 1;
b2Vec2 gravity(-acceleration.y *10, acceleration.x *10);
world->SetGravity( gravity );
}
Thanks in advance for your help .
You should use mouseJoints. Look at this tutorial. There he explains exactly what you are trying to accomplish.
Hi,
can we find the coordinates of a UI element say UItextfield which is masked after rotation, if yes how is it possible?
Thanx in advance
I'm not sure whether I understand your question. If you want to know the coordinates of a UI element after your device was rotated, here's how you do it:
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
CGRect newFrame = someUIElement.frame;
int x = newFrame.origin.x; // x-Coordinate
int y = newFrame.origin.y; // y-Coordinate
// do stuff with coordinates
}
i have something like fabian answer while rotating the device first called method is - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
then -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
finally
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
method called so you can get the coordinates in this method.The main thing here is the object origin ll change not the size.this is the thing i am expecting from some sample app.
i am developing application which point towards the particular location, i have calculate angle between current coordinate to specific coordinate and my image is rotating by that difference but image rotation is fixed means when i change my direction the image is not moved it remain fix to specific postion, i want that the image should be moved aacording to the actual position where it is located(where we want to reach) thanks for the help in advance below is my code..
-(float) angleToRadians:(float) a {
return ((a/180)*M_PI);
}
- (float) getHeadingForDirectionFromCoordinate:(CLLocationCoordinate2D)fromLoc toCoordinate:(CLLocationCoordinate2D)toLoc
{
float fLat = [self angleToRadians:fromLoc.latitude];
float fLng = [self angleToRadians:fromLoc.longitude];
float tLat = [self angleToRadians:toLoc.latitude];
float tLng = [self angleToRadians:toLoc.longitude];
float result= atan2f(sin(tLng-fLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng));
return RadiansToDegrees(result);
}
- (void) scanButtonTouchUpInside {
UIImage *overlayGraphic = [UIImage imageNamed:#"GFI.jpg"];
overlayGraphicView = [[UIImageView alloc] initWithImage:overlayGraphic];
overlayGraphicView.frame = CGRectMake(50, 50, 50, 80);
[self addSubview:overlayGraphicView];
float angle =[self getHeadingForDirectionFromCoordinate:currentlocation toCoordinate:pointlocation];
if(angle < 0.0)
angle += 2*M_PI;
overlayGraphicView.transform=CGAffineTransformMakeRotation(angle);
}
Judging by the name of the method that is rotating the image: scanButtonTouchUpInside, I'm guessing that it is called only when a user hits a button. If it is only called once, I would expect the image to only rotate once, then remain fixed. In order to keep the image rotating, you need to put that code somewhere that is called repeatedly. A (cheap hack) way to test this would be to add this line to the end of your - (void)scanButtonTouchUpInside method:
[self performSelector:#selector(scanButtonTouchUpInside) withObject:nil afterDelay:0.25f];
This will make the method call fire repeatedly. One thing to note though: It seems that your calculation of the angle of rotation depends on a variable called currentLocation. This solution will only work if you are updating currentLocation appropriately.
EDIT:
Just a thought, you're currently calculating the angle of rotation based on the location of the device and the location of the destination. You're not taking into account compass bearing at all. Is this intentional? With this approach, your angle will never change unless the device actually moves. Any change in orientation will be ignored.
I need a way to create a collide effect, without the actual collision between the two images. Let me explain in more detail... If I have one fixed image and one image that is moving both images are on the same x coordinate at different positions. Basically I want the images appear to be colliding.I would want to run a check on the moving image like this...
If (front of moving image is clear)
{[move forward];}
else
{[stop];}
How would I implement this in code??? So that right before the moving image collides into the fixed image it stops, so that they appear to have collided.This check would also be running on a 1/60 NSTimer.
Any advice is welcome. Thank you.
Assuming the object is moving from the left
#define PIXELS_PER_FRAME 1
-(CGFloat) getCurrentX:(UIImage*)image
{
return image.frame.origin.x + image.frame.size.width;
}
-(void) moveImageToStableImage
{
CGFloat xTarget = stableImage.frame.origin.x;
if([self getCurrentX:movingImage] < xTarget)
{
movingImage.frame.origin.x += PIXELS_PER_FRAME;
[self performSelector:#selector(moveImageToStableImage) withObject:nil afterDelay:1.0/60];
}
}
But truth be told in this situation you would probably just be better off using an animation