淡入/淡出UIScrollView的内容像移动Safari在其选项卡 [英] Fade in/out UIScrollView's content like Mobile Safari does in its tab

查看:156
本文介绍了淡入/淡出UIScrollView的内容像移动Safari在其选项卡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:我在下面的UPDATE答案中添加了我的新解决方案。



我尝试重新创建我们在Mobile Safari在iPhone / iPod touch上。



基本上,它是一个UIScrollView,它保存着4个可重用的UIView(像环形缓冲区一样),并水平滚动。当滚动时,UIView的不透明度将与偏移无缝地淡入/淡出。



目前,我做所有的脏工作在 - (void)scrollViewDidScroll :(UIScrollView *)scrollView 。例如从UIScrollView获取contentOffset,确定pageingation,计算contentOffset和每个UIView位置之间的增量,并在 scrollViewDidScroll:被调用。



它的工作原理,性能是好的,一切运行顺利,但唯一的问题是太多的计算。



我试过UIView的 beginAnimations: commitAnimations:但是它在 scrollViewDidScroll:中无用,因为1)新的alpha值仍然必须由自己计算,和2)scrollViewDidScroll:在滚动时保持被调用,动画在这里。有什么办法可以用Core Animation重写这个部分?所以我不必对每个UIView的alpha值自己做数学,而是可以把整个作品留给Core Animation。

解决方案

UPDATE



我想出了另一种更新每个网页的Alpha值的方法。当创建内容视图时,我使用KVO addObserver与UIScrollView的contentOffset:

  [self.scrollView addObserver:[self.contentViews objectAtIndex: i] 
forKeyPath:@contentOffset
options:NSKeyValueObservingOptionNew
context:@selector(updateAlpha :)];这样,当contentOffset改变时,我的每个contentViews都会收到这个消息:



b

   - (void)observeValueForKeyPath:(NSString *)keyPath 
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
[self performSelector:(SEL)context withObject:change];
}

我的contentViews可以在滚动时自己做计算和动画: p>

   - (void)updateAlpha:(NSDictionary *)change {
CGFloat offset = [[change objectForKey:NSKeyValueChangeNewKey] CGPointValue] 。X;
CGFloat origin = [self frame] .origin.x;
CGFloat delta = fabs(origin - offset);

[UIView beginAnimations:@Fadingcontext:nil];
if(delta< [self frame] .size.width){
self.alpha = 1-delta / self.frame.size.width * 0.7;
} else {
self.alpha = 0.3;
}
[UIView commitAnimations];
}

当然,删除内容视图时需要删除观察器



希望帮助那些想要这样做的人。


NOTE: I added my new solution at the UPDATE answer below.

I try to recreate the effects we saw in Mobile Safari's tab on iPhone/iPod touch.

Basically, it's a UIScrollView that holds 4 reusable UIView (acting like ring buffer), and scrolls horizontally. When scrolling, the UIView's opacity will fade in/out seamlessly with offset.

Currently, I do all the dirty job in - (void)scrollViewDidScroll:(UIScrollView *)scrollView. Such as getting the contentOffset from UIScrollView, determine the pageingation, calculate the delta between contentOffset and each UIView positions, and decide/set the alpha value of each UIView at the moment when scrollViewDidScroll: was called.

And it works, performance is okay, everything runs smoothly, but the only problem is too much calculating.

I tried UIView's beginAnimations: and commitAnimations:, but it's useless in scrollViewDidScroll:, since 1) the new alpha value still have to be calculate by myself, and 2) scrollViewDidScroll: kept called when scrolling, it's meaningless to do the animation here. Is there any way to rewrite this part with Core Animation? So I don't have to do the math myself on alpha value of each UIView, instead, I can left whole works to Core Animation.

解决方案

UPDATE

I came up with another way to update alpha value of each page. When creating content view, I use KVO to addObserver with UIScrollView's contentOffset:

[self.scrollView addObserver:[self.contentViews objectAtIndex:i] 
                  forKeyPath:@"contentOffset" 
                     options:NSKeyValueObservingOptionNew
                     context:@selector(updateAlpha:)];

So that each of my contentViews will get the message when contentOffset changed:

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context {
    [self performSelector:(SEL)context withObject:change];
}

And my contentViews can do the calculation and animate by themselves when scrolling:

- (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];
}

Of course, you will need to remove the observer when you remove the content view from superview, and add them again when new content view created.

Hope this help to those who want to do the same.

这篇关于淡入/淡出UIScrollView的内容像移动Safari在其选项卡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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