File: ContentPage\HideSoftInputOnTappedChanged\HideSoftInputOnTappedChangedManager.Platform.cs
Web Access
Project: src\src\Controls\src\Core\Controls.Core.csproj (Microsoft.Maui.Controls)
// This behavior isn't lit up for WinUI because it's never been supported on WinUI, event in Xamarin.Forms
// The primary purpose of this API is for XF migration purposes. 
// Ideally users would use behavior that's more accessible forward and consistent with platform expectations.
#if ANDROID || IOS
using System;
using System.Collections.Generic;
 
namespace Microsoft.Maui.Controls
{
	partial class HideSoftInputOnTappedChangedManager
	{
		IDisposable? _watchingForTaps;
		WeakReference<IView>? _focusedView;
 
		internal void UpdatePage(ContentPage page)
		{
			if (page.HideSoftInputOnTapped && page.HasNavigatedTo)
			{
				if (!_contentPages.Contains(page))
				{
					_contentPages.Add(page);
					page.NavigatedFrom += OnPageNavigatedFrom;
					SetupHideSoftInputOnTapped();
				}
			}
			else
			{
				RemovePage(page);
			}
 
			void RemovePage(ContentPage pageToRemove)
			{
				page.NavigatedFrom -= OnPageNavigatedFrom;
				if (_contentPages.Contains(pageToRemove))
					_contentPages.Remove(pageToRemove);
 
				SetupHideSoftInputOnTapped();
			}
 
			void OnPageNavigatedFrom(object? sender, NavigatedFromEventArgs e)
			{
				if (sender is ContentPage pageNavigatedFrom)
				{
					RemovePage(pageNavigatedFrom);
				}
			}
		}
 
		internal IDisposable? UpdateFocusForView(IView _view)
		{
			// Update to new focused view
			if (_view.IsFocused)
			{
				DisconnectFromPlatform();
				_focusedView = new WeakReference<IView>(_view);
			}
			// If currently tracked view became unfocused then disconnect from it
			else if (_view == FocusedView)
			{
				DisconnectFromPlatform();
				_focusedView = null;
			}
 
			if (!FeatureEnabled)
			{
				DisconnectFromPlatform();
				return null;
			}
 
			if (_view is not VisualElement ve)
				return null;
 
			if (!_view.IsFocused)
				return null;
 
			DisconnectFromPlatform();
 
			// This view has been set as focused but it's not currently loaded
			var platformView = (_view.Handler as IPlatformViewHandler)?.PlatformView;
			if (platformView is null)
			{
				return null;
			}
 
			if (ve.Window is null)
			{
				// This means the xplat IsFocused value has lagged behind navigation events.
				// This might happen if navigated has fired on the incoming page but the
				// "LostFocus" event hasn't propagated from the previous one
				return null;
			}
 
			IDisposable? platformToken = SetupHideSoftInputOnTapped(platformView);
 
#if ANDROID
			var window = ve.Window;
			window.DispatchTouchEvent += OnWindowDispatchedTouch;
#endif
			_watchingForTaps = new ActionDisposable(() =>
			{
				platformToken?.Dispose();
				platformToken = null;
#if ANDROID
				window.DispatchTouchEvent -= OnWindowDispatchedTouch;
				window = null;
#endif
			});
 
			return _watchingForTaps;
		}
 
		void DisconnectFromPlatform()
		{
			_watchingForTaps?.Dispose();
			_watchingForTaps = null;
		}
 
		IView? FocusedView
		{
			get
			{
				if (_focusedView?.TryGetTarget(out IView? view) == true)
				{
					return view;
				}
 
				return null;
			}
		}
		internal void SetupHideSoftInputOnTapped()
		{
			if (FocusedView is not null)
			{
				UpdateFocusForView(FocusedView);
			}
		}
	}
}
#endif