Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VerticalStackLayout inside Scrollview: Button at the bottom not clickable on IOS #14257

Closed
Tracked by #8895
FM1973 opened this issue Mar 29, 2023 · 37 comments · Fixed by #16385
Closed
Tracked by #8895

VerticalStackLayout inside Scrollview: Button at the bottom not clickable on IOS #14257

FM1973 opened this issue Mar 29, 2023 · 37 comments · Fixed by #16385
Assignees
Labels
area-controls-scrollview ScrollView fixed-in-7.0.96 Look for this fix in 7.0.96 SR8! fixed-in-7.0.100 fixed-in-7.0.101 fixed-in-8.0.0-preview.3.8149 Look for this fix in 8.0.0-preview.3.8149! fixed-in-8.0.0-rc.1.9171 Look for this fix in 8.0.0-rc.1.9171 layout-stack p/1 Work that is important, and has been scheduled for release in this or an upcoming sprint platform/iOS 🍎 t/bug Something isn't working
Milestone

Comments

@FM1973
Copy link

FM1973 commented Mar 29, 2023

Description

When you put a VerticalStackLayout inside a ScrollView and load some data dynamically (i.e. some Text using an async function) and then put a button on the end of the VerticalStackLayout, the Button-Handler never gets called.
This works on Android without any problem.
For me related to: #8820

Steps to Reproduce

  1. Clone the repo
  2. Run the app on IOS
  3. Click on the "Button at bottom" Button
  4. Scroll to the bottom of the page and try to click the button

Link to public reproduction project repository

https://github.com/FM1973/RefreshGridRepo.git

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

iOS

Affected platform versions

iOS 14.x +

Did you find any workaround?

Yes, there is a workaround. It´s the same as before having the general ScrollView-problem stated in #8820
Look there: #8820 (comment)

Relevant log output

-
@FM1973 FM1973 added the t/bug Something isn't working label Mar 29, 2023
@jsuarezruiz jsuarezruiz added area-layout StackLayout, GridLayout, ContentView, AbsoluteLayout, FlexLayout, ContentPresenter layout-stack area-controls-scrollview ScrollView labels Mar 29, 2023
@PureWeen PureWeen added this to the Backlog milestone Mar 29, 2023
@ghost
Copy link

ghost commented Mar 29, 2023

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

@PureWeen
Copy link
Member

@hartez FYI

@softlion
Copy link
Contributor

softlion commented Mar 30, 2023

Thank you !!

the workaround which consits in calling InvalidateMeasure on the ScrollView after you make visible new items does work !

I lost 4 days on trying to find a repro on that, since a full week !

The bug should be prioritized !

@fgiacomelli
Copy link

Thank you for sharing, it fixes the bug also for me

@MichaelNovikov
Copy link

Workaround with an InvalidateMeasure doesn't work anymore

@dk-mushiyoke
Copy link

can confirm that this issue also exists in our app - we have pages with scroll views going beyond the device screen size, when scrolled to the bottom on iOS none of the elements that were originally cut off can be interacted with. Also tried the InvalidateMeasure() workaround as well and it did not fix the issue.

@nicjay
Copy link

nicjay commented May 3, 2023

The InvalidateMeasure workaround does still work for me as of 7.0.81 for this particular issue.

To be clear, I use code similar to the following in my code-behind:

MyVerticalStackLayout.SizeChanged += (object sender, EventArgs e) =>
{
    (MyScrollView as IView).InvalidateMeasure();
}

XAML

<ScrollView x:Name="MyScrollView">
    <VerticalStackLayout x:Name="MyVerticalStackLayout">
    ...
    </VerticalStackLayout>
</ScrollView>

However, it would be ideal if this were not necessary.

@etienneCGI
Copy link

The InvalidateMeasure workaround does still work for me as of 7.0.81 for this particular issue.

To be clear, I use code similar to the following in my code-behind:

MyVerticalStackLayout.SizeChanged += (object sender, EventArgs e) =>
{
    (MyScrollView as IView).InvalidateMeasure();
}

XAML

<ScrollView x:Name="MyScrollView">
    <VerticalStackLayout x:Name="MyVerticalStackLayout">
    ...
    </VerticalStackLayout>
</ScrollView>

However, it would be ideal if this were not necessary.

Thanks you very much it's work for me

@dk-mushiyoke
Copy link

after reading @nicjay's comment I tried the workaround again in a new maui project and that worked out fine, so maybe it lies somewhere in the complexity of our view hierarchy (bunch of grids and layouts inside a CarouselView inside a ScrollView). Thanks for the info

@fgiacomelli
Copy link

In a more complex solution the workaround suggested didn't work for me: I have a scrollview, that has a verticalstacklayout with a bindablelayout inside. The datatemplate of the bindable use an expander (but I already tried using a button or a tapGestureRecognizer): the problem is that all the elements that was not present when the page appears does not receive the tap event. Calling InvalidateMeausure over the scrollview when PropertyChanged event of the verticalstacklayout is raised does not work

@fgiacomelli
Copy link

In the meantime I discovered what is the problem in my situation: I have a refreshview around the scrollview, and this seems to be the problem that prevent buttons/tapgestures to receive tap/click events if they are not visible when the page appears. Removing it solves the problem, and gave me the possibility to manually implement the pool to refresh behavior using the scrolled event of the scrollview...

@psdiviso
Copy link

psdiviso commented May 8, 2023

@fgiacomelli I have the exact same problem. Scrollview --> verticalstacklayout --> with a bindablelayout inside. Where because the bindablelayout layout is hidden onAppearing half tabs in the list doesn't work. How did you: "manually implement the pool to refresh behavior"

??

@iammh93
Copy link

iammh93 commented May 19, 2023

The InvalidateMeasure workaround does still work for me as of 7.0.81 for this particular issue.

To be clear, I use code similar to the following in my code-behind:

MyVerticalStackLayout.SizeChanged += (object sender, EventArgs e) =>
{
    (MyScrollView as IView).InvalidateMeasure();
}

XAML

<ScrollView x:Name="MyScrollView">
    <VerticalStackLayout x:Name="MyVerticalStackLayout">
    ...
    </VerticalStackLayout>
</ScrollView>

However, it would be ideal if this were not necessary.

If this solution does not worked, just add transparent box with fixed height at the bottom of your layout, stupid way but it worked

<BoxView BackgroundColor="Transparent" HeightRequest="200" />

@hartez
Copy link
Contributor

hartez commented May 19, 2023

This is fixed by #14176.

@tibuprophen
Copy link

Workaround does not work for me on iOS using workloads 7.0.92

@jadenrogers
Copy link
Contributor

jadenrogers commented Jul 21, 2023

@tibuprophen Do you have an example to check? Just some sample XAML is enough

@tibuprophen
Copy link

Of course:

<?xml version="1.0" encoding="utf-8"?>

<ContentPage
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="RefreshScrollButton.MainPage">
    <RefreshView>
        <ScrollView>
            <StackLayout>
                <!-- adding an element with a big height to force the scroll -->
                <BoxView BackgroundColor="Black" HeightRequest="1000" WidthRequest="40" HorizontalOptions="Center" />
                <!-- button is not clickable in the non-visible area / does not execute command or Clicked event -->
                <Button Text="Click me" />
            </StackLayout>
        </ScrollView>
    </RefreshView>
</ContentPage>

@jadenrogers
Copy link
Contributor

@tibuprophen Maybe the code behind as well, are you programmatically hiding showing content? That looks like that should work off the bat. Can you remove the RefreshView, Does that make a difference?

@tibuprophen
Copy link

tibuprophen commented Jul 21, 2023

There is no additional code behind. Default ContentPage with InitializeComponents - nothing more.
It works when I remove the RefreshView. The issue occurs "only" in the combination with RefreshView + ScrollView.

@jadenrogers
Copy link
Contributor

jadenrogers commented Jul 22, 2023

@tibuprophen Oh yes I see, also mentioned further above too. Challenge accepted.

Its seems no matter what the content size is never calculated correctly, invalidating doesn't adjust the height.

Confirmed it is fixed by #15460

New work around that fixes all the scrolling / button issues

Add this into your MauiProgram.cs

#if IOS

        Microsoft.Maui.Handlers.ScrollViewHandler.Mapper.AppendToMapping(nameof(IScrollView.ContentSize), (h, v) =>
			{
				var contentSize = h.VirtualView.ContentSize;

                if (contentSize.IsZero)
					return;

				UIKit.UIScrollView uiScrollView = h.PlatformView;
				var container = uiScrollView.Subviews.FirstOrDefault(x => x.Tag == 0x845fed);			

				if (container != null && container.Bounds.Height != contentSize.Height)
				{
					container.Bounds = new CoreGraphics.CGRect(
						container.Bounds.X,
						container.Bounds.Y, 
						contentSize.Width, 
						contentSize.Height);

					(h.VirtualView as IView).InvalidateMeasure();
				}
			});
#endif

@tibuprophen
Copy link

Thank you @jadenrogers, this is working!

rmarinho pushed a commit that referenced this issue Jul 27, 2023
…16385)

* Resize internal content container when ScrollView content is resized
Fixes #14257

* Fix constructor
@github-project-automation github-project-automation bot moved this from Todo to Done in MAUI SDK Ongoing Jul 27, 2023
@MageInt
Copy link

MageInt commented Aug 2, 2023

The work arround did work for me using workloads 7.0.92 :)

@PureWeen
Copy link
Member

PureWeen commented Aug 9, 2023

Can y'all validate this fix on .NET8 preview7 if you have a chance?

@jadenrogers
Copy link
Contributor

fixes #15374
fixes #14624
fixes #15288
fixes #15283
fixes #14795

@xtuzy
Copy link

xtuzy commented Aug 22, 2023

This be fixed on .NET8 preview7?
I run my demo on .NET8 preview7, when dynamically add Editor, Editor still not clickable.

sharex-20230822152912.mp4

I use jadenrogers' code to fix, it work.

sharex-20230822152641.mp4

@hartez
Copy link
Contributor

hartez commented Aug 22, 2023

This be fixed on .NET8 preview7? I run my demo on .NET8 preview7, when dynamically add Editor, Editor still not clickable.

No, this fix is not in preview 7. It should be in the next .NET 8 release.

@samhouts samhouts added the fixed-in-8.0.0-rc.1.9171 Look for this fix in 8.0.0-rc.1.9171 label Sep 12, 2023
@samhouts samhouts added the fixed-in-7.0.96 Look for this fix in 7.0.96 SR8! label Oct 10, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Nov 9, 2023
@Eilon Eilon removed the area-layout StackLayout, GridLayout, ContentView, AbsoluteLayout, FlexLayout, ContentPresenter label May 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-controls-scrollview ScrollView fixed-in-7.0.96 Look for this fix in 7.0.96 SR8! fixed-in-7.0.100 fixed-in-7.0.101 fixed-in-8.0.0-preview.3.8149 Look for this fix in 8.0.0-preview.3.8149! fixed-in-8.0.0-rc.1.9171 Look for this fix in 8.0.0-rc.1.9171 layout-stack p/1 Work that is important, and has been scheduled for release in this or an upcoming sprint platform/iOS 🍎 t/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.