36

我面临的问题是:

我想实现一个具有漂亮设计和左/右菜单的 iOS 7 应用程序,该应用程序出现在主视图向左/向右移动动画之后。我正在用[UIView animateWithDuration...]代码来做这件事,但这并不重要。我想要实现的是Mailbox iOS 7应用程序具有相同的效果:将状态栏移开(向右/向左)与主视图

图片以获得更好的解释:

状态栏移到一侧的邮箱应用

我只找到了这篇关于这个问题的文章,其中一些工作代码使用了私有 API,我不想使用这些代码,因为我希望我的应用在 App Store 上被接受。

我想达到同样的效果(“合法”)。有人知道怎么做吗?

谢谢!

4

5 回答 5

48

它的要点是使用 iOS 7 中引入的这种方法:

https://developer.apple.com/documentation/uikit/uiscreen/1617814-snapshotview

这样,您将获得一个 UIView,其中包含一个包含状态栏的屏幕截图。一旦你有了它,它只是隐藏你当前的视图然后推动屏幕截图视图的问题。

我在这里发布了一个概念证明: https ://github.com/simonholroyd/StatusBarTest

注意我没有提交通过 Apple 审核流程执行此操作的代码,但这不是私有 API 方法。

于 2013-09-25T17:01:54.500 回答
7

所以,经过Simon Holroyd先生的初步推动和一番搜索,我找到了如何实现这个“效果”功能的解决方案。这是代码:

statusbarView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];

编辑:pcholberg先生正确地指出,以前的代码在实际设备上不起作用,只能在 iOS 模拟器上运行,所以我根据他的建议对其进行了编辑

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
{
    UIView *screenShot = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO];
    [statusbarView addSubview:screenShot];
    [statusbarView setClipsToBounds:YES];
    [self.view addSubview:statusbarView];

    [self setPrefersStatusBarHidden:YES];
    [self prefersStatusBarHidden];
    [self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)];
}

...

- (BOOL)prefersStatusBarHidden
{
    return prefersStatusBarHidden;
}

...


所以第一部分创建上下文,使用西蒙提到的方法,用状态栏绘制视图,并将其保存为UIImage

第二部分将快照添加UIView到我的 viewController 的UIView

第三部分将状态栏的我的 bool 设置为 YES(为了在上面的方法中更容易使用),并调用方法来重绘它

然后,这会将 UIView 设置为无效状态栏并隐藏原始状态栏,因此没有双重渲染。然后我可以在我的[UIView animateWithDuration...方法中使用这个视图

当我返回时,我在动画块的完成处理程序中使用此代码:

[statusbarView removeFromSuperview];

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
{

    [self setPrefersStatusBarHidden:NO];
    [self prefersStatusBarHidden];
    [self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)];

}

瞧!这就像我的问题中描述的效果一样。

希望这对某人有帮助!

于 2013-09-26T22:29:23.950 回答
7

我使用这种方法来移动带有滑块视图的状态栏,在一个应用程序中有两个窗口,一个普通窗口,另一个 statuBarWindow,我得到 statuBarView 哪个 superView 是 statuBarWindows ,然后用滑块视图移动它。

- (UIView *)statuBarView
{
    NSString *key = [[NSString alloc] initWithData:[NSData dataWithBytes:(unsigned char []){0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x61, 0x72} length:9] encoding:NSASCIIStringEncoding];
    id object = [UIApplication sharedApplication];
    UIView *statusBar = nil;
    if ([object respondsToSelector:NSSelectorFromString(key)]) {
        statusBar = [object valueForKey:key];
    }
    return statusBar;
}
于 2014-02-17T10:47:14.277 回答
3

我刚刚创建了BSPanViewController,它可以非常容易地实现这种效果。可以在 GitHub 上找到有关如何使用它的控件和说明。

实现与Simon Holroyd 解释的相同。

于 2013-11-17T16:37:21.900 回答
-3

根据我的经验,App Store 的评论者通常不关心私有 API 的使用,尤其是这种简单且无害的。对于该任务,您可以通过多种方法获得指向应用程序状态栏视图的指针,您可以在 iOS 完整标题中找到这些方法,例如https://github.com/nst/iOS-Runtime-Headers

于 2013-09-25T16:45:02.137 回答