首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用NSTimer或CADisplayLink查找NSTimer或CADisplayLink的移动速度

使用NSTimer或CADisplayLink查找NSTimer或CADisplayLink的移动速度
EN

Stack Overflow用户
提问于 2014-04-28 08:13:57
回答 2查看 148关注 0票数 0

我有一个非常快的滚动UIScrollView,包含许多视图,这些视图在重用时会被更新。

当滚动视图快速滚动时,我希望视图忽略它们可能需要做的任何新绘图(这需要从磁盘(如图像等)获取信息)。

我考虑创建一个CADisplayLink (或者在本例中是一个NSTimer),并计算在键窗口中更改的视图位置,如下所示

代码语言:javascript
复制
- (void)setupUpdateTimer
{
    self.shouldUpdateCoverPhoto = YES;
    self.previousFrame = CGRectNull;
    NSTimer *timer = [NSTimer timerWithTimeInterval:UpdateInterval target:self selector:@selector(timerUpdate:) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    self.updateTimer = timer;

}

-(void)timerUpdate:(NSTimer *)timer
{
    CGRect currentFrame = [[UIApplication sharedApplication].keyWindow convertRect:self.frame fromView:self.superview];
    CGRect previousFrame = self.previousFrame;
    self.previousFrame = currentFrame;
    if (CGRectEqualToRect(previousFrame, CGRectNull))
    {
        self.shouldUpdateCoverPhoto = YES;
        return;
    }

    CGFloat distance = ABS(currentFrame.origin.y - previousFrame.origin.y);
    CGFloat speed = ABS(distance/UpdateInterval);
    DLog(@"Speed is %f",speed);
    if (speed < 1000)
    {

        self.shouldUpdateCoverPhoto = YES;
    } else {

        self.shouldUpdateCoverPhoto = NO;
    }
}

但是,当视图非常快地更改位置时,不定期调用计时器回调。

因此,我不知道什么观点的立场变化是定期的基础上。

有更好的方法吗?

编辑

这里有一个可能的解决方案(本着问题的精神),这是我为快速滚动(不一定是在您可以访问您的代表的滚动视图中)提出的。

代码语言:javascript
复制
- (void)setupUpdateTimer
{
    self.shouldUpdateCoverPhotoOnSlowLoop = NO;
    self.previousFrame = CGRectNull;
    self.scrollSpeed = 0;

    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(checkNeedsUpdate:)];
    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

-(void)checkNeedsUpdate:(CADisplayLink *)link
{

    CGRect currentFrame = [[UIApplication sharedApplication].keyWindow convertRect:self.frame fromView:self.superview];
    CGRect previousFrame = self.previousFrame;
    self.previousFrame = currentFrame;
    if (CGRectEqualToRect(previousFrame, CGRectNull))
    {
        self.scrollSpeed = 0;
        return;
    }

    CGFloat distance = ABS(currentFrame.origin.y - previousFrame.origin.y);
    CGFloat duration = link.duration;
    CGFloat speed = ABS(distance/duration);


    self.scrollSpeed = speed;
    if (self.scrollSpeed < ThreasholdSpeedForCoverPhotoUpdate && self.shouldUpdateCoverPhotoOnSlowLoop)
    {
        [self setCoverPhotoForUser:_user];
    }

}

-(void)setCoverPhotoForUser:(id <InviGenericUserProtocol>)user
{
    if (self.scrollSpeed > ThreasholdSpeedForCoverPhotoUpdate && self.coverPhotoImageView.image != nil)
    {
        self.shouldUpdateCoverPhotoOnSlowLoop = YES;
        //DLog(@"Scroll speed %f greater than threashold %d - Not updating cover photo",self.scrollSpeed,ThreasholdSpeedForCoverPhotoUpdate);
        return;
    }
    self.shouldUpdateCoverPhotoOnSlowLoop = NO;

    [self loadCoverPhotoForUser:user completion:^(UIImage *image){
       dispatch_async(dispatch_get_main_queue(),^{self.coverPhotoImageView.image = image;}
}];
EN

回答 2

Stack Overflow用户

发布于 2014-04-28 08:35:04

我不会使用NSTimer,而是使用UIScrollView delegate来完成这个任务。

要计算滚动速度:

代码语言:javascript
复制
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat scrollSpeed = scrollView.contentOffset.y - previousScrollViewYOffset;
    previousTableViewYOffset = scrollView.contentOffset.y;
}

然后你就可以:

代码语言:javascript
复制
for( UIViewSubclass *subview in scrollView ){
    subView.shouldUpdateCoverPhoto = scrollSpeed < kMaxScrollSpeed;
}
票数 1
EN

Stack Overflow用户

发布于 2014-04-28 08:17:27

UIScrollView委托方法如何:

代码语言:javascript
复制
– scrollViewWillEndDragging:withVelocity:targetContentOffset:?

不是你想要的吗?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23335857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档