【发布时间】:2014-04-28 08:13:57
【问题描述】:
我有一个滚动速度非常快的 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;}
}];
【问题讨论】:
标签: ios objective-c uiview uiscrollview nstimer