diff --git a/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.iOS.cs index afdd79b764e2..8b441eb28761 100644 --- a/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/ScrollView/ScrollViewTests.iOS.cs @@ -7,7 +7,6 @@ using Microsoft.Maui.Graphics; using Microsoft.Maui.Handlers; using Microsoft.Maui.Hosting; -using UIKit; using Xunit; namespace Microsoft.Maui.DeviceTests @@ -36,52 +35,5 @@ await scrollViewHandler.PlatformView.AttachAndRun(() => }); }); } - - [Fact] - public async Task ContentSizeExpandsToViewport() - { - EnsureHandlerCreated(builder => { builder.ConfigureMauiHandlers(handlers => { handlers.AddHandler(); }); }); - - var scrollView = new ScrollView(); - - var entry = new Entry() { Text = "In a ScrollView", HeightRequest = 10 }; - - - static CoreGraphics.CGSize getViewportSize(UIScrollView scrollView) - { - return scrollView.AdjustedContentInset.InsetRect(scrollView.Bounds).Size; - }; - - var scrollViewHandler = await InvokeOnMainThreadAsync(() => - { - return CreateHandlerAsync(scrollView); - }); - - await InvokeOnMainThreadAsync(async () => - { - await scrollViewHandler.PlatformView.AttachAndRun(async () => - { - var uiScrollView = scrollViewHandler.PlatformView; - - uiScrollView.ContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.Always; - var parent = uiScrollView.Superview; - uiScrollView.Bounds = parent.Bounds; - uiScrollView.Center = parent.Center; - - scrollView.Content = entry; - - parent.SetNeedsLayout(); - parent.LayoutIfNeeded(); - - await Task.Yield(); - - var contentSize = uiScrollView.ContentSize; - var viewportSize = getViewportSize(uiScrollView); - - Assert.Equal(viewportSize.Height, contentSize.Height); - Assert.Equal(viewportSize.Width, contentSize.Width); - }); - }); - } } } diff --git a/src/Controls/tests/UITests/snapshots/ios/Issue16094Test.png b/src/Controls/tests/UITests/snapshots/ios/Issue16094Test.png index ec3ab47ffe9c..d0ef6eb54aab 100644 Binary files a/src/Controls/tests/UITests/snapshots/ios/Issue16094Test.png and b/src/Controls/tests/UITests/snapshots/ios/Issue16094Test.png differ diff --git a/src/Core/src/Handlers/ScrollView/ScrollViewHandler.iOS.cs b/src/Core/src/Handlers/ScrollView/ScrollViewHandler.iOS.cs index 60b6964c286a..b86d4882bf44 100644 --- a/src/Core/src/Handlers/ScrollView/ScrollViewHandler.iOS.cs +++ b/src/Core/src/Handlers/ScrollView/ScrollViewHandler.iOS.cs @@ -1,7 +1,13 @@ using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; using CoreGraphics; using Microsoft.Maui.Graphics; using Microsoft.Maui.Layouts; +using Microsoft.Maui.Platform; +using ObjCRuntime; using UIKit; using Size = Microsoft.Maui.Graphics.Size; @@ -97,11 +103,9 @@ public static void MapOrientation(IScrollViewHandler handler, IScrollView scroll // without having to re-layout the ScrollView var fullContentSize = scrollView.PresentedContent?.DesiredSize ?? Size.Zero; - - var viewportBounds = GetViewportBounds(uiScrollView); + var viewportBounds = uiScrollView.Bounds; var viewportWidth = viewportBounds.Width; var viewportHeight = viewportBounds.Height; - SetContentSizeForOrientation(uiScrollView, viewportWidth, viewportHeight, scrollView.Orientation, fullContentSize); } @@ -123,7 +127,7 @@ public static void MapRequestScrollTo(IScrollViewHandler handler, IScrollView sc var availableScrollWidth = uiScrollView.ContentSize.Width - uiScrollView.Frame.Width; var minScrollHorizontal = Math.Min(request.HorizontalOffset, availableScrollWidth); var minScrollVertical = Math.Min(request.VerticalOffset, availableScrollHeight); - uiScrollView.SetContentOffset(new CGPoint(minScrollHorizontal, minScrollVertical), !request.Instant); + uiScrollView.SetContentOffset(new CoreGraphics.CGPoint(minScrollHorizontal, minScrollVertical), !request.Instant); if (request.Instant) { @@ -181,15 +185,16 @@ static void InsertContentView(UIScrollView platformScrollView, IScrollView scrol return; } - var contentContainer = new ContentView + var contentContainer = new ContentView() { View = scrollView.PresentedContent, - Tag = ContentPanelTag, - // This is where we normally would inject the cross-platform ScrollView's layout logic; instead, we're injecting the - // methods from this handler so it can make some adjustments for things like Padding before the default logic is invoked - CrossPlatformLayout = crossPlatformLayout + Tag = ContentPanelTag }; + // This is where we normally would inject the cross-platform ScrollView's layout logic; instead, we're injecting the + // methods from this handler so it can make some adjustments for things like Padding before the default logic is invoked + contentContainer.CrossPlatformLayout = crossPlatformLayout; + platformScrollView.ClearSubviews(); contentContainer.AddSubview(platformContent); platformScrollView.AddSubview(contentContainer); @@ -284,11 +289,6 @@ static void SetContentSizeForOrientation(UIScrollView uiScrollView, double viewp uiScrollView.ContentSize = contentSize; } - static CGRect GetViewportBounds(UIScrollView platformScrollView) - { - return platformScrollView.AdjustedContentInset.InsetRect(platformScrollView.Bounds); - } - Size ICrossPlatformLayout.CrossPlatformMeasure(double widthConstraint, double heightConstraint) { var scrollView = VirtualView; @@ -301,18 +301,17 @@ Size ICrossPlatformLayout.CrossPlatformMeasure(double widthConstraint, double he return Size.Zero; } - var viewPortBounds = GetViewportBounds(platformScrollView); - + var scrollViewBounds = platformScrollView.Bounds; var padding = scrollView.Padding; if (widthConstraint == 0) { - widthConstraint = viewPortBounds.Width; + widthConstraint = scrollViewBounds.Width; } if (heightConstraint == 0) { - heightConstraint = viewPortBounds.Height; + heightConstraint = scrollViewBounds.Height; } // Account for the ScrollView Padding before measuring the content @@ -331,28 +330,29 @@ Size ICrossPlatformLayout.CrossPlatformArrange(Rect bounds) var crossPlatformLayout = scrollView as ICrossPlatformLayout; var platformScrollView = PlatformView; + var contentSize = crossPlatformLayout.CrossPlatformArrange(bounds); + // The UIScrollView's bounds are available, so we can use them to make sure the ContentSize makes sense // for the ScrollView orientation - var viewportBounds = GetViewportBounds(platformScrollView); - - var contentSize = crossPlatformLayout.CrossPlatformArrange(viewportBounds.ToRectangle()); - + var viewportBounds = platformScrollView.Bounds; var viewportHeight = viewportBounds.Height; var viewportWidth = viewportBounds.Width; SetContentSizeForOrientation(platformScrollView, viewportWidth, viewportHeight, scrollView.Orientation, contentSize); var container = GetContentView(platformScrollView); - if (container != null) + if (container?.Superview is UIScrollView uiScrollView) { // Ensure the container is at least the size of the UIScrollView itself, so that the // cross-platform layout logic makes sense and the contents don't arrange outside the // container. (Everything will look correct if they do, but hit testing won't work properly.) + + var scrollViewBounds = uiScrollView.Bounds; var containerBounds = contentSize; container.Bounds = new CGRect(0, 0, - Math.Max(containerBounds.Width, viewportBounds.Width), - Math.Max(containerBounds.Height, viewportBounds.Height)); + Math.Max(containerBounds.Width, scrollViewBounds.Width), + Math.Max(containerBounds.Height, scrollViewBounds.Height)); container.Center = new CGPoint(container.Bounds.GetMidX(), container.Bounds.GetMidY()); }