gpt4 book ai didi

ios - 具有同步计数线程的 UIView 动画

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:13:15 25 4
gpt4 key购买 nike

我正在尝试使用动画 block 来扩展 UIView,效果非常好。但是,我希望 UILabel 从 0 开始,每 0.01 秒加 1,直到达到 100。我在动画之后创建了一个线程来完成这个并且它有效但是它导致我设置的动画什么也不做。我尝试过很多不同的东西,但没有运气。实现这一目标的最佳方法是什么?

我最简单的尝试与所有其他人的结果相同:

[UIView animateWithDuration:1 animations:^{
_lView.frame = CGRectMake(_lView.frame.origin.x,_lView.frame.origin.y+_lView.frame.size.height,_lView.frame.size.width,-500);
}];

[[[NSThread alloc]initWithTarget:self selector:@selector(startcounting) object:nil]start];


-(void)startcounting{
for(int x=0; x<100; x++){
[NSThread sleepForTimeInterval:0.01];
++_mcount;
dispatch_async(dispatch_get_main_queue(), ^{
_cLabel.text = [NSString stringWithFormat:@"%i",_mcount];
});
}
}

最佳答案

有两个问题:

  1. 关于同时更改标签的帧动画,问题在于更改标签的文本会导致重新应用约束。正确的解决方案是不通过更改帧来设置动画,而是通过更改指示帧的约束,然后在动画 block 中调用 layoutIfNeeded。参见 Animating an image view to slide upwards

  2. 关于标签的动画:

    • 您无法保证可以如此快速地处理更新。 (事实上​​ ,您应该计划永远不会超过 60 fps。)

    • 即使您能够充分降低更新的频率,您也永远无法保证它们会以恒定的速率进行处理(其他因素总是会阻塞主线程几毫秒,从而产生数字递增不一致)。

    因此,您应该改用计时器(或者更好的“显示链接”,它类似于计时器,但协调以在屏幕准备好刷新时调用),计算耗时(这样计数器不会受到其他事情的影响,但该值将从 0 快速变为 100,足以产生您正在寻找的效果),并相应地更新标签。例如:

    @interface ViewController ()

    @property (nonatomic, strong) CADisplayLink *displayLink;
    @property (nonatomic) CFTimeInterval startTime;

    @property (weak, nonatomic) IBOutlet UILabel *label;

    @end

    @implementation ViewController

    - (void)startDisplayLink {
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
    self.startTime = CACurrentMediaTime();
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    }

    - (void)stopDisplayLink {
    [self.displayLink invalidate];
    self.displayLink = nil;
    }

    - (void)handleDisplayLink:(CADisplayLink *)displayLink {
    CFTimeInterval elapsed = CACurrentMediaTime() - self.startTime;

    if (elapsed < 1) {
    self.label.text = [NSString stringWithFormat:@"%.0f", elapsed * 100.0];
    } else {
    self.label.text = @"100";
    [self stopDisplayLink];
    }
    }

因此,结合这两点,只需调整约束(在将导出添加到约束之后)并调用 startDisplayLink(从主线程),您的标签将从 0 更新到 100 View 动画时的一秒跨度:

[self startDisplayLink];
self.topConstraint.constant += self.lView.frame.size.height;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
}];

关于ios - 具有同步计数线程的 UIView 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32001755/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com