{ "id": "174720", "key": "TIMOB-27760", "fields": { "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "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": [], "resolution": null, "resolutiondate": null, "created": "2020-02-11T14:52:24.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "scrollview" ], "versions": [], "issuelinks": [], "assignee": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2020-02-12T19:54:28.000+0000", "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" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" }, { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "The ScrollView currently doesn't have {{contentInset}} support. Adding this feature would greatly improve UI/UX on apps that don't have NavigationWindow as their main element.\r\n\r\niOS documentation: https://developer.apple.com/documentation/uikit/uiscrollview/1619406-contentinset\r\n\r\n", "attachment": [ { "id": "67273", "filename": "Example-Android.png", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-02-11T20:00:04.000+0000", "size": 63049, "mimeType": "image/png" }, { "id": "67274", "filename": "Example-iOS.png", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-02-11T20:00:09.000+0000", "size": 87029, "mimeType": "image/png" }, { "id": "67272", "filename": "ScrollViewInsetTest.js", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-02-11T19:56:11.000+0000", "size": 874, "mimeType": "application/x-javascript" } ], "flagged": false, "summary": "ScrollView: add contentInset support", "creator": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "environment": null, "comment": { "comments": [ { "id": "454184", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~topener], you can already do this \"today\" by settings up a container view with the padding/insets you want. When you set a view's {{width}} and {{height}} properties, the view's {{left}}/{{right}}/{{top}}/{{bottom}} properties are used as padding. For example...\r\n{code:javascript}\r\nvar containerView = Ti.UI.createView({\r\n\tlayout: \"vertical\",\r\n\tleft: \"5dp\",\r\n\tright: \"5dp\", \r\n\ttop: \"5dp\",\r\n\tbottom: \"5dp\",\r\n\twidth: Ti.UI.FILL,\r\n\theight: Ti.UI.SIZE,\r\n});\r\n{code}\r\n\r\nYou can use the above as a container. The idea is you add the above view to the {{ScrollView}}. You would put the child content into that container, so the container view's padding effectively become the insets you want. Try out the below test code. It works on both Android and iOS.\r\n [^ScrollViewInsetTest.js] \r\n !Example-Android.png|thumbnail! !Example-iOS.png|thumbnail! \r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-02-11T20:00:19.000+0000", "updated": "2020-02-11T20:00:19.000+0000" }, { "id": "454185", "author": { "name": "arood", "key": "arood", "displayName": "Marcus Olovsson", "active": true, "timeZone": "Europe/Berlin" }, "body": "@Joshua Quick The padding workaround doesn't work in all cases. For example if you would want to set a native Ti.UI.RefreshControl on the scrollview, you'd notice that on a device with a notch the refresh indicator always appears behind the notch, as it's unaffected by the views inside the scrollview.", "updateAuthor": { "name": "arood", "key": "arood", "displayName": "Marcus Olovsson", "active": true, "timeZone": "Europe/Berlin" }, "created": "2020-02-11T20:09:56.000+0000", "updated": "2020-02-11T20:09:56.000+0000" }, { "id": "454188", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-02-12T01:09:38.000+0000", "updated": "2020-02-12T01:26:42.000+0000" }, { "id": "454190", "author": { "name": "arood", "key": "arood", "displayName": "Marcus Olovsson", "active": true, "timeZone": "Europe/Berlin" }, "body": "Sorry but that doesn't solve the problem, as it wouldn't make the contents of the scrollview appear behind other components *while* scrolling, which is a common design pattern.\r\n\r\nI could use the safeAreaPadding to add a fake inset with views, like you mentioned before, however this doesn't work very well if you use a RefreshControl (which doesn't have any layout properties) on the scrollview as it still would appear behind the notch or any other view that overlays the scrollview.", "updateAuthor": { "name": "arood", "key": "arood", "displayName": "Marcus Olovsson", "active": true, "timeZone": "Europe/Berlin" }, "created": "2020-02-12T07:05:37.000+0000", "updated": "2020-02-12T07:05:37.000+0000" }, { "id": "454220", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Okay. I see the disconnect here.\r\n\r\nYou don't need the ability to set arbitrary view insets. The real issue (from what I can see) is that the {{RefreshControl}} is not automatically compensating for the system/device insets and it ends up being overlapped. I'm going to close this ticket and rewrite it as that... because you wouldn't get the solution you want from the way this ticket is written.\r\n\r\n*Side Note:*\r\nDon't discount the \"safeAreaPadding\" feature. It's not a \"fake\" feature. It actually does fetch from the native APIs/classes needed to implement the design guidelines you are talking about. Note that Titanium's \"safeAreaPadding\" name mirrors Apple's \"safe-area\" name. This is not a coincidence. And it allows you to easily set up a safe-area container that Apple recommends in their own guidelines, with the added benefit is that this strategy is portable on Android as well.\r\nhttps://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets\r\nhttps://developer.android.com/reference/android/view/WindowInsets\r\nhttps://developer.apple.com/documentation/uikit/uiview/positioning_content_relative_to_the_safe_area\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-02-12T19:32:11.000+0000", "updated": "2020-02-12T19:33:02.000+0000" }, { "id": "454222", "author": { "name": "arood", "key": "arood", "displayName": "Marcus Olovsson", "active": true, "timeZone": "Europe/Berlin" }, "body": "Sorry but I disagree. I don't see why contentInset shouldn't be something you can set yourself. The documentation for it even says: \"By default, UIKit automatically adjusts the content inset to account for overlapping bars. You use this property to extend that distance even further, perhaps to *accommodate your own custom content*\". https://developer.apple.com/documentation/uikit/uiscrollview/1619406-contentinset\r\n\r\nThere are also cases where contentInsetAdjustmentBehavior isn't applied correctly, because the app is using custom content.\r\n\r\nThe RefreshControl is, from my understanding, also placing itself automatically based on the contentInset, since it's build to be used with scrolling views. It works as intended as long as contentInsetAdjustmentBehavior can be applied correctly (when for example building an app with a Ti.UI.NavigationWindow with a visible navbar). https://developer.apple.com/documentation/uikit/uirefreshcontrol\r\n\r\nRegarding your side note: I never said that safeAreaPadding itself is \"fake\", I'm very well aware that this is the safe distance reported by the system and I'm using it a lot. I was referring to putting empty views into a scrollview to emulate the effect that contentInset is supposed to do.", "updateAuthor": { "name": "arood", "key": "arood", "displayName": "Marcus Olovsson", "active": true, "timeZone": "Europe/Berlin" }, "created": "2020-02-12T19:54:28.000+0000", "updated": "2020-02-12T19:54:28.000+0000" } ], "maxResults": 6, "total": 6, "startAt": 0 } } }