Skip to content

[net11.0][iOS/macOS] Fix CollectionView, RefreshView, and ScrollView interaction state after IsEnabled toggles - #36784

Closed
kubaflo wants to merge 5 commits into
net11.0from
kubaflo/net11-ios-inputtransparent-isenabled
Closed

[net11.0][iOS/macOS] Fix CollectionView, RefreshView, and ScrollView interaction state after IsEnabled toggles#36784
kubaflo wants to merge 5 commits into
net11.0from
kubaflo/net11-ios-inputtransparent-isenabled

Conversation

@kubaflo

@kubaflo kubaflo commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description of Change

Forward-ports #36305 and its follow-up regression fix from #36628 to net11.0.

Issues Fixed

Addresses #36059 and #36501 for .NET 11.

Validation

  • dotnet build Microsoft.Maui.BuildTasks.slnf --no-restore --nologo -v:minimal
  • dotnet build src/Controls/tests/TestCases.iOS.Tests/Controls.TestCases.iOS.Tests.csproj --no-restore --nologo -v:minimal
  • dotnet build src/Core/tests/DeviceTests/Core.DeviceTests.csproj -p:TargetFramework=net11.0-ios -p:RuntimeIdentifier=iossimulator-arm64 --no-restore --nologo -v:minimal

Copilot AI review requested due to automatic review settings July 25, 2026 09:44
@kubaflo
kubaflo temporarily deployed to copilot-pat-pool July 25, 2026 09:44 — with GitHub Actions Inactive
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 36784

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 36784"

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

@kubaflo

kubaflo commented Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).

@kubaflo
kubaflo temporarily deployed to copilot-pat-pool July 25, 2026 09:46 — with GitHub Actions Inactive
@kubaflo
kubaflo temporarily deployed to copilot-pat-pool July 25, 2026 09:47 — with GitHub Actions Inactive
@github-actions github-actions Bot added area-controls-general General issues that span multiple controls, or common base classes such as View or Element platform/ios platform/macos macOS / Mac Catalyst labels Jul 25, 2026
@kubaflo
kubaflo temporarily deployed to copilot-pat-pool July 25, 2026 09:47 — with GitHub Actions Inactive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR forward-ports the iOS/Mac Catalyst interaction fix to net11.0, ensuring InputTransparent is respected when IsEnabled changes (including for wrapper/container hit-testing). This prevents input-transparent layouts from becoming touch-blocking after a parent IsEnabled toggle.

Changes:

  • Update iOS UpdateIsEnabled for non-UIControl views to respect InputTransparent when setting UserInteractionEnabled.
  • Update iOS UpdateInputTransparent to keep non-UIControl interaction consistent with both IsEnabled and InputTransparent.
  • Add iOS device tests covering IsEnabled/InputTransparent combinations and container (WrapperView) hit-testing synchronization.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/Core/tests/DeviceTests/Handlers/View/ViewHandlerTests.iOS.cs Adds iOS device tests validating interaction behavior for non-UIControl views and WrapperView containers across IsEnabled toggles.
src/Core/src/Platform/iOS/ViewExtensions.cs Ensures UserInteractionEnabled updates for non-UIControl views account for both IsEnabled and InputTransparent.
src/Core/src/Handlers/View/ViewHandler.cs Keeps WrapperView container hit-testing synchronized when IsEnabled changes or a container is created (iOS/Mac Catalyst).

@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Jul 25, 2026
MauiBot

This comment was marked as outdated.

kubaflo added a commit that referenced this pull request Jul 26, 2026
#36784 review)

ViewHandler.MapIsEnabled synchronizes the WrapperView container's hit-testing via
MapInputTransparentToContainer, but ScrollView/SearchBar/Editor/RefreshView replace
the IsEnabled mapper on iOS and only updated the inner platform view. So an iOS
ScrollView/Editor/SearchBar/RefreshView that gets a WrapperView container (Clip,
Shadow, or Border) kept the container hit-testable after IsEnabled=false, preserving
the reachability bug for those controls (MauiBot NEEDS_CHANGES finding).

Expose MapInputTransparentToContainer as internal and call it from each override's
iOS MapIsEnabled so the container tracks IsEnabled/InputTransparent uniformly. Add a
ScrollView device test asserting the container's UserInteractionEnabled follows
IsEnabled through the override mapper. Also fix the stale non-UIControl comment in
ViewExtensions (it now combines IsEnabled && !InputTransparent) and the missing
trailing newline in ViewHandlerTests.iOS.cs.

Note: local net11.0-ios build not feasible in this environment (CoreCLR/workload
restore chain); relying on CI for the iOS build + device-test validation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d00747b7-96f3-4e7a-8dfb-e3a48db04b2d
Copilot AI review requested due to automatic review settings July 26, 2026 00:28
@kubaflo

kubaflo commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the review findings in 52b796cbe8e:

  • ❌ Container hit-testing stale for override handlers — the base ViewHandler.MapIsEnabled synced the WrapperView container, but ScrollView/SearchBar/Editor/RefreshView replace the iOS IsEnabled mapper and only updated the inner platform view. Exposed MapInputTransparentToContainer as internal and call it from each override's iOS MapIsEnabled, so the container's UserInteractionEnabled now tracks IsEnabled && !InputTransparent uniformly. Added a ScrollView device test (container reachable-when-disabled regression) following the existing ContainerUserInteractionTracksIsEnabledAndInputTransparent pattern.
  • ⚠️ Stale comment — updated the non-UIControl comment in ViewExtensions.cs to reflect IsEnabled && !InputTransparent.
  • 💡 Trailing newline — added to ViewHandlerTests.iOS.cs.

Note: I couldn't build net11.0-ios locally (CoreCLR/workload restore chain in this environment), so I'm relying on CI for the iOS build + device-test run. Ready for re-review — thanks!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment thread src/Core/src/Platform/iOS/ViewExtensions.cs
@kubaflo kubaflo changed the title [net11.0][iOS] Respect InputTransparent when updating UserInteractionEnabled [net11.0][iOS/macOS] Fix CollectionView, RefreshView, and ScrollView interaction state after IsEnabled toggles Jul 30, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (4)

src/Core/src/Platform/iOS/ViewExtensions.cs:641

  • UpdateInputTransparent(UIView, handler, view) still has an early-return for non-editor ITextInput which sets UserInteractionEnabled based only on IsReadOnly/InputTransparent and ignores view.IsEnabled. This can re-enable hit testing for disabled non-UIControl text inputs (and their WrapperView containers) when InputTransparent or container mapping runs.
			if (view is not IEditor && view is ITextInput textInput)
			{
				platformView.UpdateInputTransparent(textInput.IsReadOnly, view.InputTransparent);
				return;
			}

			platformView.UpdateInteractionState(view);
		}

src/Controls/src/Core/Handlers/Items/ItemsViewHandler.cs:35

  • The ItemsViewHandler mapper override for IsEnabled is guarded by #if IOS, but ItemsViewHandler.iOS.cs is compiled for both iOS and MacCatalyst. As written, MacCatalyst builds won’t call MapIsEnabled, so selection mode and UserInteractionEnabled sync won’t be updated there.
			[Controls.ItemsView.ItemsUpdatingScrollModeProperty.PropertyName] = MapItemsUpdatingScrollMode,
#if IOS
			[nameof(IView.IsEnabled)] = MapIsEnabled,
#endif
		};

src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34666.cs:24

  • After scrolling, the test waits for the same element ("Baboon") that was already present before scrolling, so it no longer validates that the CollectionView actually scrolled. It should wait for an item that becomes visible only after scrolling (e.g., "Gelada").
	public void CollectionViewScrollsWhenRefreshViewDisabled()
	{
		App.WaitForElement("Baboon");
		App.ScrollDown("CollectionView");
		App.ScrollDown("CollectionView");
		App.WaitForElement("Baboon");
	}

src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34666.cs:1

  • The file-level quarantine symbol was changed to TEST_FAILS_ON_ANDROID, but the issue description (and HostApp issue metadata) indicates the scenario affects Windows as well. Consider using a combined guard so the intent stays accurate.
#if TEST_FAILS_ON_ANDROID

@kubaflo

kubaflo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

/azp run maui-pr

@kubaflo

kubaflo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

/azp run maui-pr-devicetests

@kubaflo

kubaflo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

/azp run maui-pr-uitests

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

2 similar comments
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@kubaflo

kubaflo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

/azp run maui-pr

@kubaflo

kubaflo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

/azp run maui-pr-devicetests

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@kubaflo

kubaflo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

/azp run maui-pr-uitests

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

1 similar comment
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

jfversluis and others added 5 commits July 30, 2026 18:33
Respect InputTransparent when updating UserInteractionEnabled for non-UIControl iOS views so parent IsEnabled toggles do not make transparent layouts block touches. Keep disabled non-UIControl views from receiving interactions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
(cherry picked from commit 1bf06fd)
Synchronize container hit testing when IsEnabled changes or a container is created. Move iOS interaction coverage from shared unit tests into Core device tests so the iOS target compiles it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
(cherry picked from commit 0eba45a)
#36784 review)

ViewHandler.MapIsEnabled synchronizes the WrapperView container's hit-testing via
MapInputTransparentToContainer, but ScrollView/SearchBar/Editor/RefreshView replace
the IsEnabled mapper on iOS and only updated the inner platform view. So an iOS
ScrollView/Editor/SearchBar/RefreshView that gets a WrapperView container (Clip,
Shadow, or Border) kept the container hit-testable after IsEnabled=false, preserving
the reachability bug for those controls (MauiBot NEEDS_CHANGES finding).

Expose MapInputTransparentToContainer as internal and call it from each override's
iOS MapIsEnabled so the container tracks IsEnabled/InputTransparent uniformly. Add a
ScrollView device test asserting the container's UserInteractionEnabled follows
IsEnabled through the override mapper. Also fix the stale non-UIControl comment in
ViewExtensions (it now combines IsEnabled && !InputTransparent) and the missing
trailing newline in ViewHandlerTests.iOS.cs.

Note: local net11.0-ios build not feasible in this environment (CoreCLR/workload
restore chain); relying on CI for the iOS build + device-test validation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d00747b7-96f3-4e7a-8dfb-e3a48db04b2d
…view)

UpdateInputTransparent(UIView, handler, view) now factors IsEnabled for non-UIControl
views, but its non-editor ITextInput early-return delegated to the (isReadOnly,
inputTransparent) overload, which computes !(isReadOnly || inputTransparent) and
ignores IsEnabled. When the container-sync path runs for a disabled non-UIControl
text input (e.g. ISearchBar), its WrapperView container became hit-testable again,
defeating the synchronization the previous commit added (Copilot follow-up finding).

Compute the text-input case as IsEnabled && !(IsReadOnly || InputTransparent) so a
disabled or input-transparent SearchBar/Entry (and its container) loses hit-testing,
while enabled and read-only behavior is unchanged (editors remain excluded from this
branch so read-only scrolling is preserved). Add a device test asserting a disabled
SearchBar's WrapperView container is not interactive.

Note: local net11.0-ios build not feasible here; relying on CI device tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d00747b7-96f3-4e7a-8dfb-e3a48db04b2d
Replace the PR-specific container workaround with the merged #36628 implementation. Route ScrollView, RefreshView, and both ItemsView handlers through ViewHandler.MapIsEnabled and share interaction-state calculation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 60fb173f-7de4-4b51-822d-b306a63c2bfc
@kubaflo
kubaflo force-pushed the kubaflo/net11-ios-inputtransparent-isenabled branch from ab92978 to e3ef63a Compare July 30, 2026 16:39
Copilot AI review requested due to automatic review settings July 30, 2026 16:39
@kubaflo

kubaflo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

/azp run maui-pr-devicetests

@kubaflo

kubaflo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

/azp run maui-pr-uitests

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

1 similar comment
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

src/Core/src/Platform/iOS/ViewExtensions.cs:638

  • In UpdateInputTransparent(UIView, handler, view), the non-editor ITextInput early-return sets UserInteractionEnabled via the (isReadOnly, inputTransparent) overload, which ignores view.IsEnabled. This can re-enable hit testing for disabled text inputs (and WrapperView containers) when InputTransparent/container mapping runs, leaving IsEnabled and interaction state out of sync.
			if (view is not IEditor && view is ITextInput textInput)
			{
				platformView.UpdateInputTransparent(textInput.IsReadOnly, view.InputTransparent);
				return;
			}

src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34666.cs:23

  • After scrolling, the test waits for "Baboon" again, which is already present before scrolling and doesn't validate that scrolling succeeded. This makes the test non-assertive and could hide regressions in CollectionView scrolling when RefreshView is disabled.
		App.WaitForElement("Baboon");

@kubaflo

kubaflo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Fixed in SR10 so this pr is not needed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-general General issues that span multiple controls, or common base classes such as View or Element platform/ios platform/macos macOS / Mac Catalyst s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-failed AI could not verify tests catch the bug s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants