在 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

您需要阅读宽度限制,因为 framebounds 在调用 viewDidLayoutSubviews: 之前可能不正确。但是您不想在那里更新约束,因为那样会强制使用另一个布局。