Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tweetbot like shrink view transition

Does anyone know how to achieve the present view controller's view to shrink and put another one over it with a transparency? It is achieved in Tweetbot 3 when you tap on your avatar in the top left on the navigation bar. Should I take a snapshot for example?

The Tweetbot transition I mean

like image 499
yoeriboven Avatar asked Oct 20 '22 18:10

yoeriboven


1 Answers

In order to achieve this effect you will have to rebuild your view stack from scratch.

So as there is no possibility to change the viewController.view's frame, you'll have to add a kind of container subview a little like this:

@implementation ViewController
@synthesize container;

- (void)viewDidLoad {
    [super viewDidLoad];

    container = [[UIView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:container];
    // add all views later to this insted of self.view

    // continue viewDidLoad setup
}

Now if you have that, you can animate the shrinking behavior like so:

[UIView animateWithDuration:.5 animations:^{
        container.frame = CGRectMake(10, 17, self.view.frame.size.width-20, self.view.frame.size.height-34);
    }];

Okay, I assume you are developing for iOS 7, so we'll make use of some new APIs here (for earlier versions there are alternative frameworks). Now since WWDC UIView's got a resizableSnapshotViewFromRect:(CGRect) afterScreenUpdates:(BOOL) withCapInsets:(UIEdgeInsets) method returning a single UIView object.

[UIView animateWithDuration:.5 animations:^{
        container.frame = CGRectMake(10, 17, self.view.frame.size.width-20, self.view.frame.size.height-34);
    } completion:^(BOOL finished) {
        UIView *viewToBlur = [self.view resizableSnapshotViewFromRect:container.frame afterScreenUpdates:YES withCapInsets:UIEdgeInsetsZero];   
    }];

If you do not want to rewrite your view management, you can also first take a snapshot of your main view this way, set it to the container and then animate only the image. But remember, you can not interact with the captured view then.

When you've got that, you can download the two category files from this repo (They're from WWDC, so directly from Apple!). Basically, what they do is, they add some cool new methods to the UIView class, of which we'll use applyDarkEffect. I haven't tested this, maybe another method fits your needs better here.

Anyways if we implement that into the block and maybe also add a UIImageView to display the blurred overlay, it should look something like this:

[UIView animateWithDuration:.5 animations:^{
        container.frame = CGRectMake(10, 17, self.view.frame.size.width-20, self.view.frame.size.height-34);
    } completion:^(BOOL finished) {
        UIView *viewToBlur = [self.view resizableSnapshotViewFromRect:container.frame afterScreenUpdates:YES withCapInsets:UIEdgeInsetsZero];
        UIImage *image = [viewToBlur applyDarkEffect];
        UIImageView *blurredView = [[UIImageView alloc] initWithFrame:self.view.frame];
        [self.view addSubview:blurredView];

        // optionally also animate this, to achieve an even smoother effect
        [blurredView setImage:image];

    }];

You can then add your SecondViewController's view on top of the stack, so that it's delegate methods will still be called. The bounce effect of the incoming account view can be achieved via the new UIView animation method animateWithDuration:(NSTimeInterval) delay:(NSTimeInterval) usingSpringWithDamping:(CGFloat) initialSpringVelocity:(CGFloat) options:(UIViewAnimationOptions) animations:^(void)animations completion:^(BOOL finished)completion (more on that in the documentation)

I hope that will help you with your project.

like image 163
Finn Gaida Avatar answered Oct 23 '22 11:10

Finn Gaida