@@ -34,15 +34,36 @@ public class CustomPhoneFlyoutPageRendererPopOver : UIViewController, IPlatformV
34
34
bool _applyShadow ;
35
35
36
36
bool _intialLayoutFinished ;
37
+ bool ? _flyoutOverlapsDetailsInPopoverMode ;
37
38
38
39
Page Page => Element as Page ;
39
40
IFlyoutPageController FlyoutPageController => FlyoutPage ;
40
41
IMauiContext _mauiContext ;
41
42
IMauiContext MauiContext => _mauiContext ;
42
- bool IsPad => UIDevice . CurrentDevice . UserInterfaceIdiom == UIUserInterfaceIdiom . Pad ;
43
43
44
44
public static IPropertyMapper < FlyoutPage , CustomPhoneFlyoutPageRendererPopOver > Mapper = new PropertyMapper < FlyoutPage , CustomPhoneFlyoutPageRendererPopOver > ( ViewHandler . ViewMapper ) ;
45
45
public static CommandMapper < FlyoutPage , CustomPhoneFlyoutPageRendererPopOver > CommandMapper = new CommandMapper < FlyoutPage , CustomPhoneFlyoutPageRendererPopOver > ( ViewHandler . ViewCommandMapper ) ;
46
+ // Forms used a UISplitViewController for iPad and a custom implementation for iPhone.
47
+ // With MAUI, we switched to using this same handler for both iPad/iPhone to simplify
48
+ // the amount of code we needed to maintain. The UISplitViewController implementation was also
49
+ // problematic and would break frequently between iOS upgrades.
50
+ // At a later point, this implementation will get merged with the shell implementation so we have
51
+ // to maintain even less code.
52
+ public bool FlyoutOverlapsDetailsInPopoverMode
53
+ {
54
+ get
55
+ {
56
+ return _flyoutOverlapsDetailsInPopoverMode ??
57
+ UIDevice . CurrentDevice . UserInterfaceIdiom == UIUserInterfaceIdiom . Pad ;
58
+ }
59
+ set
60
+ {
61
+ _flyoutOverlapsDetailsInPopoverMode = value ;
62
+ }
63
+ }
64
+
65
+ bool IsRTL => ( Element as IVisualElementController ) ? . EffectiveFlowDirection . IsRightToLeft ( ) == true ;
66
+
46
67
ViewHandlerDelegator < FlyoutPage > _viewHandlerWrapper ;
47
68
48
69
[ Preserve ( Conditional = true ) ]
@@ -170,7 +191,7 @@ bool shouldReceive(UIGestureRecognizer g, UITouch t)
170
191
UpdatePresented ( false , true ) ;
171
192
} ) ;
172
193
173
- if ( IsPad )
194
+ if ( FlyoutOverlapsDetailsInPopoverMode )
174
195
_tapGesture . ShouldReceiveTouch = shouldReceive ;
175
196
176
197
_clickOffView . AddGestureRecognizer ( _tapGesture ) ;
@@ -188,7 +209,7 @@ public override void ViewWillTransitionToSize(CoreGraphics.CGSize toSize, IUIVie
188
209
{
189
210
base . ViewWillTransitionToSize ( toSize , coordinator ) ;
190
211
191
- if ( IsPad )
212
+ if ( FlyoutOverlapsDetailsInPopoverMode )
192
213
{
193
214
if ( FlyoutPageController . ShouldShowSplitMode )
194
215
UpdatePresented ( true ) ;
@@ -269,7 +290,7 @@ protected virtual void OnElementChanged(VisualElementChangedEventArgs e)
269
290
270
291
void UpdateClickOffView ( )
271
292
{
272
- if ( IsPad && FlyoutPageController . ShouldShowSplitMode )
293
+ if ( FlyoutOverlapsDetailsInPopoverMode && FlyoutPageController . ShouldShowSplitMode )
273
294
{
274
295
RemoveClickOffView ( ) ;
275
296
return ;
@@ -292,14 +313,18 @@ void AddClickOffView()
292
313
293
314
void UpdateClickOffViewFrame ( )
294
315
{
295
- if ( IsPad )
316
+ if ( FlyoutOverlapsDetailsInPopoverMode )
296
317
{
297
318
var detailsFrame = _detailController . View . Frame ;
298
319
var flyoutWidth = _flyoutController . View . Frame . Width ;
320
+ var clickOffX = _flyoutController . View . Frame . Width ;
321
+
322
+ if ( IsRTL )
323
+ clickOffX = 0 ;
299
324
300
325
_clickOffView . Frame =
301
326
new CoreGraphics . CGRect (
302
- _flyoutController . View . Frame . Width ,
327
+ clickOffX ,
303
328
detailsFrame . Y ,
304
329
detailsFrame . Width - flyoutWidth ,
305
330
detailsFrame . Height ) ;
@@ -352,7 +377,7 @@ void LayoutChildren(bool animated)
352
377
var flyoutFrame = frame ;
353
378
nfloat opacity = 1 ;
354
379
355
- if ( IsPad )
380
+ if ( FlyoutOverlapsDetailsInPopoverMode )
356
381
flyoutFrame . Width = 320 ;
357
382
else
358
383
flyoutFrame . Width = ( int ) ( Math . Min ( flyoutFrame . Width , flyoutFrame . Height ) * 0.8 ) ;
@@ -363,75 +388,89 @@ void LayoutChildren(bool animated)
363
388
364
389
var detailView = detailRenderer . ViewController . View ;
365
390
366
- var isRTL = ( Element as IVisualElementController ) ? . EffectiveFlowDirection . IsRightToLeft ( ) == true ;
367
- if ( isRTL )
391
+ if ( IsRTL && ! FlyoutOverlapsDetailsInPopoverMode )
368
392
{
369
393
flyoutFrame . X = ( int ) ( flyoutFrame . Width * .25 ) ;
370
394
}
371
395
372
- var target = frame ;
396
+ var detailsFrame = frame ;
373
397
if ( Presented )
374
398
{
375
- if ( ! IsPad || FlyoutPageController . ShouldShowSplitMode )
376
- target . X += flyoutFrame . Width ;
399
+ if ( ! FlyoutOverlapsDetailsInPopoverMode || FlyoutPageController . ShouldShowSplitMode )
400
+ {
401
+ if ( IsRTL && FlyoutPageController . ShouldShowSplitMode )
402
+ detailsFrame . X = 0 ;
403
+ else
404
+ detailsFrame . X += flyoutFrame . Width ;
405
+ }
377
406
378
- if ( IsPad && FlyoutPageController . ShouldShowSplitMode )
379
- target . Width -= flyoutFrame . Width ;
407
+ if ( FlyoutOverlapsDetailsInPopoverMode && FlyoutPageController . ShouldShowSplitMode )
408
+ {
409
+ detailsFrame . Width -= flyoutFrame . Width ;
410
+ }
380
411
381
412
if ( _applyShadow )
413
+ {
382
414
opacity = 0.5f ;
415
+ }
383
416
}
384
417
385
- if ( isRTL )
418
+ if ( IsRTL && ! FlyoutOverlapsDetailsInPopoverMode )
386
419
{
387
- target . X = target . X * - 1 ;
420
+ detailsFrame . X = detailsFrame . X * - 1 ;
388
421
}
389
422
390
- if ( animated && ! IsPad )
423
+ if ( animated && ! FlyoutOverlapsDetailsInPopoverMode )
391
424
{
392
- if ( ! IsPad )
425
+ if ( ! FlyoutOverlapsDetailsInPopoverMode )
393
426
{
394
427
UIView . Animate ( 0.250 , 0 , UIViewAnimationOptions . CurveEaseOut , ( ) =>
395
428
{
396
429
var view = _detailController . View ;
397
- view . Frame = target ;
430
+ view . Frame = detailsFrame ;
398
431
detailView . Layer . Opacity = ( float ) opacity ;
399
432
} , ( ) => { } ) ;
400
433
}
401
434
}
402
435
else
403
436
{
404
- _detailController . View . Frame = target ;
437
+ _detailController . View . Frame = detailsFrame ;
405
438
detailView . Layer . Opacity = ( float ) opacity ;
406
439
}
407
440
408
- if ( IsPad )
441
+ if ( FlyoutOverlapsDetailsInPopoverMode )
409
442
{
410
443
if ( ! Presented )
411
444
{
412
- flyoutFrame . X -= flyoutFrame . Width ;
445
+ if ( ! IsRTL )
446
+ flyoutFrame . X -= flyoutFrame . Width ;
447
+ else
448
+ flyoutFrame . X = frame . Width ;
413
449
}
414
-
415
- if ( animated )
450
+ else if ( IsRTL )
416
451
{
417
- UIView . Animate ( 0.250 , 0 , UIViewAnimationOptions . CurveEaseOut , ( ) =>
418
- {
419
- _flyoutController . View . Frame = flyoutFrame ;
420
- detailView . Layer . Opacity = ( float ) opacity ;
421
- } , ( ) => { } ) ;
452
+ if ( FlyoutPageController . ShouldShowSplitMode )
453
+ flyoutFrame . X = detailsFrame . Width ;
454
+ else
455
+ flyoutFrame . X = frame . Width - flyoutFrame . Width ;
422
456
}
423
- else
457
+ }
458
+
459
+ if ( animated && FlyoutOverlapsDetailsInPopoverMode )
460
+ {
461
+ UIView . Animate ( 0.250 , 0 , UIViewAnimationOptions . CurveEaseOut , ( ) =>
424
462
{
425
463
_flyoutController . View . Frame = flyoutFrame ;
426
- }
464
+ detailView . Layer . Opacity = ( float ) opacity ;
465
+ } , ( ) => { } ) ;
466
+ }
467
+ else
468
+ {
469
+ _flyoutController . View . Frame = flyoutFrame ;
427
470
}
428
471
429
472
FlyoutPageController . FlyoutBounds = new Rect ( flyoutFrame . X , 0 , flyoutFrame . Width , flyoutFrame . Height ) ;
430
-
431
- if ( IsPad )
432
- FlyoutPageController . DetailBounds = new Rect ( target . X , 0 , frame . Width , frame . Height ) ;
433
- else
434
- FlyoutPageController . DetailBounds = new Rect ( 0 , 0 , frame . Width , frame . Height ) ;
473
+ FlyoutPageController . DetailBounds = new Rect ( detailsFrame . X , 0 , frame . Width , frame . Height ) ;
435
474
436
475
if ( Presented )
437
476
UpdateClickOffViewFrame ( ) ;
@@ -441,7 +480,7 @@ void PackContainers()
441
480
{
442
481
_detailController . View . BackgroundColor = new UIColor ( 1 , 1 , 1 , 1 ) ;
443
482
444
- if ( ! IsPad )
483
+ if ( ! FlyoutOverlapsDetailsInPopoverMode )
445
484
{
446
485
View . AddSubview ( _flyoutController . View ) ;
447
486
View . AddSubview ( _detailController . View ) ;
@@ -601,17 +640,15 @@ bool shouldReceive(UIGestureRecognizer g, UITouch t)
601
640
var center = new PointF ( ) ;
602
641
_panGesture = new UIPanGestureRecognizer ( g =>
603
642
{
604
- var isRTL = ( Element as IVisualElementController ) ? . EffectiveFlowDirection . IsRightToLeft ( ) == true ;
605
-
606
- int directionModifier = isRTL ? - 1 : 1 ;
643
+ int directionModifier = IsRTL ? - 1 : 1 ;
607
644
608
645
switch ( g . State )
609
646
{
610
647
case UIGestureRecognizerState . Began :
611
648
center = g . LocationInView ( g . View ) ;
612
649
break ;
613
650
case UIGestureRecognizerState . Changed :
614
- if ( ! IsPad )
651
+ if ( ! FlyoutOverlapsDetailsInPopoverMode )
615
652
{
616
653
var currentPosition = g . LocationInView ( g . View ) ;
617
654
var motion = currentPosition . X - center . X ;
@@ -650,7 +687,11 @@ bool shouldReceive(UIGestureRecognizer g, UITouch t)
650
687
else
651
688
targetFrame . X = ( nfloat ) Math . Min ( 0 , Math . Max ( 0 , motion ) - flyoutWidth ) ;
652
689
653
- targetFrame . X = targetFrame . X * directionModifier ;
690
+ if ( IsRTL )
691
+ {
692
+ targetFrame . X = ( float ) Element . Bounds . Width - ( flyoutWidth + targetFrame . X ) ;
693
+ }
694
+
654
695
if ( _applyShadow )
655
696
{
656
697
var openProgress = targetFrame . X / flyoutWidth ;
@@ -663,7 +704,7 @@ bool shouldReceive(UIGestureRecognizer g, UITouch t)
663
704
break ;
664
705
case UIGestureRecognizerState . Ended :
665
706
666
- if ( ! IsPad )
707
+ if ( ! FlyoutOverlapsDetailsInPopoverMode )
667
708
{
668
709
var detailFrame = _detailController . View . Frame ;
669
710
var flyoutFrame = _flyoutController . View . Frame ;
@@ -685,18 +726,23 @@ bool shouldReceive(UIGestureRecognizer g, UITouch t)
685
726
else
686
727
{
687
728
var flyoutFrame = _flyoutController . View . Frame ;
688
- var progress = flyoutFrame . Width + flyoutFrame . X ;
729
+ var flyoutOffsetX = flyoutFrame . X + flyoutFrame . Width ;
730
+
731
+ if ( IsRTL )
732
+ {
733
+ flyoutOffsetX = ( float ) Element . Bounds . Width - flyoutFrame . X ;
734
+ }
689
735
690
736
if ( Presented )
691
737
{
692
- if ( flyoutFrame . X * directionModifier < flyoutFrame . Width * .75 )
738
+ if ( flyoutOffsetX < flyoutFrame . Width * .75 )
693
739
UpdatePresented ( false ) ;
694
740
else
695
741
LayoutChildren ( true ) ;
696
742
}
697
743
else
698
744
{
699
- if ( ( flyoutFrame . X + flyoutFrame . Width ) * directionModifier > flyoutFrame . Width * .25 )
745
+ if ( flyoutOffsetX > flyoutFrame . Width * .25 )
700
746
UpdatePresented ( true ) ;
701
747
else
702
748
LayoutChildren ( true ) ;
0 commit comments