{ "id": "171929", "key": "TIMOB-26211", "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": "20238", "description": "", "name": "Release 7.5.0", "archived": false, "released": true, "releaseDate": "2018-11-15" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2018-08-24T17:22:22.000+0000", "created": "2018-07-13T21:04:52.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "horizontal", "iOS", "layout", "percent" ], "versions": [], "issuelinks": [ { "id": "56687", "type": { "id": "10002", "name": "Duplicate", "inward": "is duplicated by", "outward": "duplicates" }, "inwardIssue": { "id": "152864", "key": "TIMOB-19900", "fields": { "summary": "iOS Layout: Views wrap while their total width % equals 100", "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" } }, "priority": { "name": "Medium", "id": "3" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } } ], "assignee": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "updated": "2018-09-11T18:47:25.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": "*Summary:*\r\niOS will incorrectly wrap views within a horizontal layout if their percentage based widths total to 100%. This is not an issue on Android.\r\n\r\n*Steps to reproduce:*\r\n# Build and run [^HorizontalPercent50x50Test.js] on iOS.\r\n# Note that the left view width is 50% and the right view width is 50%.\r\n# Observe the layout.\r\n\r\n*Result:*\r\nOn iOS, the right view is wrongly wrapped to the next row.\r\n !HorizontalPercent-iOS-bad.png|thumbnail! \r\n\r\n*Expected Result:*\r\nBoth views are expected to be on the same row since they both have a width of 50%. Android does this correctly as seen here...\r\n !HorizontalPercent-Android-good.png|thumbnail! \r\n\r\n*Work-Around:*\r\nUse {{Ti.UI.FILL}} to the right-most view's {{width}} property instead of using a percentage.\r\n\r\n*Note:*\r\nThe attached [^HorizontalFillTest.js] provides a more complex horizontal layout test. iOS has 2 issues with this as well:\r\n* The {{Left (50%) | Right (50%)}} test shows that the views are wrongly shrunk to 25% width instead of 50%.\r\n* The yellow {{(75%)}} label does not have the same width as the {{(25%)|(50%)}} labels above it.\r\n\r\niOS looks like this...\r\n !HorizontaFill-iOS-bad.png|thumbnail! \r\n\r\nAndroid handles it correctly as can be seen here...\r\n !HorizontalFill-Android-good.png|thumbnail! \r\n", "attachment": [ { "id": "65370", "filename": "Bildschirmfoto 2018-07-20 um 22.27.03.png", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-07-20T20:27:26.000+0000", "size": 394664, "mimeType": "image/png" }, { "id": "65371", "filename": "Bildschirmfoto 2018-07-20 um 22.31.05.png", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-07-20T20:32:34.000+0000", "size": 1127329, "mimeType": "image/png" }, { "id": "65353", "filename": "HorizontaFill-iOS-bad.png", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-07-13T20:54:20.000+0000", "size": 59750, "mimeType": "image/png" }, { "id": "65352", "filename": "HorizontalFill-Android-good.png", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-07-13T20:54:20.000+0000", "size": 83435, "mimeType": "image/png" }, { "id": "65357", "filename": "HorizontalFillTest.js", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-07-13T20:54:13.000+0000", "size": 6942, "mimeType": "application/x-javascript" }, { "id": "65356", "filename": "HorizontalPercent50x50Test.js", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-07-13T20:54:13.000+0000", "size": 447, "mimeType": "application/x-javascript" }, { "id": "65355", "filename": "HorizontalPercent-Android-good.png", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-07-13T20:54:20.000+0000", "size": 30256, "mimeType": "image/png" }, { "id": "65354", "filename": "HorizontalPercent-iOS-bad.png", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-07-13T20:54:20.000+0000", "size": 22167, "mimeType": "image/png" } ], "flagged": false, "summary": "iOS: Percentage based layout rounds floating widths/heights incorrectly", "creator": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "closedSprints": [ { "id": 1065, "state": "closed", "name": "2016 Sprint 17 SDK", "startDate": "2018-08-13T17:39:36.846Z", "endDate": "2018-08-27T17:39:00.000Z", "completeDate": "2018-08-29T16:10:57.013Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "439364", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Mhh, it seems to work just fine (tested on [iPhone|https://abload.de/img/simulatorscreenshot-i66i8r.png] and [iPad|https://abload.de/img/simulatorscreenshot-i94ddy.png]):", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-07-20T14:57:38.000+0000", "updated": "2018-07-20T14:57:38.000+0000" }, { "id": "439365", "author": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "body": "can you try it with an iphone 7 simulator? I got feedback of an app that wasn't showing all buttons (4 with 25%). The last button is only visible when I change to around 24.85%. All other phones where happy with 25% but one user mentioned that on his iphone 7 it wasn't working right.", "updateAuthor": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-07-20T15:05:03.000+0000", "updated": "2018-07-20T15:05:03.000+0000" }, { "id": "439368", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Can you try to {{Math.ceil}} the calculations, see TIMOB-26221", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-07-20T15:22:54.000+0000", "updated": "2018-07-20T15:22:54.000+0000" }, { "id": "439373", "author": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "body": "ah, if you mean Math.floor then you are right, that works too.\r\n\r\nDevice width is 375 (so it is 93.75 at 25%) for my 4 buttons it will be\r\n\r\n* setting it to 25% -> the last button is not visible\r\n* setting it to Math.ceil() -> one button is 94 width -> sum 376 = button is missing\r\n* setting it to Math.floor() -> one button is 93 width -> sum 372 = button is shown", "updateAuthor": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-07-20T16:23:26.000+0000", "updated": "2018-07-20T16:23:26.000+0000" }, { "id": "439374", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "For the other case, Math.ceil worked as well, but that's a quite different case because {{more}} space was needed. Do you think, this should be done internally? It might be tricky to know if rounding up or down would be required\r\n", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-07-20T16:30:10.000+0000", "updated": "2018-07-20T16:30:10.000+0000" }, { "id": "439378", "author": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "body": "Like you say, would be hard to decide which one you need. \r\nPerhaps there should be a warning when you set width/height to percentages on iOS and you'll end up with a floating point number? So the user can decide", "updateAuthor": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-07-20T17:08:17.000+0000", "updated": "2018-07-20T17:08:17.000+0000" }, { "id": "439379", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "If you look at !HorizontaFill-iOS-bad.png|thumbnail! you see a 25% and 50% views placed next to each other and a 75% sized view below it. The 2 views above seem to be a couple pixels wider than the bottom 75% view. I got the impression that a view was being set wider than configured and that's why it was wrapping.\r\n\r\nNote that I reproduced this issue in the iOS simulator. I have not tried on a real devices.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-07-20T17:15:23.000+0000", "updated": "2018-07-20T17:15:23.000+0000" }, { "id": "439383", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "!Bildschirmfoto 2018-07-20 um 22.31.05.png|thumbnail!\r\n\r\nIt seems to be a device specific issue, which is in general a good thing! I'm betting on either the scale factor or the rounding, and I bet on the rounding, because the screen width of the iPhone 7 may have a modulo > 0, resulting in rounding errors, resulting in this glitch.\r\n\r\n*EDIT*: That's the reason. An iPhone 5 has a base width of 320 px (160 px at 50%). The iPhone 7 has a base width of 375 px (157.5 px at 50 %). And the core rounds up by default, so it's 158+158 = 376, which results in a new line. Any ideas how to solve this practically?\r\n\r\n*EDIT 2*: It can be solved by removing the {{roundf}} [here|https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiDimension.h#L109], but I need to check on the possible side affects. [~jquick] do we have a full layout test app already?\r\n\r\n*EDIT 3*: TIMOB-11977 is where the rounding was introduced (SDK 3.1.0), with a valid reason. How does Android handle this?", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-07-20T20:32:52.000+0000", "updated": "2018-07-20T20:46:30.000+0000" }, { "id": "439384", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "PR: https://github.com/appcelerator/titanium_mobile/pull/10194\r\n\r\nTest-Cases: See the ones above + the one from TIMOB-11977.", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-07-20T20:56:43.000+0000", "updated": "2018-07-20T20:57:26.000+0000" }, { "id": "439496", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "PR (7_3_X): https://github.com/appcelerator/titanium_mobile/pull/10214\r\n", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-07-26T10:27:31.000+0000", "updated": "2018-07-26T10:27:31.000+0000" }, { "id": "440951", "author": { "name": "kmahalingam", "key": "kmahalingam", "displayName": "Keerthi Mahalingam", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Verified as fixed.Closing ticket.Tested SDK version 7.4.0.v20180820065502 \r\n\r\nTest Environment:\r\nAPPC Studio: 5.1.0.201808080937\r\nAPPC CLI: 7.0.5\r\niPhone 7 simulator (11.0)\r\niPhone 5simulator (11.4)\r\niPhone 6s simulator (11.0)\r\niPhone 6s -10.0\r\nOperating System Name: Mac OS High Sierra\r\nOperating System Version: 10.13.6\r\nNode.js Version: 8.9.1\r\nXcode 9.4.1", "updateAuthor": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-08-21T17:56:57.000+0000", "updated": "2018-08-21T19:33:55.000+0000" }, { "id": "440956", "author": { "name": "kmahalingam", "key": "kmahalingam", "displayName": "Keerthi Mahalingam", "active": false, "timeZone": "America/Los_Angeles" }, "body": "[~hknoechel] i tested with the sdk mentioned in PR of this ticket and i dont see the bug in the sdk mentioned.it seems not merged in 7.3. GA, bug present in 7.3.GA and latest 7.3.X SDK.\r\n", "updateAuthor": { "name": "kmahalingam", "key": "kmahalingam", "displayName": "Keerthi Mahalingam", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2018-08-21T19:15:26.000+0000", "updated": "2018-08-21T19:15:26.000+0000" }, { "id": "441485", "author": { "name": "kmahalingam", "key": "kmahalingam", "displayName": "Keerthi Mahalingam", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Verified the fix on SDK 7.5.0.v20180911090425. Works fine. Closing.\r\n{code}\r\nOperating System\r\n Name = Mac OS X\r\n Version = 10.13.6\r\nNode.js\r\n Node.js Version = 8.9.1\r\n npm Version = 5.5.1\r\nTitanium CLI\r\n CLI Version = 5.1.1\r\nTitanium SDK\r\n SDK Version = 7.5.0.v20180911090425\r\niPhone6s =Ios 11\r\niPhone 5s . = Ios 12 emulator\r\n{code}", "updateAuthor": { "name": "kmahalingam", "key": "kmahalingam", "displayName": "Keerthi Mahalingam", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2018-09-11T18:47:11.000+0000", "updated": "2018-09-11T18:47:11.000+0000" } ], "maxResults": 17, "total": 17, "startAt": 0 } } }