{ "id": "99605", "key": "TIMOB-10554", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "14098", "description": "Sprint 2012-18 API", "name": "Sprint 2012-18 API", "archived": true, "released": true, "releaseDate": "2012-09-10" } ], "resolution": { "id": "7", "description": "", "name": "Invalid" }, "resolutiondate": "2012-09-05T18:58:19.000+0000", "created": "2012-08-22T08:01:58.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "api" ], "versions": [ { "id": "13572", "description": "Release 2.1.1", "name": "Release 2.1.1", "archived": true, "released": true, "releaseDate": "2012-07-31" } ], "issuelinks": [ { "id": "20529", "type": { "id": "10011", "name": "Includes", "inward": "is included by", "outward": "includes" }, "inwardIssue": { "id": "100406", "key": "TIMOB-10747", "fields": { "summary": "TiAPI: Ti.Gesture is for user input via hardware, not for the software response", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "7", "description": "gh.issue.story.desc", "name": "Story", "subtask": false } } } } ], "assignee": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2017-03-29T17:18:22.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "h2. Actual results on device\r\n\r\nThe 'orientationchange' fires twice, and fires with a small shake or tap on the device once with bogus orientation values and the second time with a valid value. This doesn't happen in the simulator. And it doesn't happen on Android. As a result, you can't use an if/else wrapper for the Ti.Gesture.isPortrait/isLandscape functions as shown below. You must explicitly test with an if/elseif block. \r\nh2. Expected results:\r\n\r\nThe 'orientationchange' event would fire once, after orientation changes with e.orientation/Ti.Gesture.orientation reporting a non-zero value (which should be reserved for only the face up/down/unknown state). Shaking or tapping the device would not cause 'orientationchange' to fire.\r\n\r\n{code}\r\n// Drop into a new project, test on device\r\n\r\nTitanium.UI.setBackgroundColor('#000');\r\nvar win1 = Titanium.UI.createWindow({ \r\n backgroundColor:'#fff'\r\n});\r\n\r\nvar label1 = Titanium.UI.createLabel({\r\n color:'#444',\r\n text:'Orientation: Rotate/shake to change',\r\n font:{fontSize:18,fontFamily:'Helvetica Neue', fontWeight: 'bold'},\r\n textAlign:'center',\r\n width:Ti.UI.FILL,\r\n top: 2\r\n});\r\nwin1.add(label1);\r\n\r\nvar ta = Ti.UI.createTextArea({\r\n left:1, top: 25,\r\n textAlign: 'left',\r\n width: Ti.UI.FILL,\r\n height: Ti.UI.FILL,\r\n value: ''\r\n});\r\nwin1.add(ta);\r\nvar taText = '';\r\nfunction appendTA(txt) {\r\n ta.value = ta.value + '\\n' + txt;\r\n}\r\n\r\nTi.Gesture.addEventListener('orientationchange', function(e) {\r\n if(Ti.Gesture.isPortrait()) {\r\n appendTA('e.orientation/Ti.Gesture.orienation = ' + e.orientation + '/' + Ti.Gesture.orientation);\r\n appendTA('-------------------------')\r\n } else {\r\n appendTA('e.orientation/Ti.Gesture.orienation = ' + e.orientation + '/' + Ti.Gesture.orientation);\r\n appendTA('-------------------------')\r\n }\r\n});\r\n\r\n\r\nwin1.open();\r\n{code}\r\n\r\n", "attachment": [ { "id": "30658", "filename": "ipad.png", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2012-08-22T08:01:58.000+0000", "size": 108325, "mimeType": "image/png" } ], "flagged": false, "summary": "iOS: orientationchange event fires twice, once with bogus data", "creator": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "subtasks": [], "reporter": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "environment": "Ti SDK 2.1.1 GA, though reportedly problem exists in prior SDKs\r\niPad/iOS 5", "comment": { "comments": [ { "id": "215955", "author": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "This is likely invalid. Android treats UI and device orientation as one and the same, but for iOS, Ti.Gesture reports the orientation of the device, NOT the orientation of the UI. By shaking the device slowly, you are telling the device that down is in the opposite direction, then that down is back to where it was. Remember that you can't tell the difference between gravity and any other acceleration. (Blame Einstein for that one)\r\n\r\nWe need to hammer out parity on Ti.UI.orientation or Ti.UI.Window.orientation and possibly create an event to trigger on UI orientation changes, so people use that instead of the accelerometer-triggered event.", "updateAuthor": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2012-08-23T20:30:32.000+0000", "updated": "2012-08-23T20:32:26.000+0000" }, { "id": "215990", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "The main part of this ticket is that the orientationchange event fires twice. One time, the e.orientation/Ti.Gesture.orientation values are 0, the second time they hold valid data. Before marking this invalid, make sure you consider that beyond the part about the shake.\r\n\r\nA simple solution might be to account for this double firing in the isPortrait/isLandscape functions. With this double-firing, those helpers are of limited utility and reports from the field indicate people are simply writing their own versions instead of using what we supply.", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2012-08-24T05:28:56.000+0000", "updated": "2012-08-24T05:28:56.000+0000" }, { "id": "217450", "author": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Interesting, that makes sesne. 0 is Ti.Gesture.UNKNOWN. That is, it knows it's no longer portrait, but the force on the accelerometer is too conflated or too weak to have a 'down'. So the data is valid, just not what's expected, despite being true.\r\n\r\nHere's the sticky wicket. How far should we deviate from what is actually natively presented? My main point is that the test is checking for a hardware situation when it should be testing for a software situation. Gesture may dictate part of how the display is laid out, but it's neither sufficient nor necessary.", "updateAuthor": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2012-09-04T10:44:19.000+0000", "updated": "2012-09-04T10:44:19.000+0000" }, { "id": "217748", "author": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Ti.Gesture.orientationchange is an event triggered by the hardware accelerometer, and does not reflect the window's orientation. Watch TIMOB-10790 for the new event to listen for.", "updateAuthor": { "name": "blainhamon", "key": "blainhamon", "displayName": "Blain Hamon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2012-09-05T18:58:10.000+0000", "updated": "2012-09-05T18:58:10.000+0000" }, { "id": "416199", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as invalid.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-29T17:18:22.000+0000", "updated": "2017-03-29T17:18:22.000+0000" } ], "maxResults": 5, "total": 5, "startAt": 0 } } }