At a spot in my game there is a brief use of the accelerometer. I use this code:
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 1.0f/60.0f;
to start the accelerometer and then update it using:
- (void)accelerometer:(UIAccelerometer *)accellerometer didAccelerate:(UIAcceleration *)acceleration {
if (whichLevel == 24) {
//Blah blah blah, using accelerometer
} else {
//Turn accelerometer off somehow?
}
//I have found out using this:
NSLog(#"Accelerometer being used");
//That the accelerometer is being used after I start it in the game.
}
And of course, in the .h I put a
This sort of code is used in more than a few tutorials-- But my point is, this is only used for a brief period, and I would like a way to turn it off while I am not using it. (Which none of the tutorials show you how to do)
Apple seems to say here: http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html
-- that you should use
[motionManager stopAccelerometerUpdates];
but apparently you have to set it up that way in order to stop it that way. Do I have to change how I set it up in order to end it?? Or can I end it using what I have?
Thanks in advance,
The Me
Setting the accelerometer’s delegate to nil should let it know that you don’t need its updates anymore. It still might not get powered off entirely—the system watches it to deliver orientation-change events, for instance—but your app won’t be responsible for that.
Related
I have a for....loop and the UI then is blocked when in the loop.
Is the accelerometer also blocked?
I have following code in viewDidLoad
- (void)viewDidLoad{
[super viewDidLoad];
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 1.0f/60.0f;
}
and further down
- (void)accelerometer:(UIAccelerometer *)acel didAccelerate:(UIAcceleration *)acceleration {
acc=acceleration.x;
}
then an IBAction connected to a button which starts a loop
- (IBAction)doSomething {
for (int n = 1; n<=100;n++) {
// do someting in the loop
NSLog(#"x: %g", acc);
}
}
when logging the accelerometer x value it shows only the first value when the button is pressed and does not update when the loop is running. The same first value is repeating continuously.
Is there a way to log the acceleration when in the loop?
It would seem that UIAccelerometer needs the main thread so is getting blocked by the for...loop. Core Motion also has an accelerometer property in the CMMotionManager object that can report acceleration, and does better backgrounding since it's what Nike+ uses. There are two ways to access it - a pull method where you get the data directly, or a call-back. To be honest, I just tried it and couldn't get the call-back to work (mostly because it requires NSOperationQueue and I don't have much experience with that so I'm probably putting it on the wrong queue), but if you're ok with pulling data, which your approach seems to need, then this works:
CMMotionManager *motionManager = [[CMMotionManager alloc] init];
[motionManager startAccelerometerUpdates];
for (int i = 0; i < 10000; i++)
{
NSLog(#"Acceleration: %f", motionManager.accelerometerData.acceleration.x);
}
I just tried it on a device and the values reported in the for...loop update with the current acceleration.
Source: UIBackgroundModes and UIAccelerometer
i'm new to xcode and objective c, so be indulgent :)
i wrote an app where i can move a small ball over the display using the accelerometer.
in addition i want to output the accelerometer data on the display.
the problem is, when i want to output the data the ball won't move.
thanks for help!
xLabel.text = [NSString stringWithFormat:#"x: %f.02", acceleration.x];
yLabel.text = [NSString stringWithFormat:#"y: %f.02", acceleration.y];
zLabel.text = [NSString stringWithFormat:#"z: %f.02", acceleration.z];
Here's the initializing code:
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer]; //Share reference
accel.delegate = self;
accel.updateInterval = 1.0f / 60.0f;
That may be because you trying to both the tasks on main thread which is not possible simultaneously.
I think you can use Core animation (which uses its own thread to perform its operations) to move object instead of directly changing frame of the object (which requires main thread).
I have seen many tutorials over internet to detect blow in iPhone but my app's requirement is that I need to detect single blow and double blow both so that if user blow single time it can perform action a and if the user blow two times together then to perform action b.
Any way to do this?
Thanks all,
Surely if you know how to detect a single blow, you could just have a timer with a threshold & see if another blow happens within that time? Something like -
-(void)userDidBlow {
if (hasBlownOnce) {
hasBlownOnce = NO;
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(singleBlowTimedOut) object:nil];
// do double-blow stuff
} else {
hasBlownOnce = YES;
[self performSelector:#selector(singleBlowTimedOut) withObject:nil afterDelay:kDoubleBlowTime];
}
}
-(void)singleBlowTimedOut {
hasBlownOnce = NO;
// do single-blow stuff
}
I haven't tested it, but it looks ok :)
What i want to do is read the acceleration.y and do something like:
if (acceleration.y > 0.8) {
// Do something
}
As didAccelerate is deprecated I wonder how to get the y-value:
motionManager = [[[CMMotionManager alloc] init] autorelease];
motionManager.accelerometerUpdateInterval = kUpdateInterval;
if (motionManager.accelerometerAvailable) {
[motionManager startAccelerometerUpdates];
}
else {
//this device doesn't have accelerometer notice somewhere??
}
- (void)startAccelerometerUpdates {
// READ Y-VALUE?????
}
I want to use raw accelerometer data so the app also works on 3GS. Is it possible to read the Y-value?
EDIT: the answer below is deprecated, check these posts for the right way.
Old answer:
Use a UIAccelerometer singleton instance for this, for example in your AppDelegate
//in your launching method
UIAccelerometer * accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
//delegate method:
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{
// use the y-property of the acceleration
}
Look at the CMMotionManager class reference and search section named "Handing Motion Updates at Specified Intervals". In the "Accelerometer" bullet, it says
Set the accelerometerUpdateInterval property to specify an update interval. Call the startAccelerometerUpdatesToQueue:withHandler: method, passing in a block of type CMAccelerometerHandler. Accelerometer data is passed into the block as CMAccelerometerData objects.
CMAccelerometerData has a reference to CMAcceleration which is a struct that holds per axis acceleration.
I'm trying to integrate my game with Game Center and encountered this problem:
When user is authenticated for a first time, Game Center shows its UI for setting up the profile.
My problem is that I can not detect when this windows is shown - I want to pause my game at that moment and not play any sounds.
viewWillDisapper, viewDidDisapper in UIViewController are not called, neither are any of AppDelegate methods are called at this time.
I think I know how detect alert views (using changing key window notification), but that Account windows still is not detected there.
Is there any way to do this?
Building on executor21's answer here, I put this together which seems to do the trick in early testing. You can probably adapt it into something less fragile. It is built on the premise that the Game Center notification gets its own window, and it has exactly one subview of type GKGameEventView:
+(BOOL)isGameCenterNotificationUp
{
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *win in windows)
{
NSArray *winSubViews = [win subviews];
if([winSubViews count] == 1)
{
Class gcNotificationClass = NSClassFromString(#"GKGameEventView");
if(gcNotificationClass && ([[winSubViews objectAtIndex:0] isKindOfClass:gcNotificationClass]))
{
return YES;
}
}
}
return NO;
}