Objective c 淡入/淡出UIScrollView';s的内容,就像Mobile Safari在其选项卡中所做的一样
注意:我在下面的更新答案中添加了我的新解决方案。 我试图重现我们在iPhone/iPod touch上的Mobile Safari标签中看到的效果 基本上,它是一个UIScrollView,包含4个可重用的UIView(就像环形缓冲区一样),并水平滚动。滚动时,UIView的不透明度将随偏移量无缝淡入/淡出 目前,我在Objective c 淡入/淡出UIScrollView';s的内容,就像Mobile Safari在其选项卡中所做的一样,objective-c,iphone,cocoa-touch,uiscrollview,core-animation,Objective C,Iphone,Cocoa Touch,Uiscrollview,Core Animation,注意:我在下面的更新答案中添加了我的新解决方案。 我试图重现我们在iPhone/iPod touch上的Mobile Safari标签中看到的效果 基本上,它是一个UIScrollView,包含4个可重用的UIView(就像环形缓冲区一样),并水平滚动。滚动时,UIView的不透明度将随偏移量无缝淡入/淡出 目前,我在-(void)scrollViewDidScroll:(UIScrollView*)scrollView中完成所有脏工作。例如从UIScrollView获取contentOffse
-(void)scrollViewDidScroll:(UIScrollView*)scrollView
中完成所有脏工作。例如从UIScrollView获取contentOffset,确定分页操作,计算contentOffset和每个UIView位置之间的增量,并在调用scrollViewDidScroll:
时确定/设置每个UIView的alpha值
它工作正常,性能还可以,一切都很顺利,但唯一的问题是计算量太大
我尝试了UIView的
beginAnimations:
和commitAnimations:
,但是在scrollViewDidScroll:
中没有用,因为1)新的alpha值仍然必须由我自己计算,2)scrollViewDidScroll:在滚动时一直被调用,在这里做动画没有意义。有没有办法用核心动画重写这个部分?因此,我不必自己计算每个UIView的alpha值,相反,我可以将整个工作留给核心动画。正如您从调用scrollViewDidScroll:的频率中所注意到的,UIScrollView不会简单地触发并忘记核心动画转换:它会根据触摸、加速度手动移动边界,等等。没有直接的方法来改变这一点
但是,如果您被滚动事件淹没,您可以尝试以下技巧:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970];
if (timestamp - _savedTimestamp) < 0.1)
return;
_savedTimestamp = timestamp;
// do the rest of your work here
}
-(无效)scrollViewDidScroll:(UIScrollView*)scrollView
{
NSTimeInterval时间戳=[[NSDate date]TimeIntervalnce1970];
如果(时间戳-_savedTimestamp)<0.1)
返回;
_savedTimestamp=时间戳;
//你剩下的工作都在这里做
}
H更新 我想出了另一种方法来更新每个页面的alpha值。创建内容视图时,我使用KVO将Observer添加到UIScrollView的contentOffset中:
[self.scrollView addObserver:[self.contentViews objectAtIndex:i]
forKeyPath:@"contentOffset"
options:NSKeyValueObservingOptionNew
context:@selector(updateAlpha:)];
这样,当contentOffset更改时,我的每个ContentView都会收到消息:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
[self performSelector:(SEL)context withObject:change];
}
我的ContentView可以在滚动时自行进行计算和设置动画:
- (void)updateAlpha:(NSDictionary *)change {
CGFloat offset = [[change objectForKey:NSKeyValueChangeNewKey] CGPointValue].x;
CGFloat origin = [self frame].origin.x;
CGFloat delta = fabs(origin - offset);
[UIView beginAnimations:@"Fading" context:nil];
if (delta < [self frame].size.width) {
self.alpha = 1 - delta/self.frame.size.width*0.7;
} else {
self.alpha = 0.3;
}
[UIView commitAnimations];
}
-(void)updateAlpha:(NSDictionary*)更改{
CGFloat offset=[[change objectForKey:NSKeyValueChangeNewKey]CGPointValue].x;
CGFloat原点=[self frame].origin.x;
CGFloat delta=fabs(原点-偏移);
[UIView beginAnimations:@“衰退”上下文:无];
如果(增量<[自帧].size.width){
self.alpha=1-delta/self.frame.size.width*0.7;
}否则{
self.alpha=0.3;
}
[UIView委员会];
}
当然,从superview中删除内容视图时需要删除观察者,并在创建新内容视图时再次添加观察者
希望这对那些想做同样事情的人有所帮助。哈芬奇,谢谢你的想法。虽然它不是完美的,但仍然可以节省一些cpu资源。现在就找到这个,它太棒了-谢谢分享!一个小问题:初始alpha没有为屏幕外的单独视图设置。我想我可以显式地调用updateAlpha:explicit,但也许在一开始就显式地设置contentOffset就足够了。思想?