Snapchat更新状态栏iOS7更新

在最新的snapchat更新中,当您向右滑动消息时,状态栏会以渐变的方式从黑色变成白色。

View post on imgur.com

他们如何做到这一点,而不使用私人API,或者他们使用私人API?

我已经看到:

乍看之下,我认为他们只是通过屏幕捕捉整个屏幕,然后修改/制作屏幕截图来做其他人所做的事情(如rdio当前所做的)。

但是…你不能访问或animation的UIImage从屏幕捕获的方法,所以虽然你可以移动/裁剪屏幕截图,你不能改变它的外观。

所以…我testing了它,当状态栏处于这种状态(半黑/半白)时,它仍然是LIVE,就像它不是截图一样,它响应充电改变/信号改变等等。我可以告诉这是不可能的,没有使用私人API。

这让我好奇,所以我玩了一下应用程序,并在越狱设备上使用Spark Inspector检查应用程序的视图层次结构,发现了一些事情。

你对他们没有使用屏幕截图是不正确的。 您正在导航AWAY的状态栏是一个快照,不会更改。 你可以很容易地看到这一点,一分钟过去了,你正在过渡到视图的新状态栏将会改变,因为它是真实的,但旧的不会因为它是一个快照。 这使得幻觉很容易解决。

以下是发生在高层的事情:

  1. 当你开始转换时,应用程序会以当前状态拍摄状态栏的快照(很可能实际上是拍摄整个UIScreen的快照并简单地裁剪出状态栏),并将包含该快照的窗口附加到过渡视图的顶部,锚定到最终过渡位置,并由“从”视图控制器的视图掩盖。 这个窗口似乎在UIWindowLevelStatusBar之上有一个windowLevel ,所以它能覆盖真实的状态栏。

  2. 然后,“to”视图控制器接pipe实际状态栏并将其更改为“light content”状态。 这提出了一种巧妙的幻觉,即单个状态栏会随着过渡边界而改变颜色,但是实际状态栏实际上总是位于快照窗口下方,并且如果不是在快照窗口坐着,在它的上面。

根据迪马的回答,我想一些基本的实施可以帮助人们开始。 正如Dima所说的那样,它并没有移动状态栏,而是移动了状态栏的图像。

免责声明 :我喜欢这个实现,所以我不保证它是否可以开箱即用

从iOS7开始,您可以使用一张照片

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

所以基本上状态栏是从图片中剪切出来的,并添加到一个UIWindow上面,这样你就可以在真实的状态栏上看到它。 就像是:

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

现在剩下的就完全取决于你的实现是什么样的,但是从这里开始,你只需要用一个平移处理视图,或者任何引起新视图进入的操作。


当开始滑动时,使用任何样式,背景,configuration新的状态栏(下面的那个):

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

现在我们在这里有一些有趣的事情。 随着转换的进行,您将不得不使用滚动量来“剪切” statusBarView偏移量。 statusBarView.frame将不得不从x = offset开始,否则它将显示在实际状态栏上(因为它的窗口更高),但是如果你不改变contentInsets,那么图片将随着转换而滑动。 因此,为了创造幻觉,您需要将原点向右推,同时增加左侧的内容,使其看起来在相同的位置。

所以在任何处理滑动操作的方法中:

注意:这将主要取决于个人实施,可能需要一些实验

  // 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 } 

(注意:你也可以尝试使用转换,而不是明确地设置框架: statusBarView.transform = CGAffineTransformMakeTranslation(offset -previousOffsetAmount, 0);我在那里使用previousOffsetAmount,因为你只希望它移动任何新的数量它可以匹配。如果你走这条路线,这将不得不被跟踪)

最后,一旦“滑动”完成,不要忘记从窗口中完全删除截图:

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

我可能真的有兴趣试图让这个工作,所以会更新,如果是这样的话。