我使用CMMotionManager在我的视图中移动按钮、图像等,因为设备是向前、向后、右、左倾斜的。我得到态度,俯仰和滚动,然后使用这些值的字符串,表示像素放置在屏幕上。
这是我如何获得信息的方法
motionManager = [[CMMotionManager alloc] init];
motionManager.deviceMotionUpdateInterval = 0.05f;
[motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2];
[formatter setRoundingMode: NSNumberFormatterRoundUp];
numberString = [formatter stringFromNumber:[NSNumber numberWithFloat:motion.attitude.roll /8]];
numberString1 = [formatter stringFromNumber:[NSNumber numberWithFloat:motion.attitude.pitch /8]];
}];我就是这样指派他们的。
NSString *deltax = numberString;
NSString *deltay = numberString1;
NSLog(@"xString;%@",numberString);
if ([deltax isEqualToString:@"-0.01"]) {
xString = @"160";}
else if ([deltax isEqualToString:@"-0.02"]) {
xString = @"161";}
else if ([deltax isEqualToString:@"-0.03"]) {
xString = @"162";}
else if ([deltax isEqualToString:@"-0.04"]) {
xString = @"163";}等。
我制作了它们,所以x轴在屏幕上不断地上下移动。即-.01与-.40、.01和.40相同。当您从-.01和.01the值上升到更大的值,从-.40值和4.4值得到更小的值时,它们的处理方法是一样的。我对y轴也做了同样的事情。-.01和.01为284,-.20和.20为264。然而,在这种情况下,数字从-.01上升,从.01下降。
以下是一些例子
//x axis
if ([deltax isEqualToString:@"-0.01"]) {
xString = @"160";}
else if ([deltax isEqualToString:@"-0.02"]) {
xString = @"161";}
else if ([deltax isEqualToString:@"-0.03"]) {
xString = @"162";}
else if ([deltax isEqualToString:@"-0.04"]) {
xString = @"163";}
else if ([deltax isEqualToString:@"-0.37"]) {
xString = @"156";}
else if ([deltax isEqualToString:@"-0.38"]) {
xString = @"157";}
else if ([deltax isEqualToString:@"-0.39"]) {
xString = @"158";}
else if ([deltax isEqualToString:@"-0.4"]) {
xString = @"159";}
else if ([deltax isEqualToString:@"0.01"]) {
xString = @"159";}
else if ([deltax isEqualToString:@"0.02"]) {
xString = @"158";}
else if ([deltax isEqualToString:@"0.03"]) {
xString = @"157"; }
else if ([deltax isEqualToString:@"0.04"]) {
xString = @"156";}
else if ([deltax isEqualToString:@"0.37"]) {
xString = @"163";}
else if ([deltax isEqualToString:@"0.38"]) {
xString = @"162";}
else if ([deltax isEqualToString:@"0.39"]) {
xString = @"161";}
else if ([deltax isEqualToString:@"0.4"]) {
xString = @"160";}
//y axis
if ([deltay isEqualToString:@"-0.01"]) {
yString = @"284";}
else if ([deltay isEqualToString:@"-0.02"]) {
yString = @"285";}
else if ([deltay isEqualToString:@"-0.03"]) {
yString = @"286";}
else if ([deltay isEqualToString:@"-0.04"]) {
yString = @"287";}
else if ([deltay isEqualToString:@"-0.17"]) {
yString = @"300"; }
else if ([deltay isEqualToString:@"-0.18"]) {
yString = @"301";}
else if ([deltay isEqualToString:@"-0.19"]) {
yString = @"302";}
else if ([deltay isEqualToString:@"-0.2"]) {
yString = @"303";}
else if ([deltay isEqualToString:@"0.01"]) {
yString = @"283";}
else if ([deltay isEqualToString:@"0.02"]) {
yString = @"282";}
else if ([deltay isEqualToString:@"0.03"]) {
yString = @"281";}
else if ([deltay isEqualToString:@"0.04"]) {
yString = @"280"; }
else if ([deltay isEqualToString:@"0.17"]) {
yString = @"267";}
else if ([deltay isEqualToString:@"0.18"]) {
yString = @"266";}
else if ([deltay isEqualToString:@"0.19"]) {
yString = @"265";}
else if ([deltay isEqualToString:@"0.2"]) {
yString = @"264";}这样,从一个方向到另一个方向的流动是连续的。
不过,我有个小问题。当手机向前倾斜并从.2 faceUp方向传递到.2 faceDown方向时。我有个急躁的动作。在faceUp、.2、按钮等等中,突然向左移动,当移动到faceDown .20时,它们就移到右边。否则,按钮等将以.19和-.19为中心,并返回到那里以正常运行(如预期的那样)。我试着打电话给DeviceOrientationFaceUp和FaceDown,但这似乎没有帮助。
是否有人对这种行为有任何经验和了解或有任何建议。
我还添加了这个部分来移动按钮上下和侧对侧。使用这种方法,按钮上下左右移动到任何位置的手机。
//used to assign numerical values
NSString *string2 = xString;
int n = [string2 intValue];
NSLog(@"n:%d",n);
NSString *string3 = xString1;
int p = [string3 intValue];
NSLog(@"p:%d",p);
NSString *string4 = yString;
int q = [string4 intValue];
NSLog(@"q:%d",q);
NSString *string5 = yString1;
int r = [string5 intValue];
NSLog(@"r:%d",r);
//used to move the buttons etc.
imageView2.center = CGPointMake(p, q);
imageView.center = CGPointMake(n -63, q);
imageframe.center = CGPointMake(n -63, q);
textView.center = CGPointMake(n -62, q - 184);
label1.center = CGPointMake(n + 97, q - 195 );
english.center = CGPointMake(n + 97, q - 159);这是一种视差运动。
发布于 2013-09-11 18:56:20
有几种反应:
gravity而不是attitude,因为它很好地代表了设备的物理方向。if语句,只需要一个表示视图应该如何放置的公式。UIView中(通常称为“容器视图”,不要与IB中同名的自定义容器控件混淆),然后移动容器视图。因此,如果使用autolayout,我可能具有以下属性:
@property (nonatomic, strong) CMMotionManager *motionManager;
@property CGFloat top;
@property CGFloat left;然后,我可以更新自动收费约束,如下所示:
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 0.05f;
self.top = self.topConstraint.constant;
self.left = self.leadingConstraint.constant;
[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
self.leadingConstraint.constant = self.left - motion.gravity.x / 8.0 * 100.0;
self.topConstraint.constant = self.top - motion.gravity.y / 8.0 * 100.0;
}];或者如果不使用自动收费表:
@property (nonatomic, strong) CMMotionManager *motionManager;
@property CGPoint originalCenter;和
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 0.05f;
self.originalCenter = self.containerView.center;
[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
self.containerView.center = CGPointMake(self.originalCenter.x - motion.gravity.x / 8.0 * 100.0, self.originalCenter.y - motion.gravity.y / 8.0 * 100.0);
}];坦率地说,让运动管理器在主队列中操作会让我感到不安,因此我可能(a)为运动更新创建一个NSOperationQueue,并且只更新一些类属性;(b)使用CADisplayLink (QuartzCore.framework的一部分)来更新视图(如果需要的话)。因此:
@property (nonatomic, strong) CMMotionManager *motionManager;
@property (nonatomic, strong) NSOperationQueue *motionQueue;
@property (nonatomic) CMAcceleration gravity;
@property (nonatomic) CGPoint originalCenter;
@property (nonatomic) BOOL updatePosition;
@property (nonatomic, strong) NSMutableArray *angles;
@property (nonatomic, strong) CADisplayLink *displayLink;和
- (void)viewDidDisappear:(BOOL)animated
{
[self stopDisplayLink];
[self.motionManager stopDeviceMotionUpdates];
self.motionManager = nil;
self.motionQueue = nil;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 0.05f;
self.motionQueue = [[NSOperationQueue alloc] init];
self.motionQueue.name = [[[NSBundle mainBundle] bundleIdentifier] stringByAppendingString:@".motion"];
self.originalCenter = self.containerView.center;
self.updatePosition = NO;
[self.motionManager startDeviceMotionUpdatesToQueue:self.motionQueue withHandler:^(CMDeviceMotion *motion, NSError *error) {
@synchronized(self) {
self.gravity = motion.gravity;
self.updatePosition = YES;
}
}];
[self startDisplayLink];
}
- (void)startDisplayLink
{
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void)stopDisplayLink
{
[self.displayLink invalidate];
self.displayLink = nil;
}
- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
@synchronized(self) {
if (!self.updatePosition)
return;
self.containerView.center = CGPointMake(self.originalCenter.x - self.gravity.x / 8.0 * 100.0, self.originalCenter.y - self.gravity.y / 8.0 * 100.0);
self.updatePosition = NO;
}
}发布于 2014-05-23 03:05:12
我做了以下工作:在一个可调窗口内取最大值和最小值(闪烁噪声)并取平均值。不再振荡了!
下面是我的代码,以避免在五月应用程序中闪烁:
float xAxis,yAxis, zAxis;
xAxis = self.manager.accelerometerData.acceleration.x;
yAxis = self.manager.accelerometerData.acceleration.y;
zAxis = self.manager.accelerometerData.acceleration.z;
// returns if the phone is lying on the table:
if (zAxis < -0.8 || zAxis > 0.8) return;
CGFloat angle = atan2f(xAxis, yAxis ); // The angle!!!
float noise = 0.011; // Flicker noise (the noise you want to filter)
// max and min are global variables
if (angle > max){
max = angle;
min = max - noise;
}
if (angle < min){
min = angle;
max = min + noise;
}
// Average: (no flickering):
angle = min + (max - min) / 2.0;https://stackoverflow.com/questions/18729788
复制相似问题