在 iOS 8 中设置中心后视图跳回
View jumps back after setting center in iOS 8
我是 Xcode 的新手,我的应用程序中有计数器问题。
当我用计时器计算分数时,玩家(桨)跳到原来的地方
第一次(中间)
每次定时器计数时。
那么我应该怎么做才能让球拍保持原样?
还有其他计算点数的方法吗?
如何用滑动或重力传感器控制播放器并不重要,
但在这个例子中,我用滑动来控制它。
而且这个问题只出现在 ios 8.0> 中,而不出现在 ios 7.
这里是一些代码:
.h 文件:
int ScoreNumber;
@interface ViewController : UIViewController{
IBOutlet UILabel *ScoreLabel;
NSTimer *Timer;
}
@property (nonatomic, strong)IBOutlet UIImageView *paddle;
@property (nonatomic) CGPoint paddleCenterPoint;
@end
.m 文件:
@implementation ViewController
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
CGFloat yPoint = self.paddleCenterPoint.y;
CGPoint paddleCenter = CGPointMake(touchLocation.x, yPoint);
self.paddle.center = paddleCenter;
}
-(void)Score{
ScoreNumber = ScoreNumber +1;
ScoreLabel.text = [NSString stringWithFormat:@"%i", ScoreNumber];
}
-(void)viewDidLoad {
Timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(Score) userInfo:nil repeats:YES];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
在iOS8中,自动布局为王,设置center
不会改变布局约束。这与计时器无关。它与更改标签的文本有关。当发生这种情况时,它会触发整个视图的布局,并重新声明约束(通过 layoutIfNeeded
)。即使您可能没有在 IB 中设置任何约束,Xcode 也会在构建过程中自动插入它们。
有几种解决方法。首先,您可以在 viewDidLoad
中以编程方式插入球拍,这将绕过约束系统。对于这个特定问题,这可能没问题(甚至可能是我个人的做法)。像这样:
@interface ViewController ()
@property (nonatomic, strong) UIView *paddle;
@end
@implementation ViewController
- (void)viewDidLoad {
self.paddle = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 50)];
self.paddle.backgroundColor = [UIColor blueColor];
[self.view addSubview:self.paddle];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
self.paddle.center = CGPointMake(touchLocation.x, self.paddle.center.y);
}
@end
但是我们如何在不丢弃约束的情况下解决这个问题呢?好吧,我们可以修改约束。在 IB 中添加您的桨视图,并为左侧、底部、宽度和高度添加约束。然后为水平和宽度约束创建一个 IB 出口。
编辑水平 Space 约束以从第一项和第二项中删除 "Relative to margin":
现在,您可以修改约束而不是中心:
@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIView *paddle;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *paddleHorizontalConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *paddleWidthConstraint;
@end
@implementation ViewController
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
CGFloat width = self.paddleWidthConstraint.constant;
self.paddleHorizontalConstraint.constant = touchLocation.x - width/2;
}
@end
您需要阅读宽度限制,因为 frame
或 bounds
在调用 viewDidLayoutSubviews:
之前可能不正确。但是您不想在那里更新约束,因为那样会强制使用另一个布局。
我是 Xcode 的新手,我的应用程序中有计数器问题。
当我用计时器计算分数时,玩家(桨)跳到原来的地方 第一次(中间) 每次定时器计数时。
那么我应该怎么做才能让球拍保持原样? 还有其他计算点数的方法吗?
如何用滑动或重力传感器控制播放器并不重要, 但在这个例子中,我用滑动来控制它。 而且这个问题只出现在 ios 8.0> 中,而不出现在 ios 7.
这里是一些代码:
.h 文件:
int ScoreNumber;
@interface ViewController : UIViewController{
IBOutlet UILabel *ScoreLabel;
NSTimer *Timer;
}
@property (nonatomic, strong)IBOutlet UIImageView *paddle;
@property (nonatomic) CGPoint paddleCenterPoint;
@end
.m 文件:
@implementation ViewController
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
CGFloat yPoint = self.paddleCenterPoint.y;
CGPoint paddleCenter = CGPointMake(touchLocation.x, yPoint);
self.paddle.center = paddleCenter;
}
-(void)Score{
ScoreNumber = ScoreNumber +1;
ScoreLabel.text = [NSString stringWithFormat:@"%i", ScoreNumber];
}
-(void)viewDidLoad {
Timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(Score) userInfo:nil repeats:YES];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
在iOS8中,自动布局为王,设置center
不会改变布局约束。这与计时器无关。它与更改标签的文本有关。当发生这种情况时,它会触发整个视图的布局,并重新声明约束(通过 layoutIfNeeded
)。即使您可能没有在 IB 中设置任何约束,Xcode 也会在构建过程中自动插入它们。
有几种解决方法。首先,您可以在 viewDidLoad
中以编程方式插入球拍,这将绕过约束系统。对于这个特定问题,这可能没问题(甚至可能是我个人的做法)。像这样:
@interface ViewController ()
@property (nonatomic, strong) UIView *paddle;
@end
@implementation ViewController
- (void)viewDidLoad {
self.paddle = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 50)];
self.paddle.backgroundColor = [UIColor blueColor];
[self.view addSubview:self.paddle];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
self.paddle.center = CGPointMake(touchLocation.x, self.paddle.center.y);
}
@end
但是我们如何在不丢弃约束的情况下解决这个问题呢?好吧,我们可以修改约束。在 IB 中添加您的桨视图,并为左侧、底部、宽度和高度添加约束。然后为水平和宽度约束创建一个 IB 出口。
编辑水平 Space 约束以从第一项和第二项中删除 "Relative to margin":
现在,您可以修改约束而不是中心:
@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIView *paddle;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *paddleHorizontalConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *paddleWidthConstraint;
@end
@implementation ViewController
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
CGFloat width = self.paddleWidthConstraint.constant;
self.paddleHorizontalConstraint.constant = touchLocation.x - width/2;
}
@end
您需要阅读宽度限制,因为 frame
或 bounds
在调用 viewDidLayoutSubviews:
之前可能不正确。但是您不想在那里更新约束,因为那样会强制使用另一个布局。