Skip to content

Commit 5522d89

Browse files
jsuarezruizrmarinho
authored andcommitted
[iOS] Fix AdaptiveTrigger not working as expected (#20987)
* Added changes * Fixed broken test * Updated test
1 parent fa0488a commit 5522d89

File tree

4 files changed

+130
-3
lines changed

4 files changed

+130
-3
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4+
x:Class="Maui.Controls.Sample.Issues.Issue19197">
5+
<ContentPage.Resources>
6+
<ResourceDictionary>
7+
8+
<Style TargetType="Label">
9+
<Setter Property="VisualStateManager.VisualStateGroups">
10+
<VisualStateGroupList>
11+
<VisualStateGroup>
12+
<VisualState x:Name="Vertical">
13+
<VisualState.StateTriggers>
14+
<AdaptiveTrigger MinWindowWidth="0" />
15+
</VisualState.StateTriggers>
16+
<VisualState.Setters>
17+
<Setter Property="Text" Value="Vertical" />
18+
</VisualState.Setters>
19+
</VisualState>
20+
<VisualState x:Name="Horizontal">
21+
<VisualState.StateTriggers>
22+
<AdaptiveTrigger MinWindowWidth="800" />
23+
</VisualState.StateTriggers>
24+
<VisualState.Setters>
25+
<Setter Property="Text" Value="Horizontal" />
26+
</VisualState.Setters>
27+
</VisualState>
28+
</VisualStateGroup>
29+
</VisualStateGroupList>
30+
</Setter>
31+
</Style>
32+
</ResourceDictionary>
33+
</ContentPage.Resources>
34+
<Grid>
35+
<Label
36+
AutomationId="WaitForStubControl"
37+
HorizontalOptions="Center"
38+
VerticalOptions="Center" />
39+
</Grid>
40+
</ContentPage>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Microsoft.Maui.Controls;
2+
using Microsoft.Maui.Controls.Xaml;
3+
4+
namespace Maui.Controls.Sample.Issues
5+
{
6+
[XamlCompilation(XamlCompilationOptions.Compile)]
7+
[Issue(IssueTracker.Github, 19197, "AdaptiveTrigger does not work", PlatformAffected.iOS)]
8+
public partial class Issue19197 : ContentPage
9+
{
10+
public Issue19197()
11+
{
12+
InitializeComponent();
13+
}
14+
}
15+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_CATALYST && TEST_FAILS_ON_WINDOWS
2+
// Test failing on Android.
3+
// The test fails on Windows and MacCatalyst because the SetOrientation method, which is intended to change the device orientation, is only supported on mobile platforms Android and iOS.
4+
using NUnit.Framework;
5+
using UITest.Appium;
6+
using UITest.Core;
7+
8+
namespace Microsoft.Maui.TestCases.Tests.Issues
9+
{
10+
public class Issue19197 : _IssuesUITest
11+
{
12+
public Issue19197(TestDevice device) : base(device)
13+
{
14+
}
15+
16+
public override string Issue => "AdaptiveTrigger does not work";
17+
18+
[Test]
19+
[Category(UITestCategories.Page)]
20+
public void AdaptiveTriggerWorks()
21+
{
22+
App.WaitForElement("WaitForStubControl");
23+
App.SetOrientationLandscape();
24+
var text = App.FindElement("WaitForStubControl").GetText();
25+
Assert.That(text, Is.EqualTo("Horizontal"));
26+
App.SetOrientationPortrait();
27+
}
28+
}
29+
}
30+
#endif

src/Core/src/Handlers/Window/WindowHandler.iOS.cs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@ namespace Microsoft.Maui.Handlers
66
{
77
public partial class WindowHandler : ElementHandler<IWindow, UIWindow>
88
{
9-
readonly WindowProxy _proxy = new();
9+
readonly WindowProxy _windowProxy = new();
10+
readonly FrameObserverProxy _frameObserverProxy = new();
1011

1112
protected override void ConnectHandler(UIWindow platformView)
1213
{
1314
base.ConnectHandler(platformView);
1415

16+
_frameObserverProxy.Connect(VirtualView, platformView);
17+
1518
// For newer Mac Catalyst versions, we want to wait until we get effective window dimensions from the platform.
1619
if (OperatingSystem.IsMacCatalystVersionAtLeast(16))
1720
{
18-
_proxy.Connect(VirtualView, platformView);
21+
_windowProxy.Connect(VirtualView, platformView);
1922
}
2023
else
2124
{
@@ -27,7 +30,8 @@ protected override void DisconnectHandler(UIWindow platformView)
2730
{
2831
if (OperatingSystem.IsMacCatalystVersionAtLeast(16))
2932
{
30-
_proxy.Disconnect();
33+
_windowProxy.Disconnect();
34+
_frameObserverProxy.Disconnect(platformView);
3135
}
3236

3337
base.DisconnectHandler(platformView);
@@ -167,5 +171,43 @@ void HandleEffectiveGeometryObserved(NSObservedChange obj)
167171
}
168172
}
169173
}
174+
175+
class FrameObserverProxy
176+
{
177+
WeakReference<IWindow>? _virtualView;
178+
WeakReference<UIWindow>? _platformView;
179+
180+
IDisposable? _frameObserver;
181+
182+
IWindow? VirtualView => _virtualView is not null && _virtualView.TryGetTarget(out var v) ? v : null;
183+
184+
UIWindow? PlatformView => _platformView is not null && _platformView.TryGetTarget(out var v) ? v : null;
185+
186+
public void Connect(IWindow virtualView, UIWindow platformView)
187+
{
188+
_virtualView = new(virtualView);
189+
_platformView = new(platformView);
190+
191+
_frameObserver = platformView.AddObserver("frame", Foundation.NSKeyValueObservingOptions.New, FrameAction);
192+
}
193+
194+
public void Disconnect(UIWindow platformView)
195+
{
196+
_virtualView = null;
197+
_platformView = null;
198+
199+
_frameObserver?.Dispose();
200+
}
201+
202+
public void Update()
203+
{
204+
if (VirtualView is IWindow virtualView && PlatformView is UIWindow platformView)
205+
{
206+
virtualView.FrameChanged(platformView.Frame.ToRectangle());
207+
}
208+
}
209+
210+
void FrameAction(Foundation.NSObservedChange obj) => Update();
211+
}
170212
}
171213
}

0 commit comments

Comments
 (0)