We enabled 3D touch quite a few daily builds back. What version of Corona SDK are you using?
EDIT: It was added in daily build 2775.
Rob
We enabled 3D touch quite a few daily builds back. What version of Corona SDK are you using?
EDIT: It was added in daily build 2775.
Rob
Just saw it. Thanks! I’m using 2790 so all i need to check is if pressure is changed to properly interpret a move event right? Sorry I don’t have an iPhone 6 to test it around yet.
Okay that is weird. I was logged in using this account yesterday too but it registered my other account.
Hi @corona4182,
Does this only occur on the 6S? If so, does it only occur when you use the “3D touch” feature? Please provide some more detail and we can do a little testing on our side.
Thanks,
Brent
Only on 6S, since all our other devices in iOS 9 didn’t have this problem. It started happening on a 6S, so most likely due to 3D touch.
As for the code, it happens with the “onEvent” of a button. You get events with a phase “moved” at the same position the phase “began” was sent. Since our code forwards the event to the parent group (due to scrollview things), so we detect a move but the user hasn’t actually moved.
Hi @corona4182,
Can you do a print of the event.x and event.y at the same time, to distinguish how (or if) those change between the regular tap and “force touched” events? Remember that a “moved” phase can occur on just the very slightest x/y position change, so that might be what is actually happening… but if the x and y are identical between these two events, then I’ll need to ponder a solution or workaround.
Brent
I meant that neither X or Y changes. I didn’t keep the logs, but the x and y values stayed the same on 6S with force touch, so the total move was 0. While on other devices, I didn’t have a move until there was actually a change in value.
The only difference between the two events (I stored them in json and made a file diff with them to be sure) was the event phase.
I heard from native developers that it also happens on native, the 6S triggers moved events of 0 pixels, which bugs a lot of apps. Maybe you could just ignore events when the move has a 0 pixels difference.
In my case I just check if the total moved distance is > to 5 pixels before forwarding the event to my scrollview
Hi @corona4182,
Thanks for your notes and observations, especially that this seems to affect native-built apps as well.
I will discuss a potential solution with the engineering team. We probably will not just globally dismiss/ignore all subsequent “moved” phase events with the same x/y position, because that is (in effect) a way to actually support 3D Touch, and some developers clearly want that already. More likely, it would be a “system.activate()” setting to toggle the option on/off, and so users who did not care about using any 3D touch functionality in their app could safely turn that option off (most likely, the default would be off, and enabling it would be exception since 3D touch is isolated to only the new iPhones).
In the meantime, I think you can work around this in your own code, perhaps like this:
[lua]
local function touchListener( event )
local objTouched = event.target
if not ( objTouched.prevTouch ) then
objTouched.prevTouch = { x=event.x, y=event.y, touch3D=false }
else
if ( event.x == objTouched.prevTouch[“x”] and event.y == objTouched.prevTouch[“y”] and “moved” == event.phase ) then
– If a moved phase is registered on the exact same X/Y, then set the boolean 3D touch flag
objTouched.prevTouch[“touch3D”] = true
elseif ( ( event.x ~= objTouched.prevTouch[“x”] or event.y ~= objTouched.prevTouch[“y”] ) and “moved” == event.phase ) then
– If an actual move occurs, for example if the user (even following a 3D touch)
– moves the touch point, reset the boolean flag to false
objTouched.prevTouch[“touch3D”] = false
end
if ( “moved” == event.phase and objTouched.prevTouch[“touch3D”] == true ) then
print( “THERE WAS A 3D TOUCH!” )
elseif ( “moved” == event.phase and objTouched.prevTouch[“touch3D”] == false ) then
print( “NORMAL MOVED EVENT!” )
elseif ( “ended” == event.phase or “cancelled” == event.phase ) then
objTouched.prevTouch = nil
end
end
return true
end
[/lua]
Note that I just hacked this code out and haven’t tested it on a 6S. In fact, if you could test this on your end and see if it works, I’d appreciate it, and if I didn’t take into account some conditions, then provide your input and I can tune this up for others who might be facing the same issue.
Thanks,
Brent
Well you don’t have to dismiss it, you could just add a new event for 3D touch (just a new phase, like “forcetouch” or whatever) that would contain the amount of pressure or something.
That way you can keep the “move” events for when the user actually moved. Otherwise, it’ll be really unclear to developers because moving 0 pixels is not intuitive at all.
Also, as far as I see there is currently no information about the 3D touch in the events, so I don’t see what people could do with a move event of 0 pixels, if they don’t have any pressure information anyway. This event of 0 pixels seem to be fired all the time, as soon as you touch the button, so it would be worthless. Even if you try to lightly touch the button and release it, you will get the 0 pixels move. I suppose it’s fired as soon as there is even a tiny bit of pressure.
Really I’d say the best way would be a new phase specifically for pressure, so that it doesn’t change anything to users who just want classic touch.
As for your code, I don’t have the 6S with me so can’t try it. I suppose it would work, but I prefer my way of checking the pixels distance, seems a bit more safe.
My code’s like that:
self.info.onEvent = function (event) local phase = event.phase if phase == "began" then self.previousTouch = {x = event.x, y = event.y} elseif phase == "moved" then if self.group.takeFocus and self.previousTouch then -- This is where I forward my event to a scrollview if there was a move. The distPoints function just calculates the distance between two vectors -- I have 5 pixels of safety, which avoids false events and also adds a bit of tolerance if the user moved their finger a bit but still wanted to actually click if utils.distPoints(self.previousTouch, event) \> 5 then self.group:takeFocus(event) end end elseif phase == "ended" then if self.clickCallback and self.active then self:toggle() end end return false end
Hi @corona4182,
Good points, we’re still looking into what the best solution is. If this is affecting native-built apps too, I wonder if Apple intends to do anything like expose a system-wide “this feature exists” or not, since asking every iOS developer to suddenly update their apps based on this odd handling of the 3D touch is a bit odd, to say the least.
As for getting a “moved” event when you lightly ( not 3D touch) an object in Corona, that absolutely should not be happening, unless that is also a new behavior isolated to the 6S line. Up until this point, Corona has never triggered a “moved” event until the touch actually moves by a perceptible (according to the OS) amount. I’ll do a little testing to see if this has changed on 6S.
Best regards,
Brent
Hi @corona4182,
I just did a little testing on an iPhone 6S and, unfortunately, my “should not happen” case actually does happen… merely touching on the screen without any movement whatsoever (same exact x/y position) generates a constant stream of “moved” events. We’re going to explore what the best solution is, but in the meantime, I suggest you add a workaround like I suggested, or what you did with checking the pixel distance.
Brent
On that note, it looks like your code workaround is the only one that will solve this in the short term, because my previously-suggested workaround won’t distinguish between the user simply touching down (and not moving) and the user actually pressing harder for a 3D touch.
Brent
Just to understand this (as I don’t yet have a 6S, but do have customers on who’s 6s my app isn’t seeing certain touch events):
On the 6S are we saying that NO touch event is generated, just a Move event of 0 px?
-Tom
Hi Tom,
Specifically, “moved” is a phase of the “touch” event… so if no touch event is generated, that’s not a 6S issue, it’s something in your code.
Brent
D’oh! Of course. It’s been a couple of years since I looked at that code.
So to confirm: in other phones, for a touch we see:
began
ended
For a move, we see:
began
moved
moved
… (as long as finger is moving)
ended
but on the iPhone 6s, we see:
began
moved
moved
… (as long as finger is still touching)
ended
?
-Tom
Hi Tom,
Essentially, in the 6S, you get this:
– TOUCH BEGINS
“began” phase
“moved” phase (with x/y position change of 0)
“moved” phase (with x/y position change of 0) when a 3D touch is made
– TOUCH MOVES
– TOUCH LIFTS OFF
So on earlier phones, #2 and #3 did not occur. We’re looking into how to properly handle this, so I’ll update this thread when I know more.
Best regards,
Brent
Perhaps a better way to look at it is that on certain devices you get not just X/Y touch, but X/Y/Z touch. You just don’t get the “force” property (Z axis) from Corona yet. So a “3D touch” isn’t only when you move 0/0 in X/Y. You can move in Z to do a force touch while also moving in the X/Y directions. A force touch is just a threshold in the Z direction before you trigger some special UI.
Thanks for the details. This has helped me identify where the likely problem is in my code.
-Tom
Is there any difference on the 6s with Tap events?
I’m using code borrowed from the widgetLibrary/widget_tableview code of several years ago to deal with taps on possibly moving objects. My 6s users are finding that it is virtually unresponsive to taps, even when carefully not moving. I think I’ve dealt with code that might get upset with lots of moved events with dy < a threshhold, but obviously I haven’t done enough or there’s another problem.
Short of dropping $1000 to grab a new phone, any thoughts on what else might have changed?
-Tom
Hi Tom,
Well, tap events don’t have phases, so I can only assume that there’s a touch event that might be overriding it. Can you post the most simple code block here so I can test it on a 6S?
Brent