Snapchat Update Status Bar Update iOS7 Update

In the latest Snapchat update, when you “scroll right for messages,” the status bar turns from black to white as a gradient.

http://imgur.com/osJI20u

How do they do this without using private APIs, or do they use a private API?

What I reviewed:

At first glance, I thought they were just doing what everyone else is doing (like rdio at present) on the screen, capturing the whole screen, and then changing / animating this screenshot.

But ... you cannot access or animate UIImage with this screen capture method, so although you can move / crop this screenshot, you cannot change its appearance.

So ... I tested it, and when the status bar is in this state (half black / half white), it is still LIVE, as in its screenshot, and it responds to changes in charge / signal changes, etc. as far as I can tell This is not possible without using a private API.

+6
source share
2 answers

I was curious, so I played around a bit with the application and checked the hierarchy of the application views using the Spark Inspector on the jailbreak device, and I found a few things.

You are mistaken about them without using a screenshot. The status bar on the side you are moving AWAY to is a snapshot and does not change. You can easily see this when the minute passes, the new status bar for viewing that you are moving will change because it is real, but it will not be old because it is a snapshot. This facilitates the work of the illusion.

Here's what happens at a high level:

  • When you start a transition, the application receives a snapshot of the status bar (most likely, in fact, it takes a snapshot of the entire UIScreen and simply truncates the status bar from it) in the current state and attaches the window containing this snapshot to the top of the view in the transition, bound to The end position of the transition and the masked representation of the controller is "out". This window has a windowLevel above the UIWindowLevelStatusBar , so it can cover the real status bar.

  • Then, the “do” view controller takes the actual status bar and changes it to “light content”. This is a cunning illusion that one status bar changes color with the transition border, but the real status bar is actually always under the snapshot window and would really be visible immediately after the transition began, if it were not for the snapshot window at the top.

+15
source

Building what Dima answered, I thought that a basic implementation could help to get people to start. Since Dima said that he does not move the status bar, he moves the image of the status bar.

Disclaimer I followed this procedure, so I cannot guarantee if this will work out of the box.

Starting with iOS7, you can take a picture with

 UIView *screen = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO]; 

So basically the status bar is cropped from the picture and added to the UIWindow with windowLevel above the UIWindowStatusLevelBar so you can see it on top of the real status bar. Sort of:

 UIWindow *statusBarWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; statusBarWindow.windowLevel = UIWindowLevelStatusBar + 1; // higher statusBarWindow.hidden = NO; // fun fact you don't have to add a UIWindow to anything, just setting hidden = NO should display it statusBarWindow.backgroundColor = [UIColor clearColor]; // since visible, make it clear until we actually add the screen shot to it so as to not block anything ... // The view that will hold the screen shot // Later, I think we're going to need to play with contentInsets to make the view look like its staying still, so we're making it a UIScrollView in case UIScrollView *statusBarView = [[UIScrollView alloc] initWithFrame:[UIApplication sharedApplication].statusBarFrame]; statusBarView.clipsToBounds = YES; // Now we add the screen shot we took to this status bar view [scrollingStatusBarView addSubview:statusBarView]; [statusBarView addSubview:screen]; // screen is the UIScrollView from previous code block (the screen shot) // Now add this statusBarView with the image to the window we created [statusBarWindow addSubview:statusBarView]; 

Now it all depends on how your implementation looks, but from here you just need to handle moving the view with panning or any other action that causes a new view to appear on the side.


When you start scrolling, configure a new status bar (under it) with any style, background, anything:

 [UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:NO]; // anything else you might feel like doing 

Now we have something interesting. As the transition moves, you will need to use the amount that it scrolls to “cut off” this offset value from the statusBarView . statusBarView.frame should start with x = offset, otherwise it will be displayed on top of the actual status bar (since this window is larger), but if you do not change the contentInsets, then the image will move with the transition. Thus, to create an illusion, you will need to drag the beginning to the right, increasing the insertion of the contents on the left by the same amount so that it appears in the same place.

Thus, a sliding action is processed inside any method:

Note. This will depend heavily on personal implementation and is likely to take some experiments.

  // if you're using an animation to handle the transition you can match up this change in x position with the animation // if you're doing via pan gesture you could try something like: CGFloat offset = self.viewThatIsScrolling.contentOffset.x; // may be negative depending on direction that is being swiped if (midTransition) { // you can use the offset value here to check // NOTE: again, will depend on which direction this animation is happening in. I'll assume a new view coming in from left (so swiping right) statusBarView.frame = CGRectMake(offset, 0, self.statusBarView.frame.width, 20.0f); // move the origin over to the right statusBarView.contentInsets = UIEdgeInsetsMake(0, offset, 0, 0); // make the picture start 'offset' pixels to the left so it'll look like it hasn't moved } 

(Lateral note: you can also try using a transform rather than setting the frame explicitly: statusBarView.transform = CGAffineTransformMakeTranslation(offset -previousOffsetAmount, 0); I use the oldOffsetAmount parameter because you want it to move over any new amount to it could coincide. you need to somehow track if you go along this route)

And finally, after completing the “slide”, be sure to completely remove the screenshot from the window:

 // if continuing from before: if (midTransition) { ... } else { // the view has been slid completely [statusBarView removeFromSuperview]; statusBarView = nil; // I'm keeping the UIWindow where it is for now so it doesn't have to be recreated and because it has a clear background anyways } // if this is being done via animation the above can be called the animation finishes 

In fact, I could try to get this to work, so it will update if that is the case.

+1
source

All Articles