我已使用导航控制器设置了一些视图。我希望能够在握手机时回到原始视图。首先,这是我在AppDelegate中的代码片段:
- (void)startAccelerometerUpdates
{
[motionManager startDeviceMotionUpdatesToQueue:queue withHandler:^(CMDeviceMotion *motion, NSError *error) {
// based from
// http://stackoverflow.com/questions/5214197/simple-iphone-motion-detect/5220796#5220796
float accelerationThreshold = 1; // or whatever is appropriate - play around with different values
CMAcceleration userAcceleration = motion.userAcceleration;
if (fabs(userAcceleration.x) > accelerationThreshold ||
fabs(userAcceleration.y) > accelerationThreshold ||
fabs(userAcceleration.z) > accelerationThreshold) {
if(!self->isRoot) {
NSLog(@"Stopping motion manager");
[motionManager stopDeviceMotionUpdates];
NSLog(@"popping to top view controller");
[navcon popToRootViewControllerAnimated:YES];
NSLog(@"Done popping");
}
}
}];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
.....
motionManager = [[CMMotionManager alloc] init];
motionManager.deviceMotionUpdateInterval = .5;
isRoot = malloc(sizeof(BOOL));
self->isRoot = NO;
[self startAccelerometerUpdates];
[navcon pushViewController:main animated:NO];
....
}
我原本以为会立即调用popToRoot。但是,大约需要30秒。有趣的是,您可以按下以手动返回上一页的顶部按钮此时不起作用。手机似乎正在做很多工作来冻结按钮。所以,我肯定在这里做错了。
它认为我可能会多次调用popToRootViewController,所以我在代码中添加了一个“isRoot”检查(请不要分心为什么BOOL是一个指针,我有理由这样做。) / p>
答案 0 :(得分:4)
您的动作处理程序块似乎打算在后台队列上运行。 UIKit方法(如popToRootViewController)只应在主线程上调用,当你不遵守该规则时的行为通常与你所描述的类似。
-performSelectorOnMainThread:withObject:waitUntilDone
是确保您的UIKit代码在主线程上运行的最简单方法,但由于-popToRootViewControllerAnimated:
采用非对象参数,因此需要更多工作。最简单的方法是添加另一个不带参数的方法:
-(void)popToRootView {
[navcon popToRootViewControllerAnimated:YES];
}
然后更新您的块以在主线程上调用该方法:
if(!self->isRoot) {
[motionManager stopDeviceMotionUpdates];
[self performSelectorOnMainThread:@selector(popToRootView) withObject:nil waitUntilDone:NO];
}