繁体   English   中英

Snapchat更新状态栏iOS7更新

[英]Snapchat update status bar iOS7 update

在最新的Snapchat更新中,当您“向右滑动消息”时,状态栏会以某种渐变的方式从黑色变为白色。

http://imgur.com/osJI20u

他们如何在不使用私有API的情况下执行此操作,或者他们是否使用私有API?

我调查了什么:

乍一看,我认为他们正在做其他人所做的事情(就像rdio目前所做的那样),通过屏幕捕获整个屏幕,然后修改/动画该屏幕截图。

但是......您无法从该屏幕捕获方法访问或动画UIImage,因此尽管您可以移动/裁剪该屏幕截图,但您无法更改其外观。

所以...我测试了它,当状态栏处于该状态(半黑/半白)时,它仍然是LIVE,因为它不是截图,它响应充电变化/信号变化等,我不知道如果不使用私有API就不可能。

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

你不使用截图是不正确的。 您正在导航的一侧的状态栏是快照,不会更改。 一分钟过后,您可以很容易地看到这一点,您正在转换的视图的新状态栏将会更改,因为它是真实的,但旧的不会因为它是快照。 这使得幻觉很容易解决。

以下是高级别的情况:

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

  2. 然后,“到”视图控制器接管实际状态栏并将其更改为“轻量级内容”状态。 这提供了一个聪明的错觉,即单个状态栏会根据过渡边界更改颜色,但实际状态栏实际上始终位于快照窗口下方,并且如果不是快照窗口,则确实会在转换开始时立即可见在它的上面。

在Dima回答的基础上,我认为一些基本的实现可以帮助人们。 正如Dima所说它不会移动状态栏,它会移动状态栏的图像。

免责声明 :我对这个实现做了很多,所以我不保证它是否可以开箱即用

从iOS7开始,您可以使用拍照

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

因此,状态栏基本上是从图片中裁剪出来的,并添加到UIWindowwindowLevel高于UIWindowStatusLevelBar因此您可以在真实状态栏上看到它。 就像是:

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

现在其余部分实际上取决于你的实现看起来是什么样的,但是从这里你真的只需要处理移动视图与平移,或任何导致新视图进入侧面的操作。


滑动开始时,使用任何样式,背景等配置新的状态栏(下面的状态栏):

[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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM