我有一个非常快的滚动UIScrollView,包含许多视图,这些视图在重用时会被更新。
当滚动视图快速滚动时,我希望视图忽略它们可能需要做的任何新绘图(这需要从磁盘(如图像等)获取信息)。
我考虑创建一个CADisplayLink (或者在本例中是一个NSTimer),并计算在键窗口中更改的视图位置,如下所示
- (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;
}
}但是,当视图非常快地更改位置时,不定期调用计时器回调。
因此,我不知道什么观点的立场变化是定期的基础上。
有更好的方法吗?
编辑
这里有一个可能的解决方案(本着问题的精神),这是我为快速滚动(不一定是在您可以访问您的代表的滚动视图中)提出的。
- (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;}
}];发布于 2014-04-28 08:35:04
我不会使用NSTimer,而是使用UIScrollView delegate来完成这个任务。
要计算滚动速度:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat scrollSpeed = scrollView.contentOffset.y - previousScrollViewYOffset;
previousTableViewYOffset = scrollView.contentOffset.y;
}然后你就可以:
for( UIViewSubclass *subview in scrollView ){
subView.shouldUpdateCoverPhoto = scrollSpeed < kMaxScrollSpeed;
}发布于 2014-04-28 08:17:27
UIScrollView委托方法如何:
– scrollViewWillEndDragging:withVelocity:targetContentOffset:?不是你想要的吗?
https://stackoverflow.com/questions/23335857
复制相似问题