4

I have an iOS game with a few controls near the bottom of the screen that may be swiped. When a player is swiping down, if their finger slides off the bottom of the screen, the Reachability accessibility gesture is also triggered. This then slides down the screen, moving those controls off the page and hiding half of the game. Obviously, this is not the players intention and requires them to be very specific with their swipes which isn't very intuitive or fun.

On the rounded suite of iPhones, the controls are roughly 100pt from the bottom of the screen to give space for the home indicator which helps to prevent this issue in many situations, but on squared devices, they are much closer at 10pt:

Swipe down example

In my rudimentary testing, I've discovered that even if a swipe started as high as 300pt on the screen continues all the way to the base of the screen, Reachability will be triggered. So raising my controls higher isn’t a solution since that puts them dead center on the screen (also blocking the focus of the game) and out of reach of fingers comfortably on some phones.

Since Reachability doesn't have any use in my game (there are no controls in the upper third of the screen for the purpose of keeping your hand(s) in the lower part of the screen) I'd really like a way to prevent this. Ideally, some way to inform the system it is unnecessary during gameplay, so I can allow it during non-gameplay menus - but I may be dreaming with that part. I also don't think it's A great solution to ask a user to disable this system wide, as it's my app's conflict and that requires them changing their behavior everywhere else.

Is there any guidance, examples, or advice on how to handle conflicts with this specific accessibility gesture?

Dandy
  • 1,203
  • 1
  • 16
  • 31
  • this answer may help https://stackoverflow.com/questions/56718552/disable-gesture-to-pull-down-form-page-sheet-modal-presentation – Somoy Das Gupta Apr 01 '20 at 12:47

1 Answers1

7

You do not want to disable it, you want to defer it.

see https://developer.apple.com/documentation/uikit/uiviewcontroller/2887512-preferredscreenedgesdeferringsys

To use this, you want to override preferredScreenEdgesDeferringSystemGestures to defer the part of the screen you need to delay.

In your case:

override func preferredScreenEdgesDeferringSystemGestures() -> UIRectEdge {
    return [.bottom]
}

Now if you are doing this in a dynamic fashion, you are also going to need to call setNeedsUpdateOfScreenEdgesDeferringSystemGestures() to notify iOS that your rules are changing.

Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44
  • 4
    From what I can tell and after trying, preferredScreenEdgesDeferringSystemGestures has no effect on the Reachability gesture. – Dandy Mar 16 '20 at 21:40
  • It should, you need to block the gesture after it is deferred – Knight0fDragon Mar 16 '20 at 21:43
  • 1
    Every gesture has delegate functions that can be used. If I wasnt mobile I would elaborate better. – Knight0fDragon Mar 16 '20 at 21:46
  • All good! Thanks for the direction so far — I'm going to do my best here to see what I can find in the meantime but would appreciate any elaboration if you get the chance! – Dandy Mar 16 '20 at 21:51
  • 3
    This answer is highly voted, but I just want to state again that _it does not work._ While deferring bottom system gestures prevents things like swipe-up to go home, it does not have any effect with the Reachability accessibility gesture while in portrait. You can see this, in action, with games like Monument Valley which implement the deferring behavior or try it yourself. I'd appreciate any additional details. – Dandy Apr 02 '20 at 15:20
  • Can you provide me your project – Knight0fDragon Apr 02 '20 at 15:21
  • 1
    I went ahead and threw together a sample project from Apple's game template that defers edges here: https://github.com/Nemesisprime/SimpleGameSystemDeferredAttempt — I hope that works as an example. System gestures are deferred, but not Reachability. I realized only just now that squared iPhones are ok, because Reachability is tied to double tapping the home button, but rounded iPhones still have issues because it is tied to the down swipe at the bottom of the screen (seemingly outside of standard system defer behaviors). – Dandy Apr 02 '20 at 15:58
  • 2
    I recently got some feedback from Apple indicating that this might be a bug and preferredScreenEdgesDeferringSystemGestures _should_ have an effect. I've explicitly asked and if this is the case (and if a fix is rolled out), I'll mark this as accepted :) – Dandy Apr 13 '20 at 17:59
  • 1
    I have been playing with it. It technically does have an effect. You cannot disable or cancel any of the screen gestures with the introduction of the X. There is something in the system that determines if a deferment happened and that by doing it again fires the gesture. The bug may be that the system is registering the gesture twice behind the scenes sometimes, which is why it doesn’t work correctly. – Knight0fDragon Apr 13 '20 at 18:02
  • Very nice find. I'm going to add those additional bits to my on-going ticket; I only noticed reachability because it's the only one which my game really has a conflict with. – Dandy Apr 13 '20 at 18:10
  • Yeah, if you delve into the framework, there are private methods to prevent them, but they will cause your app to be rejected. You really should design your app in a way that it does not conflict as they state in their documents, but this makes zero sense on a device that has zero buttons lol. I am not sure why they did not make it kind of like what the did on the 8+. Something like a double tap immediately followed by a pan. – Knight0fDragon Apr 13 '20 at 18:14
  • I know comments really shouldn't be used in this manner: but thanks for your ongoing look into this. It helps to not feel as insane when behavior is... unexpected. Also agree so hard. I can only do so much to prevent conflict when they're reserving a down swipe for the entire bottom third of the device. Argh! – Dandy Apr 13 '20 at 18:32
  • Still having this problem if anyone cares. It seems like all swipe gestures would be included in this. Reachability still shows up when swiping down. Having a scrollview at the bottom of the screen becomes a big problem. The AppStore even suffers this problem, but mitigated with a tab bar that makes the scrolling higher on the screen. – The Way Jan 02 '21 at 15:09
  • How to disable (UIKit) ONLY swipe-down (bottom) reachability gesture? – sabiland May 05 '22 at 06:16
  • I haven't touched this stuff in years, so I am no longer up to date. Like I mentioned in the comments, with the introduction of the full on touch screen phones, deferment is over ridden. – Knight0fDragon May 05 '22 at 14:18
  • For the record (and what it's worth), I've not heard anything back from Apple on Feedback about this issue. – Dandy May 06 '22 at 15:06