So on iOS, UIScrollView
bounces by default so in Xamarin.Forms the ScrollView
natrually bounces. But what if you don’t want your ScrollView
to bounce? Android doesn’t bounce, so we won’t worry about it.
Let’s solve this problem with a custom renderer and control called NoBounceScrollView
. This could also be done with an Effect
but I like to have a custom control with the verbosity and flexibility with a renderer.
Let’s start by building a simple control in our Xamarin.Forms project:
NoBounceScrollView.cs
public class NoBounceScrollView : ScrollView { }
We don’t need anything in it since we are just going to assume it should never bounce and doesn’t affect the ScrollView
in any other way. If you want, you can add a bindable property here to set Bouncable
or something like that to true or false. Note: if you don’t want your ScrollView to bounce ever, then you don’t need this. Instead just have your renderer replace the default ScrollView
renderer.
So we have our Xamarin.Forms control to build the renderer for, so now let’s create the iOS renderer:
NoBounceScrollViewRenderer.cs
public class NoBounceScrollViewRenderer : ScrollViewRenderer { protected override void OnElementChanged(VisualElementChangedEventArgs e) { base.OnElementChanged(e); UpdateScrollView(); } private void UpdateScrollView() { ContentInset = new UIKit.UIEdgeInsets(0, 0, 0, 0); if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0)) ContentInsetAdjustmentBehavior = UIKit.UIScrollViewContentInsetAdjustmentBehavior.Never; Bounces = false; ScrollIndicatorInsets = new UIKit.UIEdgeInsets(0, 0, 0, 0); } }
What this is doing is setting the content insets to 0 so we don’t have empty space on top or bottom that the bouncing adds, and we also set Bounces
to false. Note that the ContentInsetAdjustmentBehavior
is only available on iOS 11 and higher, so for that extra step, we need to check the current iOS version.
Lastly, be sure to register your renderer:
[assembly: ExportRenderer(typeof(NoBounceScrollView), typeof(NoBounceScrollViewRenderer))]
or if you are replacing all ScrollViews
:
[assembly: ExportRenderer(typeof(ScrollView), typeof(NoBounceScrollViewRenderer))]
Now we have everything we need! So let’s use it in our page:
MainPage.xaml
<ContentPage ...> <components:NoBounceScrollView> <StackLayout> ... </StackLayout> </components:NoBounceScrollView> </ContentPage>
Check out the difference!
You can see this control in action with the EF Go Ahead Tours Companion App
If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!
Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.
i didn’t not see android solution
LikeLike
this isn’t needed for android. Android doesn’t bounce its ScrollViews
LikeLike
Thank you so much for your example. It helped a lot.
LikeLike
What you insert in the MainPage.xaml xml:”clr-namespace …..”??
LikeLike
nvm this question
LikeLike