Mobile Safari がタブで行うのと同じように、UIScrollView のコンテンツをフェードイン/フェードアウトします

StackOverflow https://stackoverflow.com/questions/875129

質問

注記:以下の更新回答に新しいソリューションを追加しました。

iPhone/iPod touch の Mobile Safari タブで見られた効果を再現してみます。

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

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

動作し、パフォーマンスも問題なく、すべてがスムーズに動作します。しかし、唯一の問題は計算が多すぎることです。

UIViewを試してみた beginAnimations: そして commitAnimations:, 、しかし、それは役に立たない scrollViewDidScroll:, 1) 新しいアルファ値はまだ自分で計算する必要があり、2)scrollViewDidScroll があるためです。スクロール時に呼び出され続けるため、ここでアニメーションを実行しても意味がありません。この部分をCoreAnimationで書き直す方法はあるでしょうか?そのため、各 UIView のアルファ値を自分で計算する必要はなく、作業全体を Core Animation に任せることができます。

役に立ちましたか?

解決

アップデート

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

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

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

同じことをしたい人にとって、これが役立つことを願っています。

他のヒント

あなたはどのくらいの頻度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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top