好的,这实际上是使用一些巧妙的技巧完成的。
基本上它实际上并不是在移动状态栏,而是在移动状态栏的图像。
免责声明:我 YOLO 完成了这个实现,所以我不保证它是否能开箱即用
从iOS7开始你可以使用拍照
UIView *screen = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO];
我看到了更多有用的信息here。但基本上状态栏是从图片中裁剪出来的,并添加到UIWindow 和windowLevel 上方的UIWindowStatusLevelBar,这将掩盖真实的状态栏。比如:
UIWindow *statusBarWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
statusBarWindow.windowLevel = UIWindowLevelStatusBar;
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]; // I have no idea if this is necessary but since it's now visible you def don't want it to have a color
...
// The view that will hold the screen shot
UIView *statusBarView = [[UIView alloc] initWithFrame:[UIApplication sharedApplication].statusBarFrame];
statusBarView.clipsToBounds = YES;
// Now we add the screen shot we took to this status bar view
[statusBarView addSubview:screen]; // screen is the UIView from previous code block
// Now add this statusBarView with the image to the window we created
[statusBarWindow addSubview:statusBarView];
现在剩下的真的取决于你的实现是什么样的,但从这里你真的只需要使用平移或任何导致新视图从侧面进入的动作来处理移动视图:
// you're going to want to hide the status bar when this action starts so that your new window is visible
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
// then inside whatever method is handling the sliding you're going to adjust the frame of the statusBarView
// this can be done explicitly by setting a new frame, or animating its x position, or whatever
// if you're doing it explicitly something like:
CGFloat offset = self.viewThatIsScrolling.contentOffset.x; // may be negative depending on direction that is being swiped
statusBarView.frame = CGRectMake(offset, 0, self.statusBarView.frame.width, 20.0f);
// or maybe even
statusBarView.transform = CGAffineTransformMakeTranslation(offset -previousOffsetAmount, 0); // you only want it to move over by whatever new amount so it can match up, this will have to be tracked somehow if you go this route
...
// and finally once the 'sliding' is done don't forget to remove the screenshot and unhide the status bar
// (can check by looking at the offset value from earlier or as a callback after animation, or whatever)
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
[statusBarView removeFromSuperview];
statusBarView = nil;
另请注意,这不处理方向变化或任何事情(固定框架可能会导致它无法工作)。您可能可以使用autoResizingMask 或其他东西