3D touch seems really cool and I wanted to see how it would work in a musical context. I was reading a bit about 3D touch and it seems like the force property almost always reads as 0 when a touch begins (touchesBegan method).
How do I get a usable force when a touch begins because even if I'm pressing with maximum "force" I'm still getting that initial 0? I was thinking about just approximating a value within a time frame but that would involve me moving the touch. I just want a usable force upon the first touch.
Thanks!
Unfortunately this is impossible.
Every touch starts as a contact with no force at all, as soon as the user's finger makes contact (or even near-contact) with the screen. The force only starts to build as the user's finger is compressed against the screen.
The only way for touchesBegan: to report any force at all would be for it to delay artificially for a certain number of milliseconds before reporting a touch, to allow the force to build up. This would destroy the interactivity of all iOS applications; and Apple put a huge amount of work into delivering a touch the instant it is detected.
Related
Implementing a sort of 'distress call' button which should work as following:
User starts application and covers a screen with a palm of a hand
Some time passes, user may introduce additional touches during that time or remove some of the existing (but not all of them), location/shape of touches may change
When user releases a hand (i.e. removes last touch) a distress signal is emitted by the app
Basically, the app should register two events: (1) a screen is touched (2) all touched are released
I'm trying to use touchesBegan/touchesEnded methods and those work for small area touches (fingertips) but on touching screen with a full palm or even only palm edge a touchesCancelled gets triggered immediately while hand is still on the screen. Obviously no other events are emitted upon hand release afterwards.
I tried subclassing UIWindow and UIApplication and overriding sendEvent in those but got no additional info - large area touches are triggering touch begin and immediately touch cancel, releasing hand afterwards emits nothing. In some cases large area touches fire no events at all, not even the touchesBegan. Basically, iOS doesn't let me work with a very basic scenario - detecting just the fact of screen touch/release.
Is there any way to query the screen touch state directly and not work with responder chain? Or suppress the cancellation event from firing? Or maybe I'm missing something?
Unfortunately, as of right now, no solution exists
I'm testing the touch detection capabilities of the iPad (specifically iPad 3 at the moment). I'm printing out a log of detected touches to see what is going on, and using a bottle with three foam (touch friendly) pads at the bottom.
The touches are detected fine and it logs any slight movements which is great. The issue is that after a while if the bottle isn't moved at all, all three touches are forcibly cancelled and remain undetected until the bottle is removed and placed back down.
So it seems there's a timeout on these touches... I have not found any specific information on this. Is there any way to revive or keep alive touches without having to physically remove and restore your touch points?
A capacitive touch sensor is a very sensitive instrument, and a lot of filtering is done before the OS reports touches to you. This is also the reason why the iPad cannot detect touches with smaller contact areas than what comes with cheap styli - rubber domes of about 7mm diameter. The touchscreen controller detects smaller touches alright, but filters them to avoid spurious signals. Note that the touchscreen of a Samsung Galaxy will already detect touches with a dull pencil - the screen is (for practical purposes) the same as that of an iPad, but the cutoff for the controller is lower.
I would expect that the self-calibrating logic inside the touch controller will calibrate your touches away. Basically, it will set the signal produced by your foam pads as the new normal. On the application side there is nothing that you can do to reverse this.
Disclaimer: I have no inside knowledge of what goes on inside the touchscreen controller. My answer is based on much reading and solid reasoning, nothing more.
I wonder if I can detect continuously changing pressure of user input on iPhone 6s.
With simple touch it's obvious, from the UIResponder you can hook into touchesBegan and TouchesMoved and you'll have the coordinates every time when the user touches the screen and when moves his/her finger, you can have the current position on every update.
However, I'm not sure how the new :force property works. If you read the "force" in touchesBegan, wouldn't you get some minimal pressure value that was detected at the initiation of the touch?
Is there a way to get update on the force value as it changes, just like the touchesMoved? Maybe there is a method like "forceChanged"?
From the iOS 9.1 Release Notes
On 3D Touch capable devices, touch pressure changes cause touchesMoved: to be called.
Apps should be prepared to receive touch move events with no change in the x/y coordinates.
This means that a touchesMoved: callback either indicates a continuous change in force or location or both!
Hopefully this information will one day make it into the UITouch documentation.
I'm making an iOS game, and I want to be able to control the movement of my character with a toggle.
My idea is that when the user touches the screen with their thumb / finger, I will record where the touch began, and then whichever direction the users thumb is compared to where the touch began is the direction the character should move.
How could I setup a touch gesture recogniser to do this?
Cheers
Hmm, it sounds to me like you are thinking of this at too high of a level. You don't need a "gesture recognition system" to do this. You know how to tell whether and where the touch is down? You know how to tell what time it is? Each time through your main loop, check if the touch is down / still down. When it first goes down, record the location and time. If later you see that it hasn't gone up and it's positioned a certain number of pixels to the right, you know it slid over there. And by comparing the times you know how fast it slid over there.
And of course you might want to check out Cocos2d for a library that does some of this for you. But it's worth doing yourself first, just to learn it.
I'm working on a game, and I'm using a CAEAGLLayer backed UIView subclass to present the game engine. Touch handling is done using -touchesBegan:withEvent: et. al.
Everything works fine, except that very rarely, if one of the on-screen controls is tapped rapidly, -touchesBegan:withEvent: doesn't get called for somewhere between 0.1 and 1-2 seconds. This happens maybe one in 20 times, and only if you tap the screen rapidly (4-5 times) first. It seems to be more likely to happen if I am also holding down another finger on a different control on the screen.
Thinking that it was something to do with my own code, I subclassed UIApplication so I could add a logging statement to -sendEvent:. When the laggy touch happens, -sendEvent: doesn't get called until some period of time after the touch has started, so it the touch handling code inside my UIView subclass doesn't appear to be at fault.
Does anyone have any idea what's going on here (other than iOS having some obscure bug)? Is there some sort of internal "events queue" that makes event delivery become laggy when it fills up? Has anyone else experienced this?
Touch events are only dispatched in the main UI run loop, and sometimes only when the main run loop goes idle for a bit. So if your app is busy handling several previous touch events in a row without taking a break, the main UI run loop might be saturated, and thus not get any further touch events until done with the current stuff.
Touch events also have time stamps. So you can check if they're coming too fast (faster than your event handlers and resulting UI updates can run), and skip or combine some of the event handlers, as appropriate for your app, if you want the app to stay maximally responsive.