基于Dima的回答,我认为提供一些基本实现方法可以帮助人们入门。正如Dima所说,它并不是移动状态栏,而是移动状态栏的图像。
免责声明:我YOLO了这个实现,因此不能保证它是否可以直接使用。
从iOS7开始,您可以使用
UIView *screen = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO]
基本上状态栏是从图片中裁剪出来,然后添加到一个UIWindow
中,并设置windowLevel
高于UIWindowStatusLevelBar
,这样您就可以在真实的状态栏上方看到它。类似于以下内容:
UIWindow *statusBarWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
statusBarWindow.windowLevel = UIWindowLevelStatusBar + 1;
statusBarWindow.hidden = NO;
statusBarWindow.backgroundColor = [UIColor clearColor];
...
UIScrollView *statusBarView = [[UIScrollView alloc] initWithFrame:[UIApplication sharedApplication].statusBarFrame];
statusBarView.clipsToBounds = YES;
[scrollingStatusBarView addSubview:statusBarView];
[statusBarView addSubview:screen];
[statusBarWindow addSubview:statusBarView];
现在,其余的内容实际上取决于您的实现方式,但是从这里开始,您只需要使用平移或任何导致新视图从侧面进入的操作来处理移动视图。
当滑动开始时,请使用任何样式、背景等配置您的新状态栏(位于下方):
[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:NO];
现在我们有一些有趣的事情发生了。随着过渡的进行,您将不得不使用它滚动到“剪切”
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 (midTransition) {
...
} else {
[statusBarView removeFromSuperview];
statusBarView = nil;
}
我真的很想尝试让它工作,如果成功了,我会更新。