Skip to content

Commit e991243

Browse files
Updated the bottom sheet's backdrop overlay visibility
1 parent 9255830 commit e991243

File tree

2 files changed

+121
-65
lines changed

2 files changed

+121
-65
lines changed

maui/src/BottomSheet/SfBottomSheet.cs

Lines changed: 114 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Microsoft.Maui.Controls.Shapes;
1+
using Microsoft.Maui.Controls.Shapes;
22
using Syncfusion.Maui.Toolkit.Internals;
33
using Syncfusion.Maui.Toolkit.Themes;
44
using Syncfusion.Maui.Toolkit.Helper;
@@ -74,11 +74,16 @@ public partial class SfBottomSheet : SfView, IParentThemeElement
7474
/// </summary>
7575
bool _isPointerPressed;
7676

77-
// Touch tracking
78-
/// <summary>
79-
/// The initial Y-coordinate of a touch event on the bottom sheet.
80-
/// </summary>
81-
double _initialTouchY;
77+
/// <summary>
78+
/// Indicates whether the overlay grid is currently added to the view hierarchy.
79+
/// </summary>
80+
bool _isOverlayAdded;
81+
82+
// Touch tracking
83+
/// <summary>
84+
/// The initial Y-coordinate of a touch event on the bottom sheet.
85+
/// </summary>
86+
double _initialTouchY;
8287

8388
/// <summary>
8489
/// The starting Y-coordinate of a swipe gesture on the bottom sheet.
@@ -1242,7 +1247,7 @@ internal Color OverlayBackgroundColor
12421247
/// </exception>
12431248
public void Show()
12441249
{
1245-
if (_bottomSheet is null || _overlayGrid is null)
1250+
if (_bottomSheet is null)
12461251
{
12471252
return;
12481253
}
@@ -1267,15 +1272,15 @@ public void Show()
12671272
/// </exception>
12681273
public void Close()
12691274
{
1270-
if(_bottomSheet is null || _overlayGrid is null)
1275+
if(_bottomSheet is null)
12711276
{
12721277
return;
12731278
}
12741279

12751280
AnimateBottomSheet(Height, onFinish: () =>
12761281
{
12771282
_bottomSheet.IsVisible = false;
1278-
_overlayGrid.IsVisible = false;
1283+
RemoveOverlayFromView();
12791284
});
12801285

12811286
if (_isSheetOpen)
@@ -1356,9 +1361,8 @@ void InitializeLayout()
13561361
InitializeBottomSheetBorder();
13571362
InitializeContentBorder();
13581363

1359-
if (_bottomSheet is not null && _overlayGrid is not null)
1364+
if (_bottomSheet is not null)
13601365
{
1361-
Children.Add(_overlayGrid);
13621366
Children.Add(_bottomSheet);
13631367
_bottomSheet.IsVisible = false;
13641368
}
@@ -1370,6 +1374,7 @@ void InitializeLayout()
13701374
void UpdateContentView()
13711375
{
13721376
Children.Clear();
1377+
_isOverlayAdded = false; // Reset overlay state
13731378
UpdateAllChild();
13741379
}
13751380

@@ -1379,7 +1384,6 @@ void UpdateContentView()
13791384
void UpdateAllChild()
13801385
{
13811386
AddChild(Content);
1382-
AddChild(_overlayGrid);
13831387
AddChild(_bottomSheet);
13841388
}
13851389

@@ -1404,7 +1408,7 @@ void InitializeOverlayGrid()
14041408
{
14051409
BackgroundColor = OverlayBackgroundColor,
14061410
Opacity = DefaultOverlayOpacity,
1407-
IsVisible = false
1411+
IsVisible = true
14081412
};
14091413

14101414
var tapGestureRecognizer = new TapGestureRecognizer();
@@ -1485,6 +1489,36 @@ void InitializeBottomSheetBorder()
14851489
};
14861490
}
14871491

1492+
/// <summary>
1493+
/// Adds the overlay grid to the view hierarchy if it's not already added and modal is enabled.
1494+
/// </summary>
1495+
void AddOverlayToView()
1496+
{
1497+
if (_overlayGrid is not null && IsModal && !_isOverlayAdded)
1498+
{
1499+
if (!Children.Contains(_overlayGrid))
1500+
{
1501+
Children.Insert(Children.Count - 1, _overlayGrid); // Insert before bottom sheet
1502+
}
1503+
_isOverlayAdded = true;
1504+
}
1505+
}
1506+
1507+
/// <summary>
1508+
/// Removes the overlay grid from the view hierarchy.
1509+
/// </summary>
1510+
void RemoveOverlayFromView()
1511+
{
1512+
if (_overlayGrid is not null && _isOverlayAdded)
1513+
{
1514+
if (Children.Contains(_overlayGrid))
1515+
{
1516+
Children.Remove(_overlayGrid);
1517+
}
1518+
_isOverlayAdded = false;
1519+
}
1520+
}
1521+
14881522
/// <summary>
14891523
/// Calculates the initial height for the half-expanded state.
14901524
/// </summary>
@@ -2040,16 +2074,20 @@ void RegisterSizeChangedEvent()
20402074
/// </summary>
20412075
void SetupBottomSheetForShow()
20422076
{
2043-
if (_isSheetOpen || _bottomSheet is null || _overlayGrid is null)
2077+
if (_isSheetOpen || _bottomSheet is null)
20442078
{
20452079
return;
20462080
}
20472081

20482082
// Position the bottom sheet just below the visible area
20492083
_bottomSheet.TranslationY = Height;
20502084
_bottomSheet.IsVisible = true;
2051-
_overlayGrid.IsVisible = IsModal;
2052-
_overlayGrid.Opacity = 0;
2085+
2086+
// Add overlay to view if modal
2087+
if (IsModal)
2088+
{
2089+
AddOverlayToView();
2090+
}
20532091
}
20542092

20552093

@@ -2159,46 +2197,45 @@ void AnimateBottomSheet(double targetPosition, Action? onFinish = null)
21592197
/// </summary>
21602198
void AnimateOverlay(int animationDuration)
21612199
{
2162-
if (_overlayGrid is not null)
2200+
if (_overlayGrid is null || !IsModal)
2201+
{
2202+
return;
2203+
}
2204+
2205+
// Ensure overlay is added to view when needed
2206+
bool shouldShowOverlay = State is not (BottomSheetState.Collapsed or BottomSheetState.Hidden);
2207+
2208+
if (shouldShowOverlay)
2209+
{
2210+
AddOverlayToView();
2211+
}
2212+
2213+
if (_overlayGrid.AnimationIsRunning("overlayGridAnimation"))
21632214
{
2164-
double startValue = 0;
2165-
double endValue = 0;
2166-
_overlayGrid.IsVisible = IsModal;
2215+
_overlayGrid.AbortAnimation("overlayGridAnimation");
2216+
}
21672217

2168-
if (IsModal)
2218+
double startValue = _overlayGrid.Opacity;
2219+
double endValue = shouldShowOverlay ? DefaultOverlayOpacity : 0;
2220+
2221+
var overlayGridAnimation = new Animation(d =>
2222+
{
2223+
if (!double.IsNaN(d))
21692224
{
2170-
if (State is BottomSheetState.Collapsed || State is BottomSheetState.Hidden)
2171-
{
2172-
startValue = _overlayGrid.Opacity;
2173-
endValue = 0;
2174-
}
2175-
else
2176-
{
2177-
startValue = _overlayGrid.Opacity;
2178-
endValue = DefaultOverlayOpacity;
2179-
}
2225+
_overlayGrid.Opacity = d;
2226+
}
2227+
}, startValue, endValue);
21802228

2181-
var overlayGridAnimation = new Animation(d =>
2229+
_overlayGrid.Animate("overlayGridAnimation", overlayGridAnimation,
2230+
length: (uint)animationDuration,
2231+
easing: Easing.Linear,
2232+
finished: (v, c) =>
2233+
{
2234+
if (!shouldShowOverlay)
21822235
{
2183-
// Ensure the opacity is only updated with valid numeric values to avoid rendering issues.
2184-
if (!double.IsNaN(d))
2185-
{
2186-
_overlayGrid.Opacity = d;
2187-
}
2236+
RemoveOverlayFromView();
21882237
}
2189-
, startValue, endValue);
2190-
_overlayGrid.Animate("overlayGridAnimation", overlayGridAnimation,
2191-
length: (uint)animationDuration,
2192-
easing: Easing.Linear,
2193-
finished: (e, v) =>
2194-
{
2195-
if (State is BottomSheetState.Collapsed || State is BottomSheetState.Hidden)
2196-
{
2197-
_overlayGrid.IsVisible = false;
2198-
}
2199-
});
2200-
}
2201-
}
2238+
});
22022239
}
22032240

22042241
/// <summary>
@@ -2342,16 +2379,29 @@ AllowedState is BottomSheetAllowedState.HalfExpanded &&
23422379
/// <param name="touchY">The current Y coordinate of the touch point.</param>
23432380
void UpdateBottomSheetPosition(double newTranslationY, double touchY)
23442381
{
2345-
if (_bottomSheet is null || _overlayGrid is null)
2382+
if (_bottomSheet is null)
23462383
{
23472384
return;
23482385
}
23492386

23502387
_bottomSheet.TranslationY = newTranslationY;
23512388
_initialTouchY = touchY;
23522389
_bottomSheet.HeightRequest = Height - newTranslationY;
2353-
_overlayGrid.IsVisible = IsModal && (_bottomSheet.HeightRequest > CollapsedHeight);
2354-
_overlayGrid.Opacity = CalculateOverlayOpacity(_bottomSheet.HeightRequest);
2390+
// Manage overlay visibility during touch
2391+
bool shouldShowOverlay = IsModal && (_bottomSheet.HeightRequest > CollapsedHeight);
2392+
2393+
if (shouldShowOverlay)
2394+
{
2395+
AddOverlayToView();
2396+
if (_overlayGrid is not null)
2397+
{
2398+
_overlayGrid.Opacity = CalculateOverlayOpacity(_bottomSheet.HeightRequest);
2399+
}
2400+
}
2401+
else
2402+
{
2403+
RemoveOverlayFromView();
2404+
}
23552405
}
23562406

23572407
/// <summary>
@@ -2517,12 +2567,18 @@ static void OnIsModalPropertyChanged(BindableObject bindable, object oldValue, o
25172567
{
25182568
if (bindable is SfBottomSheet sheet)
25192569
{
2520-
if (sheet._overlayGrid is not null && (sheet.State is BottomSheetState.FullExpanded || sheet.State is BottomSheetState.HalfExpanded))
2521-
{
2522-
sheet._overlayGrid.IsVisible = sheet.IsModal;
2570+
bool isModal = (bool)newValue;
2571+
2572+
if (isModal && (sheet.State is BottomSheetState.FullExpanded or BottomSheetState.HalfExpanded))
2573+
{
2574+
sheet.AddOverlayToView();
25232575
sheet.AnimateOverlay(150);
2524-
}
2525-
}
2576+
}
2577+
else if (!isModal)
2578+
{
2579+
sheet.RemoveOverlayFromView();
2580+
}
2581+
}
25262582
}
25272583

25282584

maui/tests/Syncfusion.Maui.Toolkit.UnitTest/Navigation/SfBottomSheetUnitTests.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public void Constructor_InitializesDefaultsCorrectly()
3838
Assert.Equal(4d, _bottomSheet.GrabberHeight);
3939
Assert.Equal(32d, _bottomSheet.GrabberWidth);
4040
Assert.Equal(12d, _bottomSheet.GrabberCornerRadius);
41-
Assert.Equal(150d, _bottomSheet.AnimationDuration);
41+
Assert.Equal(150d,_bottomSheet.AnimationDuration);
4242
if (_bottomSheet.GrabberBackground is SolidColorBrush grabberBrush)
4343
{
4444
var grabberColor = grabberBrush.Color;
@@ -564,7 +564,7 @@ public void InitializeLayout()
564564
var bottomSheet = GetPrivateField(_bottomSheet, "_bottomSheet");
565565
var overlayGrid = GetPrivateField(_bottomSheet, "_overlayGrid");
566566
Assert.True(_bottomSheet.Children?.Contains(bottomSheet));
567-
Assert.True(_bottomSheet.Children?.Contains(overlayGrid));
567+
Assert.False(_bottomSheet.Children?.Contains(overlayGrid));
568568
}
569569

570570
[Fact]
@@ -592,7 +592,7 @@ public void InitializeOverlayGrid()
592592
Grid? overlayGrid = (Grid?)GetPrivateField(_bottomSheet, "_overlayGrid");
593593
Assert.Equal(overlayGrid?.BackgroundColor, Color.FromArgb("#80000000"));
594594
Assert.Equal(overlayGrid?.Opacity, 0.5);
595-
Assert.Equal(overlayGrid?.IsVisible, false);
595+
Assert.Equal(overlayGrid?.IsVisible, true);
596596
}
597597

598598
[Fact]
@@ -852,24 +852,24 @@ public void UpdateStateChanged(BottomSheetState oldState, BottomSheetState newSt
852852

853853
[Theory]
854854
[InlineData(true, true)]
855-
[InlineData(false, false)]
855+
[InlineData(false, true)]
856856
public void SetupBottomSheetForShow(bool input, bool expected)
857857
{
858858
_bottomSheet.IsModal = input;
859859
InvokePrivateMethod(_bottomSheet, "SetupBottomSheetForShow");
860860
SfGrid? overlay = (SfGrid?)GetPrivateField(_bottomSheet, "_overlayGrid");
861861
SfBorder? bottomsheet = (SfBorder?)GetPrivateField(_bottomSheet, "_bottomSheet");
862862
Assert.True(bottomsheet?.IsVisible);
863-
Assert.Equal(0, overlay?.Opacity);
863+
Assert.Equal(0.5, overlay?.Opacity);
864864
Assert.Equal(expected, overlay?.IsVisible);
865865
}
866866

867867
[Fact]
868868
public void GetCollapsedPosition()
869869
{
870870
InvokePrivateMethod(_bottomSheet, "GetCollapsedPosition");
871-
SfGrid? overlay = (SfGrid?)GetPrivateField(_bottomSheet, "_overlayGrid");
872-
Assert.False(overlay?.IsVisible);
871+
var overlay = GetPrivateField(_bottomSheet, "_overlayGrid");
872+
Assert.False(_bottomSheet.Children?.Contains(overlay));
873873
}
874874

875875
[Fact]

0 commit comments

Comments
 (0)