2009-05-17 4 views
13

注:私は新しいソリューションを下記のUPDATE回答に追加しました。フェードイン/アウトモバイルSafariのようなUIScrollViewのコンテンツはタブ内にあります

iPhone/iPod touchのMobile Safariのタブで見た効果を再現しようとしています。

基本的には、4つの再利用可能なUIView(リングバッファーのように動作する)を保持し、水平方向にスクロールするUIScrollViewです。スクロールすると、UIViewの不透明度はオフセットとシームレスにフェードイン/アウトされます。

現在、私はすべて- (void)scrollViewDidScroll:(UIScrollView *)scrollViewの汚れた仕事をしています。例えば、UIScrollViewからcontentOffsetを取得し、ページングを決定し、contentOffsetと各UIView位置との間の差分を計算し、scrollViewDidScroll:が呼び出された時点の各UIViewのアルファ値を決定/設定する。

これは機能し、パフォーマンスは正常です。すべてがスムーズに実行されますが、唯一の問題はあまりにも多くの計算です。

私はUIViewののbeginAnimations:commitAnimations:を試してみましたが、それは1以来、scrollViewDidScroll:に役に立たないのです)新しいアルファ値は、まだ自分で計算する必要があり、2)scrollViewDidScrollは:スクロールするとき、それはここにアニメーションを行うには無意味だと呼ばれ続けました。コアアニメーションでこの部分を書き直す方法はありますか?だから私は、各UIViewのアルファ値で自分で数学を行う必要はなく、代わりに、私はコアアニメーションに全体の作品を残すことができます。

答えて

26

UPDATE

私は別の方法を思いつきました各ページのアルファ値を更新します。コンテンツビューを作成するとき、私はUIScrollViewののcontentOffsetでaddObserverするKVOを使用します。

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

contentOffsetが変更されたとき、私のcontentViewsのそれぞれがメッセージを取得するように:

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

をそして、私のcontentViews計算を行うことができますし、

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

もちろん、スーパービューからコンテンツビューを削除するときにはオブザーバーを削除する必要がありますが、新しいコンテンツビューが作成されたときにそれらを再度追加します。

同じことをしたいと思っている人にこのヘルプをお願いします。

+1

これを今すぐ見つけて、それは素晴らしいです - 共有ありがとう! 1つのグリッチ:最初のアルファは、単独のオフスクリーンビューに設定されていません。私はupdateAlphaを明示的に呼び出すことができますが、開始時に明示的にcontentOffsetを設定するだけで十分でしょう。思考? –

2

scrollViewDidScroll:が呼び出される頻度から気付くように、UIScrollViewは単にCore Animationトランジションを起動して忘れるだけではなく、タッチ、アクセラレーションなどに従って手動で境界を移動します。変更する方法はありませんこの。あなたは、スクロールイベントに圧倒されている場合

ただし、次のようなトリックを試してみてください:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970]; 
    if (timestamp - _savedTimestamp) < 0.1) 
     return; 
    _savedTimestamp = timestamp; 

    // do the rest of your work here 
} 

H

+0

hatfinch、アイデアのおかげで。それは完璧ではありませんが、まだいくつかのCPUパワーを節約します。 – digdog