• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

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

[复制链接]
菜鸟教程小白 发表于 2022-12-13 09:51:37 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在尝试使用动画 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 selectorselector(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];
    });
  }
}



Best Answer-推荐答案


有两个问题:

  • 关于同时更改标签的帧动画,问题在于更改标签的文本会导致重新应用约束。正确的解决方案是不通过更改框架来制作动画,而是通过更改规定框架的约束然后调用 layoutIfNeeded在动画 block 中。见 Animating an image view to slide upwards
  • 关于标签的动画:
  • 您无法保证可以如此快速地处理更新。 (事实上​​,您应该计划永远不会超过 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 selectorselector(handleDisplayLink];
        self.startTime = CACurrentMediaTime();
        [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    }
    
    - (void)stopDisplayLink {
        [self.displayLink invalidate];
        self.displayLink = nil;
    }
    
    - (void)handleDisplayLinkCADisplayLink *)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 (来自主线程)并且当 View 动画时,您的标签将在一秒钟内从 0 更新到 100:
    [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/

    回复

    使用道具 举报

    懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关注0

    粉丝2

    帖子830918

    发布主题
    阅读排行 更多
    广告位

    扫描微信二维码

    查看手机版网站

    随时了解更新最新资讯

    139-2527-9053

    在线客服(服务时间 9:00~18:00)

    在线QQ客服
    地址:深圳市南山区西丽大学城创智工业园
    电邮:jeky_zhao#qq.com
    移动电话:139-2527-9053

    Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap