动画UICollectionView contentOffset不显示不可见的细胞 [英] Animating UICollectionView contentOffset does not display non-visible cells
问题描述
我工作的一些股票一样的功能,并正在使用 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 {
TickerElementCell *电池=(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屋!