2009-05-17 53 views
13

注意:我在下面的UPDATE答案中添加了我的新解決方案。淡入/淡出UIScrollView的內容如Mobile Safari在其標籤

我嘗試重新創建我們在iPhone/iPod touch的Mobile Safari選項卡中看到的效果。

基本上,它是一個UIScrollView,它包含4個可重用的UIView(表現得像環形緩衝區),並且水平滾動。滾動時,UIView的不透明度將隨着偏移而無縫地淡入/淡出。

目前,我在- (void)scrollViewDidScroll:(UIScrollView *)scrollView做所有骯髒的工作。如從UIScrollView獲取contentOffset,確定頁面設置,計算contentOffset和每個UIView位置之間的增量,並在調用scrollViewDidScroll:時決定/設置每個UIView的Alpha值。

它的工作原理,性能沒問題,一切運行順利,但唯一的問題是太多的計算。

我試過的UIView的beginAnimations:commitAnimations:,但它在scrollViewDidScroll:沒用的,因爲1)新的阿爾法值還是要由我自己來計算,和2)scrollViewDidScroll:滾動時不停叫,這是毫無意義的,在這裏做動畫。有什麼方法可以用Core Animation重寫這部分?所以我不必對每個UIView的alpha值進行數學運算,相反,我可以將整個作品留給Core Animation。

回答

26

UPDATE

我想出了另一種方式更新每個頁面的alpha值。當創建內容來看,我用韓國國際志願者組織與UIScrollView的contentOffset到的addObserver:

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

讓我的每個contentViews時contentOffset改變會得到消息:

- (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

現在就找到它,它很棒 - 謝謝你的分享!一個小故障:最初的alpha並沒有設置爲唯一的離屏視圖。我想我可以明確地調用updateAlpha,但也許在開始時顯式設置contentOffset就足夠了。思考? – 2011-03-06 03:56:20

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 2009-05-21 13:56:54