How to override three finger accessibility zoom gesture? - ios

I am trying to create a gesture recognizer that responds to three touches, but the gesture is ignored if the user has the accessibility zoom feature enabled, which triggers off a three finger double tap.
My view uses massive UI elements, so zooming is not appropriate. Is there an api to disable the accessibility zoom so I can respond to a three finger tap?

You could try posting a UIAccessibilityPauseAssistiveTechnologyNotification though I believe this only refers to external ATs, and not to VoiceOver and Zoom features. Though I have not played around with it much.
EDIT: I just checked, the constant for disabling the zoom feature is not available in UIAccessibilityConstants.h. So this will not work, meaning there is no viable solution for this.

Related

ios voiceover slider double tap and hold, but for custom view

I've created a custom view that acts like a UISlider - there is a "track", and a handle to "grab" to change the value. For particular reasons, I can't just make it a subclass of UISlider. I'm trying to make this slider as accessible as possible with VoiceOver. I have accessibilityIncrease and accessibilityDecrease on my custom view that handle single finger drag up and single finger drag down. This changes the value of the slider by 10% at a time.
However, I'd like to allow more fine grained control, just like a non-VoiceOver slider. By default , UISlider has double tap and hold, and you can drag up/down to "pan" the slider. I'd like to add exactly that to my custom view, but I can't find the correct incantation to handle the double tap and hold gesture.
Is there something I can do to mimic the double tap and hold gesture from UISlider on my custom view?
Thanks very much!!!
If you want to implement this kind of new gesture for VoiceOver users, just forget it.
The recommended gesture for this kind of UI control is definitely the implementation of adjustable value as you already did apparently.
I don't think it's a good idea to try and implement new VoiceOver gestures in an application because its users have their habits and they may be totally lost with your customed control if they cannot handle it unless you add an hint to explain but that's definitely not what I recommend anyway.
Otherwise, you could take a look at the pass through concept introduced in the What's New in Accessibility WWDC 2017 video that deals with the same idea but for a panning gesture...

Xcode UI test: How can I check something in the UI while a gesture is in progress?

My app supports a kind of dragging/panning gesture: The gesture begins after a short delay when the user presses the screen with one finger, and keeps pressing. The user can then drag/pan pan around the screen while keeping the finger on the screen. The gesture ends when the user lifts the finger.
While the user drags/pans around the screen the UI continuously updates. Among other things, a label is continously updated with a text that has certain information about the current gesture location. I would like to write a UI test that not only simulates the gesture, but also checks how the UI is updated while the gesture is in progress.
I have found the XCUICoordinate class which has the pressForDuration:thenDragToCoordinate: method. This looks as if it would allow me to simulate the gesture, but I can't see any way how I could, for instance, check that the label I mentioned contains a certain text while the gesture is in progress.
Is there an API that allows me to write the desired UI test?
My app is written in Objective-C, but a Swift answer is also acceptable.

Using Pan and Swipe gesture recognisers simultaneously

I've got a view on the bottom of my ViewController ( similar to Google Maps Bottom Sheet ). The goal is:
When panning up, the view moves towards the pan direction ( essentially follows the finger), when panning ends, the view goes fullscreen. So far so good, all works.
Adding swipe gestures. When swiping up, the view should go full screen.
The issue is that by definition, a swiping gesture is a pan gesture but not the other way around. So unless i go really slow with my panning , the swipe gesture will trigger and the view will go full screen even though im still dragging on the screen.
Simply panning up doesnt look much like the kind of swipe im looking for. The swipe gesture im describing should only trigger if the user "flicked" the view momentarily. If they keep on panning the pan gesture should take precedence.
Any ideas how to achieve this? For reference you could check tap on a pin on google maps on either android or ios.
Its a little hard to describe without showing so if it helps im very open to clarify things.
UPDATES
I think the distinction for a swipe that would override the pan as im describing is that it a) took a short amount of time to complete b)the gesture ended with the user lifting the finger off the screen c) (maybe wrong ) the area traversed should not be too big. Sounds a lot like a flick to me..
If you cannot describe the difference between the two gestures in clearly defined terms then it will be difficult to tell the UIGestureRecognizer how to do so. In addition, it is possible that your user will have difficulty figuring out how to properly interact with the screen if your gestures are too similar or complex.
That being said, you may be able to distinguish between a "swipe" and a "pan" by checking the gesture's velocity. You should be able to play around with the UIGestureRecognizerDelegate methods and achieve the effect you want.
Ok i've achieved what was needed. The short answer is that i was looking for a "flick" gesture instead of a pan gesture. Generally its a nono to add custom gestures but as im replicating the google maps bottom sheet component for ios, it would appear that a custom gesture is the only way.
Using Navillus's comment, I added a velocity and gesture end check in the pan recogniser. The result looked like this:
if(recognizer.state == .ended){
if(recognizer.velocity(in: self).y > CGFloat(500) ){
self.pullUpViewSetMode_SUMMARY()
return;
}
if(recognizer.velocity(in: self).y < CGFloat(-500) ){
self.pullUpViewSetMode_FULL()
return;
}
}
//the rest of the pan handling code, namely translating the view up and up follows here
Hope this helps somebody.

How can I use a HammerJS pinch gesture on iOS without scrolling a page?

I'm using Ember-Gestures which implements Hammer.js in a Cordova app to implement some simple gesture controls.
I'm running into a major problem whereby any gesture that triggers an animation (transition, transform, SVG animations), if the screen is scrolling any amount, that animation will freeze and be at its end state when scrolling is complete. In particular, I have an element on a vertically scrollable page which should (ideally) be able to be pinched in and out to expand it into multiple elements or back into one.
I'm familiar that as an optimization iOS freezes all animation during scroll. However, since pinch and swipe gestures can both slightly scroll the screen, this is terrible for user experience because elaborate transitions can be completely frozen if the user swipes, for example, slightly up and to the left rather than just directly left.
I've tried a few solutions to enable rendering during scroll like those here, but these don't seem to work on contemporary versions of iOS. I've also tried the hammerJS e.preventDefault() method to freeze scrolling during gestures called through the Ember-gestures extension, so my method looks like:
swipeLeft(e) {
e.originalEvent.gesture.srcEvent.preventDefault()
// Do stuff
},
...but this doesn't have any appreciable effect. (Maybe there's something wrong here? gesture had no preventDefault() method itself, and ember-gestures seems to try to abstract some of this away.
Is there any way I can either keep animations rendering during scrolling (this seems unlikely), or alternately STOP a page from scrolling right before performing an animation (and prevent scroll while it's executing)?
Alternately is there any way I can add constraints to what is interpreted as a "pinch" or "swipe" gesture such that those that would also be interpreted as scroll gestures are excluded.
My solution here ended up being to add event handlers such that when the screen is touched with multiple fingers, the body is set to fixed position such that it's unscrollable for the duration of the touch (with the fixed position removed when touch is ended). I added the handlers to the pinchStart and pinchEnd events
I suspect there might be a more elegant solution out there, but for the purpose of disabling accidental scrolling while pinching so that D3.js animations won't freeze midway, this was a quick and effective fix.

Slide Effect for iOS

I'm new to developing iOS apps,
I've successfully implemented a Swipe Gesture Recognizer,
What I was wondering is if there is an easy to use recognizer like the swipe gesture. That would let you implement the homescreen page turning effect but just on a small view in the view controller?
If your unclear on what effect I mean, when you look at the iPhone's homescreen you can drag your finger and it responds instantly (unlike swipe) and also has some spring feeling to it, is this some effect I can use, or do I manually have to program this into the code if so is there a tutorial that explains this?
Thanks,
I hope my question makes sense.
Have a look at UIPanGestureRecognizer:
https://developer.apple.com/library/ios/documentation/uikit/reference/UIPanGestureRecognizer_Class/Reference/Reference.html
UIPanGestureRecognizer is a concrete subclass of UIGestureRecognizer
that looks for panning (dragging) gestures. The user must be pressing
one or more fingers on a view while they pan it. Clients implementing
the action method for this gesture recognizer can ask it for the
current translation and velocity of the gesture.
A panning gesture is continuous. It begins
(UIGestureRecognizerStateBegan) when the minimum number of fingers
allowed (minimumNumberOfTouches) has moved enough to be considered a
pan. It changes (UIGestureRecognizerStateChanged) when a finger moves
while at least the minimum number of fingers are pressed down. It ends
(UIGestureRecognizerStateEnded) when all fingers are lifted.
Clients of this class can, in their action methods, query the
UIPanGestureRecognizer object for the current translation of the
gesture (translationInView:) and the velocity of the translation
(velocityInView:). They can specify the view whose coordinate system
should be used for the translation and velocity values. Clients may
also reset the translation to a desired value.
Edit: The spring feeling part you would need to implement yourself. Since iOS 7 there is UIDynamics which contains different animators, for what you describe you may need UIGravityBehavior and maybe UICollisionBehaviour. Look at the WWDC 2013 videos for this topic, I think you will find some examples there.

Resources