Fade in/out UIScrollView's content like Mobile Safari does in its tab

后端 未结 2 703
有刺的猬
有刺的猬 2021-01-30 11:44

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.

Ba

相关标签:
2条回答
  • 2021-01-30 12:27

    As you'll have noticed from how often scrollViewDidScroll: is called, UIScrollView doesn't simply fire and forget a Core Animation transition: it manually moves the bounds according to touches, acceleration, etc. There's no straightforward way to change this.

    However, if you're being swamped by scroll events, you might try a trick like the following:

    - (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 讨论(0)
  • 2021-01-30 12:41

    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.

    0 讨论(0)
提交回复
热议问题