Stop app going to background when swiping up from bottom edge on iPhone X iOS 12
Asked Answered
A

4

3

My game is going into background mode when performing a swipe from the bottom edge of the screen on iPhone X iOS 12.

As per Apple documentation overriding preferredScreenEdgesDeferringSystemGestures and calling setNeedsUpdateOfScreenEdgesDeferringSystemGestures should stop the app from going to background but this is's not working on iOS 12.

I am using Unity3D and the editor has the Defer system gestures on edges option , which is implemented as per apple documentation, but also does not work.

I am compiling the project in Xcode 10.

Does anyone else have this problem and do you have a fix?

PS: I am testing this in an empty single view iOS project, the only added code is the following:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear: animated];

    [self setNeedsUpdateOfHomeIndicatorAutoHidden];
    [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
}

- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
    return UIRectEdgeAll;
}

- (BOOL)prefersHomeIndicatorAutoHidden
{
    return YES;
}

Update: Turns out that if I use a swift implementation it works. Too bad I cannot do this for the Unity3D 2017 generated project.

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    
    if #available(iOS 11.0, *){
        setNeedsUpdateOfScreenEdgesDeferringSystemGestures()
    }
}

override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge{
    return [.all];
}
}

New Update: In Unity 2019 it works by unchecking "Status Bar Hidden" in Project Stttings\Resolution and presentation and making sure you check at least one edge in Poject Settings\Other Settings\Defer system gestures on edges

Abort answered 9/10, 2018 at 8:46 Comment(6)
Did you try it in iOS 11? Or is the issue specific to iOS 12?Achitophel
I cannot since I don't have an iOS 11 iPhone X and the game does not run in simulator.Abort
I will check it with iOS 12 and let you know.Achitophel
Thank you GoGreen. But I am testing on iOS 12, it would be helpful if you can test on iOS 11.Abort
On a side note, you should only consider UIRectEdgeBottom as the home indicator lies there.Issue
I agree, was using All only for testing!Abort
A
7

Removing prefersHomeIndicatorAutoHidden makes it work in Objective C also.

This is the working example implementation, for anyone having the same problem:

- (void)viewDidLoad {
    [super viewDidLoad];

    if (@available(iOS 11.0, *)) { 
      [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
    }
 }

- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
    return UIRectEdgeAll;
}

And for those who, like me, are using Unity3d just delete the following method from UnityViewControllerBase+iOS.mm in the generated Xcode project:

- (BOOL)prefersHomeIndicatorAutoHidden
{
    return YES;
}

If you're not using Unity, ensure that prefersHomeIndicatorAutoHidden is NO/false.

Abort answered 18/10, 2018 at 13:29 Comment(3)
Making it return NO should have the same effect.Shrug
And critically, if you do everything listed above except leave the code return UnityGetHideHomeButton() it will not work. Change it to return NO and it will.Supramolecular
Removing prefersHomeIndicatorAutoHidden does the trick. Thank you for pointing that out!Oahu
A
3

As per the apple documentation, preferredScreenEdgesDeferringSystemGestures doesn't stop the app from going to background, it just gives your gesture precedence over system gesture. However, if you try to do it successively a second time, the system gesture would work. You can easily verify this by comparing with other apps.

By default the line at the bottom which helps in swiping up is black in colour and the swipe up gesture would work instantly if you do not override this method. But in your app, the line will look gray'ed out initially. If you do a swipe up, it will become black again and if you swipe up a second time, the system gesture will work.

I am putting this as an answer because of limited characters for commenting.

Achitophel answered 9/10, 2018 at 12:10 Comment(1)
Thanks for pointing this out, it helps clarify my question. The behaviour I am looking for is the one described by you where system gesture works the second time ( the app backgrounds on the second gesture ). The behaviour I am currently experiencing is that the app goes to background from the first gesture.Abort
R
1

For Swift the answer is to override the instance property like so within your UIViewController.

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

for example.

Reposition answered 19/7, 2022 at 17:20 Comment(0)
I
0

Same as accepted answer but now more Swifty

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 }
}
Inverter answered 17/3, 2023 at 3:24 Comment(1)
Note: using [.all] is a good option too.Inverter

© 2022 - 2024 — McMap. All rights reserved.