动画UICollectionView contentOffset不显示不可见的细胞 [英] Animating UICollectionView contentOffset does not display non-visible cells

查看:390
本文介绍了动画UICollectionView contentOffset不显示不可见的细胞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一些股票一样的功能,并正在使用 UICollectionView 。它最初是一个滚动视图,但我们图个的CollectionView将使它更容易添加/删除单元格。

我的动画用的CollectionView如下:

   - (无效){beginAnimation
    [UIView的animateWithDuration:((self.collectionView.collectionViewLayout.collectionViewContentSize.width - self.collectionView.contentOffset.x)/ 75)延迟:0选项:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionRepeat | UIViewAnimationOptionBeginFromCurrentState)动画:^ {
        self.collectionView.contentOffset = CGPointMake(self.collectionView.collectionViewLayout.collectionViewContentSize.width,0);
    }完成:无];
}

这为滚动视图工作正常,并且动画与集合视图发生。但是,只有在动画结束可见的细胞实际上呈现。调整contentOffset不会导致 cellForItemAtIndexPath 被调用。我怎样才能得到这些细胞呈现时contentOffset变化?

编辑:
对于多一点参考(如果不知道它是太大的帮助):

   - (UICollectionViewCell *)的CollectionView:(UICollectionView *)的CollectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    Tick​​erElementCell *电池=(TickerElementCell *)的CollectionView dequeueReusableCellWithReuseIdentifier:@TickerElementCellforIndexPath:indexPath];
    cell.ticker = [self.fetchedResultsController objectAtIndexPath:indexPath];
    返回细胞;
} - (无效)controllerDidChangeContent:(NSFetchedResultsController *)控制器{    // ...    [个体经营loadTicker]
} - (无效){loadTicker    // ...    如果(self.animating){
        [个体经营updateAnimation]
    }
    其他{
        [个体经营beginAnimation]
    }
} - (无效){beginAnimation    如果(self.animating){
        [个体经营endAnimation]
    }    如果([self.tickerElements计数]放大器;&安培;!self.animating和放大器;&安培;!self.paused){
        self.animating = YES;
        self.collectionView.contentOffset = CGPointMake(1,0);
        [UIView的animateWithDuration:((self.collectionView.collectionViewLayout.collectionViewContentSize.width - self.collectionView.contentOffset.x)/ 75)延迟:0选项:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionBeginFromCurrentState)动画:^ {
            self.collectionView.contentOffset = CGPointMake(self.collectionView.collectionViewLayout.collectionViewContentSize.width,0);
        }完成:无];
    }
}


解决方案

您可以尝试使用CADisplayLink自己驱动动画。这是不是太难成立,因为你使用的是线性动画曲线反正。这里有一个可以为你工作的基本实现:

  @属性(非原子,强)CADisplayLink * DisplayLink的;
@属性(非原子,分配)CFTimeInterval lastTimerTick;
@属性(非原子,分配)CGFloat的animationPointsPerSecond;
@属性(非原子,分配)CGPoint finalContentOffset; - (无效){beginAnimation
    self.lastTimerTick = 0;
    self.animationPointsPerSecond = 50;
    self.finalContentOffset = CGPointMake(...,...);
    self.displayLink = [CADisplayLink displayLinkWithTarget:自我选择:@选择(displayLinkTick :)]。
    [self.displayLink setFrameInterval:1];
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
} - (无效){endAnimation
    [self.displayLink无效]
    self.displayLink =零;
} - (无效){displayLinkTick
    如果(self.lastTimerTick = 0){
        self.lastTimerTick = self.displayLink.timestamp;
        返回;
    }
    CFTimeInterval currentTimestamp = self.displayLink.timestamp;
    CGPoint newContentOffset = self.collectionView.contentOffset;
    newContentOffset.x + = self.animationPointsPerSecond *(currentTimestamp - self.lastTimerTick)
    self.collectionView.contentOffset = newContentOffset;    self.lastTimerTick = currentTimestamp;    如果(newContentOffset.x> = self.finalContentOffset.x)
        [个体经营endAnimation]
}

I'm working on some ticker-like functionality and am using a UICollectionView. It was originally a scrollView, but we figure a collectionView will make it easier to add/remove cells.

I am animating the collectionView with the following:

- (void)beginAnimation {
    [UIView animateWithDuration:((self.collectionView.collectionViewLayout.collectionViewContentSize.width - self.collectionView.contentOffset.x) / 75) delay:0 options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionRepeat | UIViewAnimationOptionBeginFromCurrentState) animations:^{
        self.collectionView.contentOffset = CGPointMake(self.collectionView.collectionViewLayout.collectionViewContentSize.width, 0);
    } completion:nil];
}

This works fine for the scroll view, and the animation is happening with the collection view. However, only the cells that are visible at the end of the animation are actually rendered. Adjusting the contentOffset is not causing cellForItemAtIndexPath to be called. How can I get the cells to render when the contentOffset changes?

EDIT: For a bit more reference (not sure if it's much help):

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    TickerElementCell *cell = (TickerElementCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"TickerElementCell" forIndexPath:indexPath];
    cell.ticker = [self.fetchedResultsController objectAtIndexPath:indexPath];
    return cell;
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {

    // ...

    [self loadTicker];
}

- (void)loadTicker {

    // ...

    if (self.animating) {
        [self updateAnimation];
    }
    else {
        [self beginAnimation];
    }
}

- (void)beginAnimation {

    if (self.animating) {
        [self endAnimation];
    }

    if ([self.tickerElements count] && !self.animating && !self.paused) {
        self.animating = YES;
        self.collectionView.contentOffset = CGPointMake(1, 0);
        [UIView animateWithDuration:((self.collectionView.collectionViewLayout.collectionViewContentSize.width - self.collectionView.contentOffset.x) / 75) delay:0 options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionBeginFromCurrentState) animations:^{
            self.collectionView.contentOffset = CGPointMake(self.collectionView.collectionViewLayout.collectionViewContentSize.width, 0);
        } completion:nil];
    }
}

解决方案

You could try using a CADisplayLink to drive the animation yourself. This is not too hard to set up since you are using a Linear animation curve anyway. Here's a basic implementation that may work for you:

@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic, assign) CFTimeInterval lastTimerTick;
@property (nonatomic, assign) CGFloat animationPointsPerSecond;
@property (nonatomic, assign) CGPoint finalContentOffset;

-(void)beginAnimation {
    self.lastTimerTick = 0;
    self.animationPointsPerSecond = 50;
    self.finalContentOffset = CGPointMake(..., ...);
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTick:)];
    [self.displayLink setFrameInterval:1];
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}

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

-(void)displayLinkTick {
    if (self.lastTimerTick = 0) {
        self.lastTimerTick = self.displayLink.timestamp;
        return;
    }
    CFTimeInterval currentTimestamp = self.displayLink.timestamp;
    CGPoint newContentOffset = self.collectionView.contentOffset;
    newContentOffset.x += self.animationPointsPerSecond * (currentTimestamp - self.lastTimerTick)
    self.collectionView.contentOffset = newContentOffset;

    self.lastTimerTick = currentTimestamp;

    if (newContentOffset.x >= self.finalContentOffset.x)
        [self endAnimation];
}

这篇关于动画UICollectionView contentOffset不显示不可见的细胞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆