Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-27760] ScrollView: add contentInset support

GitHub Issuen/a
TypeImprovement
PriorityMedium
StatusOpen
ResolutionUnresolved
Affected Version/sn/a
Fix Version/sn/a
ComponentsAndroid, iOS
Labelsscrollview
ReporterRene Pot
AssigneeAbir Mukherjee
Created2020-02-11T14:52:24.000+0000
Updated2020-02-12T19:54:28.000+0000

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. iOS documentation: https://developer.apple.com/documentation/uikit/uiscrollview/1619406-contentinset

Attachments

FileDateSize
Example-Android.png2020-02-11T20:00:04.000+000063049
Example-iOS.png2020-02-11T20:00:09.000+000087029
ScrollViewInsetTest.js2020-02-11T19:56:11.000+0000874

Comments

  1. Joshua Quick 2020-02-11

    [~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...
       var containerView = Ti.UI.createView({
       	layout: "vertical",
       	left: "5dp",
       	right: "5dp", 
       	top: "5dp",
       	bottom: "5dp",
       	width: Ti.UI.FILL,
       	height: Ti.UI.SIZE,
       });
       
    You 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. [^ScrollViewInsetTest.js] !Example-Android.png|thumbnail! !Example-iOS.png|thumbnail!
  2. Marcus Olovsson 2020-02-11

    @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.
  3. Joshua Quick 2020-02-12

  4. Marcus Olovsson 2020-02-12

    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. I 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.
  5. Joshua Quick 2020-02-12

    Okay. I see the disconnect here. You 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. *Side Note:* Don'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. https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets https://developer.android.com/reference/android/view/WindowInsets https://developer.apple.com/documentation/uikit/uiview/positioning_content_relative_to_the_safe_area
  6. Marcus Olovsson 2020-02-12

    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 There are also cases where contentInsetAdjustmentBehavior isn't applied correctly, because the app is using custom content. The 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 Regarding 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.

JSON Source