1
- using Microsoft . Maui . Controls . Shapes ;
1
+ using Microsoft . Maui . Controls . Shapes ;
2
2
using Syncfusion . Maui . Toolkit . Internals ;
3
3
using Syncfusion . Maui . Toolkit . Themes ;
4
4
using Syncfusion . Maui . Toolkit . Helper ;
@@ -74,11 +74,16 @@ public partial class SfBottomSheet : SfView, IParentThemeElement
74
74
/// </summary>
75
75
bool _isPointerPressed ;
76
76
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 ;
82
87
83
88
/// <summary>
84
89
/// The starting Y-coordinate of a swipe gesture on the bottom sheet.
@@ -1242,7 +1247,7 @@ internal Color OverlayBackgroundColor
1242
1247
/// </exception>
1243
1248
public void Show ( )
1244
1249
{
1245
- if ( _bottomSheet is null || _overlayGrid is null )
1250
+ if ( _bottomSheet is null )
1246
1251
{
1247
1252
return ;
1248
1253
}
@@ -1267,15 +1272,15 @@ public void Show()
1267
1272
/// </exception>
1268
1273
public void Close ( )
1269
1274
{
1270
- if ( _bottomSheet is null || _overlayGrid is null )
1275
+ if ( _bottomSheet is null )
1271
1276
{
1272
1277
return ;
1273
1278
}
1274
1279
1275
1280
AnimateBottomSheet ( Height , onFinish : ( ) =>
1276
1281
{
1277
1282
_bottomSheet . IsVisible = false ;
1278
- _overlayGrid . IsVisible = false ;
1283
+ RemoveOverlayFromView ( ) ;
1279
1284
} ) ;
1280
1285
1281
1286
if ( _isSheetOpen )
@@ -1356,9 +1361,8 @@ void InitializeLayout()
1356
1361
InitializeBottomSheetBorder ( ) ;
1357
1362
InitializeContentBorder ( ) ;
1358
1363
1359
- if ( _bottomSheet is not null && _overlayGrid is not null )
1364
+ if ( _bottomSheet is not null )
1360
1365
{
1361
- Children . Add ( _overlayGrid ) ;
1362
1366
Children . Add ( _bottomSheet ) ;
1363
1367
_bottomSheet . IsVisible = false ;
1364
1368
}
@@ -1370,6 +1374,7 @@ void InitializeLayout()
1370
1374
void UpdateContentView ( )
1371
1375
{
1372
1376
Children . Clear ( ) ;
1377
+ _isOverlayAdded = false ; // Reset overlay state
1373
1378
UpdateAllChild ( ) ;
1374
1379
}
1375
1380
@@ -1379,7 +1384,6 @@ void UpdateContentView()
1379
1384
void UpdateAllChild ( )
1380
1385
{
1381
1386
AddChild ( Content ) ;
1382
- AddChild ( _overlayGrid ) ;
1383
1387
AddChild ( _bottomSheet ) ;
1384
1388
}
1385
1389
@@ -1404,7 +1408,7 @@ void InitializeOverlayGrid()
1404
1408
{
1405
1409
BackgroundColor = OverlayBackgroundColor ,
1406
1410
Opacity = DefaultOverlayOpacity ,
1407
- IsVisible = false
1411
+ IsVisible = true
1408
1412
} ;
1409
1413
1410
1414
var tapGestureRecognizer = new TapGestureRecognizer ( ) ;
@@ -1485,6 +1489,36 @@ void InitializeBottomSheetBorder()
1485
1489
} ;
1486
1490
}
1487
1491
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
+
1488
1522
/// <summary>
1489
1523
/// Calculates the initial height for the half-expanded state.
1490
1524
/// </summary>
@@ -2040,16 +2074,20 @@ void RegisterSizeChangedEvent()
2040
2074
/// </summary>
2041
2075
void SetupBottomSheetForShow ( )
2042
2076
{
2043
- if ( _isSheetOpen || _bottomSheet is null || _overlayGrid is null )
2077
+ if ( _isSheetOpen || _bottomSheet is null )
2044
2078
{
2045
2079
return ;
2046
2080
}
2047
2081
2048
2082
// Position the bottom sheet just below the visible area
2049
2083
_bottomSheet . TranslationY = Height ;
2050
2084
_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
+ }
2053
2091
}
2054
2092
2055
2093
@@ -2133,11 +2171,6 @@ void AnimateBottomSheet(double targetPosition, Action? onFinish = null)
2133
2171
_bottomSheet . AbortAnimation ( "bottomSheetAnimation" ) ;
2134
2172
}
2135
2173
2136
- if ( _overlayGrid . AnimationIsRunning ( "overlayGridAnimation" ) )
2137
- {
2138
- _overlayGrid . AbortAnimation ( "overlayGridAnimation" ) ;
2139
- }
2140
-
2141
2174
int animationDuration = this . GetClampedAnimationDuration ( ) ;
2142
2175
const int topPadding = 2 ;
2143
2176
_isSheetOpen = true ;
@@ -2159,46 +2192,45 @@ void AnimateBottomSheet(double targetPosition, Action? onFinish = null)
2159
2192
/// </summary>
2160
2193
void AnimateOverlay ( int animationDuration )
2161
2194
{
2162
- if ( _overlayGrid is not null )
2195
+ if ( _overlayGrid is null || ! IsModal )
2163
2196
{
2164
- double startValue = 0 ;
2165
- double endValue = 0 ;
2166
- _overlayGrid . IsVisible = IsModal ;
2197
+ return ;
2198
+ }
2167
2199
2168
- if ( IsModal )
2200
+ // Ensure overlay is added to view when needed
2201
+ bool shouldShowOverlay = State is not ( BottomSheetState . Collapsed or BottomSheetState . Hidden ) ;
2202
+
2203
+ if ( shouldShowOverlay )
2204
+ {
2205
+ AddOverlayToView ( ) ;
2206
+ }
2207
+
2208
+ if ( _overlayGrid . AnimationIsRunning ( "overlayGridAnimation" ) )
2209
+ {
2210
+ _overlayGrid . AbortAnimation ( "overlayGridAnimation" ) ;
2211
+ }
2212
+
2213
+ double startValue = _overlayGrid . Opacity ;
2214
+ double endValue = shouldShowOverlay ? DefaultOverlayOpacity : 0 ;
2215
+
2216
+ var overlayGridAnimation = new Animation ( d =>
2217
+ {
2218
+ if ( ! double . IsNaN ( d ) )
2169
2219
{
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
- }
2220
+ _overlayGrid . Opacity = d ;
2221
+ }
2222
+ } , startValue , endValue ) ;
2180
2223
2181
- var overlayGridAnimation = new Animation ( d =>
2224
+ _overlayGrid . Animate ( "overlayGridAnimation" , overlayGridAnimation ,
2225
+ length : ( uint ) animationDuration ,
2226
+ easing : Easing . Linear ,
2227
+ finished : ( v , c ) =>
2228
+ {
2229
+ if ( ! shouldShowOverlay )
2182
2230
{
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
- }
2231
+ RemoveOverlayFromView ( ) ;
2188
2232
}
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
- }
2233
+ } ) ;
2202
2234
}
2203
2235
2204
2236
/// <summary>
@@ -2342,16 +2374,29 @@ AllowedState is BottomSheetAllowedState.HalfExpanded &&
2342
2374
/// <param name="touchY">The current Y coordinate of the touch point.</param>
2343
2375
void UpdateBottomSheetPosition ( double newTranslationY , double touchY )
2344
2376
{
2345
- if ( _bottomSheet is null || _overlayGrid is null )
2377
+ if ( _bottomSheet is null )
2346
2378
{
2347
2379
return ;
2348
2380
}
2349
2381
2350
2382
_bottomSheet . TranslationY = newTranslationY ;
2351
2383
_initialTouchY = touchY ;
2352
2384
_bottomSheet . HeightRequest = Height - newTranslationY ;
2353
- _overlayGrid . IsVisible = IsModal && ( _bottomSheet . HeightRequest > CollapsedHeight ) ;
2354
- _overlayGrid . Opacity = CalculateOverlayOpacity ( _bottomSheet . HeightRequest ) ;
2385
+ // Manage overlay visibility during touch
2386
+ bool shouldShowOverlay = IsModal && ( _bottomSheet . HeightRequest > CollapsedHeight ) ;
2387
+
2388
+ if ( shouldShowOverlay )
2389
+ {
2390
+ AddOverlayToView ( ) ;
2391
+ if ( _overlayGrid is not null )
2392
+ {
2393
+ _overlayGrid . Opacity = CalculateOverlayOpacity ( _bottomSheet . HeightRequest ) ;
2394
+ }
2395
+ }
2396
+ else
2397
+ {
2398
+ RemoveOverlayFromView ( ) ;
2399
+ }
2355
2400
}
2356
2401
2357
2402
/// <summary>
@@ -2517,12 +2562,18 @@ static void OnIsModalPropertyChanged(BindableObject bindable, object oldValue, o
2517
2562
{
2518
2563
if ( bindable is SfBottomSheet sheet )
2519
2564
{
2520
- if ( sheet . _overlayGrid is not null && ( sheet . State is BottomSheetState . FullExpanded || sheet . State is BottomSheetState . HalfExpanded ) )
2521
- {
2522
- sheet . _overlayGrid . IsVisible = sheet . IsModal ;
2565
+ bool isModal = ( bool ) newValue ;
2566
+
2567
+ if ( isModal && ( sheet . State is BottomSheetState . FullExpanded or BottomSheetState . HalfExpanded ) )
2568
+ {
2569
+ sheet . AddOverlayToView ( ) ;
2523
2570
sheet . AnimateOverlay ( 150 ) ;
2524
- }
2525
- }
2571
+ }
2572
+ else if ( ! isModal )
2573
+ {
2574
+ sheet . RemoveOverlayFromView ( ) ;
2575
+ }
2576
+ }
2526
2577
}
2527
2578
2528
2579
0 commit comments