在iPhone X iOS 12上从底部边缘向上滑动时停止应用程序进入背景



我的游戏在iPhone X iOS 12上从屏幕底部边缘执行滑动时进入后台模式。

根据Apple文档,覆盖preferredScreenEdgesDeferringSystemGestures并调用setNeedsUpdateOfScreenEdgesDeferringSystemGestures应该阻止应用程序进入后台,但这不适用于iOS 12。

我正在使用 Unity3D,编辑器具有 在边缘上延迟系统手势选项 ,这是根据 Apple 文档实现的,但也不起作用。

我正在用Xcode 10编译该项目。

还有其他人有这个问题吗,你有解决方法吗?

PS:我正在一个空的单视图iOS项目中对此进行测试,唯一添加的代码如下:

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear: animated];
[self setNeedsUpdateOfHomeIndicatorAutoHidden];
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
}
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
return UIRectEdgeAll;
}
- (BOOL)prefersHomeIndicatorAutoHidden
{
return YES;
}

更新:事实证明,如果我使用快速实现,它可以工作。太糟糕了,我无法为Unity3D 2017生成的项目执行此操作。

class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

if #available(iOS 11.0, *){
setNeedsUpdateOfScreenEdgesDeferringSystemGestures()
}
}
override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge{
return [.all];
}
}

新更新:在Unity 2019中,它的工作原理是取消选中项目间距\分辨率和演示文稿中的"状态栏隐藏",并确保在Poject设置\其他设置\延迟边缘上的系统手势中至少选中一条边缘

删除prefersHomeIndicatorAutoHidden使其在目标 C 中也可以工作。

这是工作示例实现,适用于遇到相同问题的任何人:

- (void)viewDidLoad {
[super viewDidLoad];
if (@available(iOS 11.0, *)) { 
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
}
}
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
return UIRectEdgeAll;
}

对于那些像我一样使用Unity3d的人,只需在生成的Xcode项目中从UnityViewControllerBase+iOS.mm中删除以下方法:

- (BOOL)prefersHomeIndicatorAutoHidden
{
return YES;
}

如果您没有使用 Unity,请确保prefersHomeIndicatorAutoHidden为 NO/false。

根据苹果文档,preferredScreenEdgesDeferringSystemGestures不会阻止应用程序进入后台,它只是使您的手势优先于系统手势。 但是,如果您尝试再次连续执行此操作,系统手势将起作用。您可以通过与其他应用程序进行比较轻松验证这一点。

默认情况下,底部有助于向上滑动的行是黑色的,如果您不覆盖此方法,向上滑动手势将立即起作用。但在您的应用中,该行最初看起来会变灰。如果向上滑动,它将再次变为黑色,如果再次向上滑动,系统手势将起作用。

我把这个作为一个答案,因为评论的字符有限。

对于 Swift 来说,答案是覆盖 UIViewController 中的实例属性。

override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge { 
get { .all } 
}

例如。

与接受的答案相同,但现在更斯威夫特

class ViewController: UIViewController {
// must be false so that first swipe up is ignored
override var prefersHomeIndicatorAutoHidden: Bool {
return false
}
override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge {
return [.bottom]
}

// MARK: - Either true or false works

override var prefersStatusBarHidden: Bool { return true }
}