react-native-navigation 7.47.0 → 7.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/dist/src/interfaces/Options.d.ts +9 -0
- package/lib/ios/RNNSideMenu/MMDrawerController/MMDrawerController.h +22 -0
- package/lib/ios/RNNSideMenu/MMDrawerController/MMDrawerController.m +782 -161
- package/lib/ios/RNNSideMenuPresenter.m +27 -0
- package/lib/ios/RNNSideMenuSideOptions.h +6 -0
- package/lib/ios/RNNSideMenuSideOptions.m +13 -1
- package/lib/src/interfaces/Options.ts +9 -0
- package/package.json +1 -1
|
@@ -986,10 +986,19 @@ export interface SideMenuSide {
|
|
|
986
986
|
height?: number;
|
|
987
987
|
/**
|
|
988
988
|
* Stretch sideMenu contents when opened past the width
|
|
989
|
+
*
|
|
990
|
+
* **Not applicable when `openMode` is `aboveContent`**
|
|
991
|
+
*
|
|
989
992
|
* #### (iOS specific)
|
|
990
993
|
* @default true
|
|
991
994
|
*/
|
|
992
995
|
shouldStretchDrawer?: boolean;
|
|
996
|
+
/**
|
|
997
|
+
* Configure the opening mode of the side menu
|
|
998
|
+
* #### (iOS specific)
|
|
999
|
+
* @default 'pushContent'
|
|
1000
|
+
*/
|
|
1001
|
+
openMode?: 'pushContent' | 'aboveContent';
|
|
993
1002
|
}
|
|
994
1003
|
export interface OptionsSideMenu {
|
|
995
1004
|
/**
|
|
@@ -127,6 +127,14 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController *dra
|
|
|
127
127
|
|
|
128
128
|
@interface MMDrawerController : UIViewController
|
|
129
129
|
|
|
130
|
+
/**
|
|
131
|
+
Enum defining how the drawer opens
|
|
132
|
+
*/
|
|
133
|
+
typedef NS_ENUM(NSInteger, MMDrawerOpenMode) {
|
|
134
|
+
MMDrawerOpenModePushContent = 0, // Original behavior - pushes content aside
|
|
135
|
+
MMDrawerOpenModeAboveContent = 1, // Overlay behavior - opens above content
|
|
136
|
+
};
|
|
137
|
+
|
|
130
138
|
///---------------------------------------
|
|
131
139
|
/// @name Accessing Drawer Container View Controller Properties
|
|
132
140
|
///---------------------------------------
|
|
@@ -213,6 +221,18 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController *dra
|
|
|
213
221
|
@property(nonatomic, assign) BOOL shouldStretchLeftDrawer;
|
|
214
222
|
@property(nonatomic, assign) BOOL shouldStretchRightDrawer;
|
|
215
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Specifies how the drawer should open relative to the center content.
|
|
226
|
+
*
|
|
227
|
+
* Possible values:
|
|
228
|
+
* - MMDrawerOpenModePushContent: The drawer will push the center content aside when opening (traditional behavior).
|
|
229
|
+
* - MMDrawerOpenModeAboveContent: The drawer will open above the center content with a semi-transparent overlay.
|
|
230
|
+
*
|
|
231
|
+
* By default, this value is set to MMDrawerOpenModePushContent.
|
|
232
|
+
*/
|
|
233
|
+
@property(nonatomic, assign) MMDrawerOpenMode leftDrawerOpenMode;
|
|
234
|
+
@property(nonatomic, assign) MMDrawerOpenMode rightDrawerOpenMode;
|
|
235
|
+
|
|
216
236
|
/**
|
|
217
237
|
The current open side of the drawer.
|
|
218
238
|
|
|
@@ -600,4 +620,6 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController *dra
|
|
|
600
620
|
(BOOL (^)(MMDrawerController *drawerController, UIGestureRecognizer *gesture,
|
|
601
621
|
UITouch *touch))gestureShouldRecognizeTouchBlock;
|
|
602
622
|
|
|
623
|
+
- (void)side:(MMDrawerSide)drawerSide openMode:(MMDrawerOpenMode)openMode;
|
|
624
|
+
|
|
603
625
|
@end
|
|
@@ -152,6 +152,8 @@ static NSString *MMDrawerOpenSideKey = @"MMDrawerOpenSide";
|
|
|
152
152
|
CGFloat _maximumRightDrawerWidth;
|
|
153
153
|
CGFloat _maximumLeftDrawerWidth;
|
|
154
154
|
UIColor *_statusBarViewBackgroundColor;
|
|
155
|
+
MMDrawerOpenMode _leftDrawerOpenMode;
|
|
156
|
+
MMDrawerOpenMode _rightDrawerOpenMode;
|
|
155
157
|
}
|
|
156
158
|
|
|
157
159
|
@property(nonatomic, assign, readwrite) MMDrawerSide openSide;
|
|
@@ -160,13 +162,15 @@ static NSString *MMDrawerOpenSideKey = @"MMDrawerOpenSide";
|
|
|
160
162
|
@property(nonatomic, strong) MMDrawerCenterContainerView *centerContainerView;
|
|
161
163
|
@property(nonatomic, strong) UIView *dummyStatusBarView;
|
|
162
164
|
|
|
163
|
-
@property(nonatomic, assign) CGRect startingPanRect;
|
|
164
165
|
@property(nonatomic, copy) MMDrawerControllerDrawerVisualStateBlock drawerVisualState;
|
|
165
166
|
@property(nonatomic, copy) MMDrawerGestureShouldRecognizeTouchBlock gestureShouldRecognizeTouch;
|
|
166
167
|
@property(nonatomic, copy) MMDrawerGestureCompletionBlock gestureStart;
|
|
167
168
|
@property(nonatomic, copy) MMDrawerGestureCompletionBlock gestureCompletion;
|
|
168
169
|
@property(nonatomic, assign, getter=isAnimatingDrawer) BOOL animatingDrawer;
|
|
169
170
|
@property(nonatomic, strong) UIGestureRecognizer *pan;
|
|
171
|
+
@property (nonatomic, strong) UIView *centerContentOverlay;
|
|
172
|
+
@property(nonatomic, assign) CGRect startingPanRect;
|
|
173
|
+
@property(nonatomic, assign) MMDrawerSide panDrawerSide;
|
|
170
174
|
|
|
171
175
|
@end
|
|
172
176
|
|
|
@@ -227,6 +231,8 @@ static NSString *MMDrawerOpenSideKey = @"MMDrawerOpenSide";
|
|
|
227
231
|
[self setShowsShadow:YES];
|
|
228
232
|
[self setShouldStretchLeftDrawer:YES];
|
|
229
233
|
[self setShouldStretchRightDrawer:YES];
|
|
234
|
+
[self side:MMDrawerSideRight openMode:MMDrawerOpenModePushContent];
|
|
235
|
+
[self side:MMDrawerSideLeft openMode:MMDrawerOpenModePushContent];
|
|
230
236
|
|
|
231
237
|
[self setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeNone];
|
|
232
238
|
[self setCloseDrawerGestureModeMask:MMCloseDrawerGestureModeNone];
|
|
@@ -323,52 +329,126 @@ static NSString *MMDrawerOpenSideKey = @"MMDrawerOpenSide";
|
|
|
323
329
|
}
|
|
324
330
|
} else {
|
|
325
331
|
[self setAnimatingDrawer:animated];
|
|
326
|
-
|
|
332
|
+
MMDrawerSide visibleSide = self.openSide;
|
|
327
333
|
|
|
328
|
-
|
|
329
|
-
|
|
334
|
+
if (visibleSide == MMDrawerSideNone) {
|
|
335
|
+
[self setAnimatingDrawer:NO];
|
|
336
|
+
if (completion) {
|
|
337
|
+
completion(NO);
|
|
338
|
+
}
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
330
341
|
|
|
331
|
-
|
|
332
|
-
|
|
342
|
+
UIViewController *sideDrawerViewController = [self sideDrawerViewControllerForSide:visibleSide];
|
|
343
|
+
[sideDrawerViewController beginAppearanceTransition:NO animated:animated];
|
|
333
344
|
|
|
334
|
-
|
|
335
|
-
CGFloat percentVisble = 0.0;
|
|
345
|
+
MMDrawerOpenMode openMode = [self getDrawerOpenMode:visibleSide];
|
|
336
346
|
|
|
337
|
-
if (
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
347
|
+
if (openMode == MMDrawerOpenModeAboveContent) {
|
|
348
|
+
[self closeDrawerInOverlayMode:sideDrawerViewController
|
|
349
|
+
visibleSide:visibleSide
|
|
350
|
+
animated:animated
|
|
351
|
+
velocity:velocity
|
|
352
|
+
animationOptions:options
|
|
353
|
+
completion:completion];
|
|
354
|
+
} else {
|
|
355
|
+
[self closeDrawerInPushMode:sideDrawerViewController
|
|
356
|
+
visibleSide:visibleSide
|
|
357
|
+
animated:animated
|
|
358
|
+
velocity:velocity
|
|
359
|
+
animationOptions:options
|
|
360
|
+
completion:completion];
|
|
346
361
|
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
347
364
|
|
|
348
|
-
|
|
349
|
-
|
|
365
|
+
- (void)closeDrawerInOverlayMode:(UIViewController *)sideDrawerViewController
|
|
366
|
+
visibleSide:(MMDrawerSide)visibleSide
|
|
367
|
+
animated:(BOOL)animated
|
|
368
|
+
velocity:(CGFloat)velocity
|
|
369
|
+
animationOptions:(UIViewAnimationOptions)options
|
|
370
|
+
completion:(void (^)(BOOL finished))completion {
|
|
371
|
+
CGFloat maximumDrawerWidth = [self maximumDrawerWidthForSide:visibleSide];
|
|
350
372
|
|
|
351
|
-
|
|
373
|
+
CGRect currentFrame = sideDrawerViewController.view.frame;
|
|
374
|
+
CGRect finalFrame = currentFrame;
|
|
352
375
|
|
|
353
|
-
|
|
376
|
+
// Set final position based on side
|
|
377
|
+
if (visibleSide == MMDrawerSideLeft) {
|
|
378
|
+
finalFrame.origin.x = -maximumDrawerWidth; // Off-screen left
|
|
379
|
+
} else { // MMDrawerSideRight
|
|
380
|
+
finalFrame.origin.x = self.view.bounds.size.width; // Off-screen right
|
|
381
|
+
}
|
|
354
382
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
383
|
+
// Ensure overlay is in view hierarchy
|
|
384
|
+
if (self.centerContentOverlay && self.centerContentOverlay.superview == nil) {
|
|
385
|
+
[self.centerContainerView addSubview:self.centerContentOverlay];
|
|
386
|
+
[self.centerContainerView bringSubviewToFront:self.centerContentOverlay];
|
|
387
|
+
self.centerContentOverlay.alpha = 0.5;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
CGFloat distance = ABS(currentFrame.origin.x - finalFrame.origin.x);
|
|
391
|
+
NSTimeInterval duration = [self animationDurationForDistance:distance velocity:velocity];
|
|
392
|
+
|
|
393
|
+
[UIView animateWithDuration:(animated ? duration : 0.0)
|
|
394
|
+
delay:0.0
|
|
395
|
+
options:options
|
|
396
|
+
animations:^{
|
|
397
|
+
[self setNeedsStatusBarAppearanceUpdateIfSupported];
|
|
398
|
+
[sideDrawerViewController.view setFrame:finalFrame];
|
|
399
|
+
self.centerContentOverlay.alpha = 0.0;
|
|
400
|
+
[self updateDrawerVisualStateForDrawerSide:visibleSide percentVisible:0.0];
|
|
401
|
+
}
|
|
402
|
+
completion:^(BOOL finished) {
|
|
403
|
+
[self completeDrawerClosingForSide:visibleSide
|
|
404
|
+
sideDrawerViewController:sideDrawerViewController
|
|
405
|
+
finished:finished
|
|
406
|
+
completion:completion];
|
|
407
|
+
[self.centerContentOverlay removeFromSuperview];
|
|
408
|
+
}];
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
- (void)closeDrawerInPushMode:(UIViewController *)sideDrawerViewController
|
|
412
|
+
visibleSide:(MMDrawerSide)visibleSide
|
|
413
|
+
animated:(BOOL)animated
|
|
414
|
+
velocity:(CGFloat)velocity
|
|
415
|
+
animationOptions:(UIViewAnimationOptions)options
|
|
416
|
+
completion:(void (^)(BOOL finished))completion {
|
|
417
|
+
|
|
418
|
+
CGRect newFrame = self.childControllerContainerView.bounds;
|
|
419
|
+
|
|
420
|
+
CGFloat distance = ABS(CGRectGetMinX(self.centerContainerView.frame));
|
|
421
|
+
NSTimeInterval duration = [self animationDurationForDistance:distance velocity:velocity];
|
|
422
|
+
sideDrawerViewController.view.hidden = NO;
|
|
423
|
+
|
|
424
|
+
[UIView animateWithDuration:(animated ? duration : 0.0)
|
|
425
|
+
delay:0.0
|
|
426
|
+
options:options
|
|
427
|
+
animations:^{
|
|
428
|
+
[self setNeedsStatusBarAppearanceUpdateIfSupported];
|
|
429
|
+
[self.centerContainerView setFrame:newFrame];
|
|
430
|
+
[self updateDrawerVisualStateForDrawerSide:visibleSide percentVisible:0.0];
|
|
431
|
+
}
|
|
432
|
+
completion:^(BOOL finished) {
|
|
433
|
+
[self completeDrawerClosingForSide:visibleSide
|
|
434
|
+
sideDrawerViewController:sideDrawerViewController
|
|
435
|
+
finished:finished
|
|
436
|
+
completion:completion];
|
|
437
|
+
}];
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
- (void)completeDrawerClosingForSide:(MMDrawerSide)visibleSide
|
|
441
|
+
sideDrawerViewController:(UIViewController *)sideDrawerViewController
|
|
442
|
+
finished:(BOOL)finished
|
|
443
|
+
completion:(void (^)(BOOL finished))completion {
|
|
444
|
+
[sideDrawerViewController endAppearanceTransition];
|
|
445
|
+
|
|
446
|
+
[self setOpenSide:MMDrawerSideNone];
|
|
447
|
+
[self resetDrawerVisualStateForDrawerSide:visibleSide];
|
|
448
|
+
[self setAnimatingDrawer:NO];
|
|
449
|
+
|
|
450
|
+
if (completion) {
|
|
451
|
+
completion(finished);
|
|
372
452
|
}
|
|
373
453
|
}
|
|
374
454
|
|
|
@@ -397,50 +477,207 @@ static NSString *MMDrawerOpenSideKey = @"MMDrawerOpenSide";
|
|
|
397
477
|
}
|
|
398
478
|
} else {
|
|
399
479
|
[self setAnimatingDrawer:animated];
|
|
400
|
-
UIViewController *sideDrawerViewController =
|
|
401
|
-
|
|
480
|
+
UIViewController *sideDrawerViewController = [self sideDrawerViewControllerForSide:drawerSide];
|
|
481
|
+
|
|
402
482
|
if (self.openSide != drawerSide) {
|
|
403
483
|
[self prepareToPresentDrawer:drawerSide animated:animated];
|
|
404
484
|
}
|
|
405
485
|
|
|
406
486
|
if (sideDrawerViewController) {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
if (
|
|
410
|
-
|
|
411
|
-
|
|
487
|
+
MMDrawerOpenMode openMode = [self getDrawerOpenMode:drawerSide];
|
|
488
|
+
|
|
489
|
+
if (openMode == MMDrawerOpenModeAboveContent) {
|
|
490
|
+
[self openDrawerInOverlayMode:sideDrawerViewController
|
|
491
|
+
drawerSide:drawerSide
|
|
492
|
+
animated:animated
|
|
493
|
+
velocity:velocity
|
|
494
|
+
animationOptions:options
|
|
495
|
+
completion:completion];
|
|
412
496
|
} else {
|
|
413
|
-
|
|
414
|
-
|
|
497
|
+
[self openDrawerInPushMode:sideDrawerViewController
|
|
498
|
+
drawerSide:drawerSide
|
|
499
|
+
animated:animated
|
|
500
|
+
velocity:velocity
|
|
501
|
+
animationOptions:options
|
|
502
|
+
completion:completion];
|
|
415
503
|
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
416
507
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
options:options
|
|
424
|
-
animations:^{
|
|
425
|
-
[self setNeedsStatusBarAppearanceUpdateIfSupported];
|
|
426
|
-
[self.centerContainerView setFrame:newFrame withLayoutAlpha:1.0];
|
|
427
|
-
[self updateDrawerVisualStateForDrawerSide:drawerSide percentVisible:1.0];
|
|
428
|
-
}
|
|
429
|
-
completion:^(BOOL finished) {
|
|
430
|
-
// End the appearance transition if it already wasn't open.
|
|
431
|
-
if (drawerSide != self.openSide) {
|
|
432
|
-
[sideDrawerViewController endAppearanceTransition];
|
|
433
|
-
}
|
|
434
|
-
[self setOpenSide:drawerSide];
|
|
508
|
+
- (void)openDrawerInOverlayMode:(UIViewController *)sideDrawerViewController
|
|
509
|
+
drawerSide:(MMDrawerSide)drawerSide
|
|
510
|
+
animated:(BOOL)animated
|
|
511
|
+
velocity:(CGFloat)velocity
|
|
512
|
+
animationOptions:(UIViewAnimationOptions)options
|
|
513
|
+
completion:(void (^)(BOOL finished))completion {
|
|
435
514
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
515
|
+
CGFloat maximumDrawerWidth = [self maximumDrawerWidthForSide:drawerSide];
|
|
516
|
+
|
|
517
|
+
CGRect drawerFrame = sideDrawerViewController.view.frame;
|
|
518
|
+
CGRect initialFrame = sideDrawerViewController.view.frame;
|
|
519
|
+
|
|
520
|
+
drawerFrame.size.width = maximumDrawerWidth;
|
|
521
|
+
initialFrame.size.width = maximumDrawerWidth;
|
|
522
|
+
|
|
523
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
524
|
+
drawerFrame.origin.x = 0; // Final position
|
|
525
|
+
|
|
526
|
+
if (self.openSide != drawerSide) {
|
|
527
|
+
initialFrame.origin.x = -maximumDrawerWidth; // Start off-screen
|
|
528
|
+
[sideDrawerViewController.view setFrame:initialFrame];
|
|
529
|
+
}
|
|
530
|
+
} else { // MMDrawerSideRight
|
|
531
|
+
CGFloat screenWidth = self.view.bounds.size.width;
|
|
532
|
+
drawerFrame.origin.x = screenWidth - maximumDrawerWidth; // Final position
|
|
533
|
+
|
|
534
|
+
if (self.openSide != drawerSide) {
|
|
535
|
+
initialFrame.origin.x = screenWidth; // Start off-screen
|
|
536
|
+
[sideDrawerViewController.view setFrame:initialFrame];
|
|
442
537
|
}
|
|
443
538
|
}
|
|
539
|
+
|
|
540
|
+
[self setupCenterContentOverlay];
|
|
541
|
+
[self.centerContainerView addSubview:self.centerContentOverlay];
|
|
542
|
+
[self.centerContainerView bringSubviewToFront:self.centerContentOverlay];
|
|
543
|
+
self.centerContentOverlay.alpha = 0.0; // Start transparent
|
|
544
|
+
|
|
545
|
+
// Make sure drawer is visible and in front
|
|
546
|
+
sideDrawerViewController.view.hidden = NO;
|
|
547
|
+
[self.childControllerContainerView bringSubviewToFront:sideDrawerViewController.view];
|
|
548
|
+
|
|
549
|
+
CGFloat distance = ABS(initialFrame.origin.x - drawerFrame.origin.x);
|
|
550
|
+
NSTimeInterval duration = [self animationDurationForDistance:distance velocity:velocity];
|
|
551
|
+
|
|
552
|
+
[UIView animateWithDuration:(animated ? duration : 0.0)
|
|
553
|
+
delay:0.0
|
|
554
|
+
options:options
|
|
555
|
+
animations:^{
|
|
556
|
+
[self setNeedsStatusBarAppearanceUpdateIfSupported];
|
|
557
|
+
[sideDrawerViewController.view setFrame:drawerFrame]; // Move to final position
|
|
558
|
+
self.centerContentOverlay.alpha = 0.5;
|
|
559
|
+
[self updateDrawerVisualStateForDrawerSide:drawerSide percentVisible:1.0];
|
|
560
|
+
}
|
|
561
|
+
completion:^(BOOL finished) {
|
|
562
|
+
[self completeDrawerOpeningForSide:drawerSide
|
|
563
|
+
sideDrawerViewController:sideDrawerViewController
|
|
564
|
+
finished:finished
|
|
565
|
+
completion:completion];
|
|
566
|
+
}];
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
- (void)openDrawerInPushMode:(UIViewController *)sideDrawerViewController
|
|
570
|
+
drawerSide:(MMDrawerSide)drawerSide
|
|
571
|
+
animated:(BOOL)animated
|
|
572
|
+
velocity:(CGFloat)velocity
|
|
573
|
+
animationOptions:(UIViewAnimationOptions)options
|
|
574
|
+
completion:(void (^)(BOOL finished))completion {
|
|
575
|
+
|
|
576
|
+
CGRect oldFrame = self.centerContainerView.frame;
|
|
577
|
+
CGRect newFrame = self.centerContainerView.frame;
|
|
578
|
+
|
|
579
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
580
|
+
newFrame.origin.x = self.maximumLeftDrawerWidth;
|
|
581
|
+
} else {
|
|
582
|
+
newFrame.origin.x = 0 - self.maximumRightDrawerWidth;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
CGFloat distance = ABS(CGRectGetMinX(oldFrame) - newFrame.origin.x);
|
|
586
|
+
NSTimeInterval duration = MAX(distance / ABS(velocity), MMDrawerMinimumAnimationDuration);
|
|
587
|
+
BOOL isGestureOpen = !CGRectIsNull(self.startingPanRect) && [self shouldStretchForSide:drawerSide];
|
|
588
|
+
sideDrawerViewController.view.hidden = NO;
|
|
589
|
+
|
|
590
|
+
[UIView animateWithDuration:(animated ? duration : 0.0)
|
|
591
|
+
delay:0.0
|
|
592
|
+
options:options
|
|
593
|
+
animations:^{
|
|
594
|
+
[self setNeedsStatusBarAppearanceUpdateIfSupported];
|
|
595
|
+
[self.centerContainerView setFrame:newFrame withLayoutAlpha:1.0];
|
|
596
|
+
[self updateDrawerVisualStateForDrawerSide:drawerSide percentVisible:1.0];
|
|
597
|
+
}
|
|
598
|
+
completion:^(BOOL finished) {
|
|
599
|
+
[self completeDrawerOpeningForSide:drawerSide
|
|
600
|
+
sideDrawerViewController:sideDrawerViewController
|
|
601
|
+
finished:finished
|
|
602
|
+
completion:^(BOOL innerFinished) {
|
|
603
|
+
|
|
604
|
+
if (isGestureOpen) {
|
|
605
|
+
[self applyBounceForDrawerSide:drawerSide];
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
if (completion) {
|
|
609
|
+
completion(innerFinished);
|
|
610
|
+
}
|
|
611
|
+
}];
|
|
612
|
+
}];
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
- (void)applyBounceForDrawerSide:(MMDrawerSide)drawerSide {
|
|
616
|
+
UIViewController *sideDrawerViewController = [self sideDrawerViewControllerForSide:drawerSide];
|
|
617
|
+
if (!sideDrawerViewController) return;
|
|
618
|
+
|
|
619
|
+
CGRect centerFrame = self.centerContainerView.frame;
|
|
620
|
+
CGRect bounceFrame = centerFrame;
|
|
621
|
+
CGFloat bounceAmount = 15.0;
|
|
622
|
+
|
|
623
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
624
|
+
bounceFrame.origin.x += bounceAmount;
|
|
625
|
+
} else {
|
|
626
|
+
bounceFrame.origin.x -= bounceAmount;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
CATransform3D originalTransform = sideDrawerViewController.view.layer.transform;
|
|
630
|
+
CGFloat scale = 1.0 + (bounceAmount / (drawerSide == MMDrawerSideLeft ?
|
|
631
|
+
self.maximumLeftDrawerWidth :
|
|
632
|
+
self.maximumRightDrawerWidth));
|
|
633
|
+
|
|
634
|
+
CATransform3D bounceTransform = CATransform3DMakeScale(scale, 1.0, 1.0);
|
|
635
|
+
|
|
636
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
637
|
+
bounceTransform = CATransform3DTranslate(bounceTransform,
|
|
638
|
+
self.maximumLeftDrawerWidth * (scale - 1.0) / 2.0,
|
|
639
|
+
0, 0);
|
|
640
|
+
} else {
|
|
641
|
+
bounceTransform = CATransform3DTranslate(bounceTransform,
|
|
642
|
+
-self.maximumRightDrawerWidth * (scale - 1.0) / 2.0,
|
|
643
|
+
0, 0);
|
|
644
|
+
}
|
|
645
|
+
[UIView animateWithDuration:0.15
|
|
646
|
+
delay:0.0
|
|
647
|
+
options:UIViewAnimationOptionCurveEaseOut
|
|
648
|
+
animations:^{
|
|
649
|
+
self.centerContainerView.frame = bounceFrame;
|
|
650
|
+
sideDrawerViewController.view.layer.transform = bounceTransform;
|
|
651
|
+
}
|
|
652
|
+
completion:^(BOOL bounceFinished) {
|
|
653
|
+
[UIView animateWithDuration:0.15
|
|
654
|
+
delay:0.0
|
|
655
|
+
options:UIViewAnimationOptionCurveEaseIn
|
|
656
|
+
animations:^{
|
|
657
|
+
self.centerContainerView.frame = centerFrame;
|
|
658
|
+
sideDrawerViewController.view.layer.transform = originalTransform;
|
|
659
|
+
}
|
|
660
|
+
completion:nil];
|
|
661
|
+
}];
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
- (void)completeDrawerOpeningForSide:(MMDrawerSide)drawerSide
|
|
665
|
+
sideDrawerViewController:(UIViewController *)sideDrawerViewController
|
|
666
|
+
finished:(BOOL)finished
|
|
667
|
+
completion:(void (^)(BOOL finished))completion {
|
|
668
|
+
|
|
669
|
+
// End the appearance transition if it already wasn't open.
|
|
670
|
+
if (drawerSide != self.openSide) {
|
|
671
|
+
[sideDrawerViewController endAppearanceTransition];
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
[self setOpenSide:drawerSide];
|
|
675
|
+
[self resetDrawerVisualStateForDrawerSide:drawerSide];
|
|
676
|
+
[self setAnimatingDrawer:NO];
|
|
677
|
+
|
|
678
|
+
if (completion) {
|
|
679
|
+
completion(finished);
|
|
680
|
+
}
|
|
444
681
|
}
|
|
445
682
|
|
|
446
683
|
#pragma mark - Updating the Center View Controller
|
|
@@ -801,7 +1038,7 @@ static NSString *MMDrawerOpenSideKey = @"MMDrawerOpenSide";
|
|
|
801
1038
|
[super viewDidLoad];
|
|
802
1039
|
|
|
803
1040
|
[self.view setBackgroundColor:[UIColor blackColor]];
|
|
804
|
-
|
|
1041
|
+
[self.view setAccessibilityIdentifier:@"SideMenuContainer"];
|
|
805
1042
|
[self setupGestureRecognizers];
|
|
806
1043
|
}
|
|
807
1044
|
|
|
@@ -1070,6 +1307,16 @@ static NSString *MMDrawerOpenSideKey = @"MMDrawerOpenSide";
|
|
|
1070
1307
|
[self.dummyStatusBarView setBackgroundColor:_statusBarViewBackgroundColor];
|
|
1071
1308
|
}
|
|
1072
1309
|
|
|
1310
|
+
- (void)setLeftDrawerOpenMode:(MMDrawerOpenMode)openMode {
|
|
1311
|
+
if (self.openSide == MMDrawerSideLeft) return;
|
|
1312
|
+
_leftDrawerOpenMode = openMode;
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
- (void)setRightDrawerOpenMode:(MMDrawerOpenMode)openMode {
|
|
1316
|
+
if (self.openSide == MMDrawerSideRight) return;
|
|
1317
|
+
_rightDrawerOpenMode = openMode;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1073
1320
|
- (void)setAnimatingDrawer:(BOOL)animatingDrawer {
|
|
1074
1321
|
_animatingDrawer = animatingDrawer;
|
|
1075
1322
|
[self.view setUserInteractionEnabled:!animatingDrawer];
|
|
@@ -1085,6 +1332,7 @@ static NSString *MMDrawerOpenSideKey = @"MMDrawerOpenSide";
|
|
|
1085
1332
|
[self updatePanHandlersState];
|
|
1086
1333
|
}
|
|
1087
1334
|
|
|
1335
|
+
|
|
1088
1336
|
#pragma mark - Getters
|
|
1089
1337
|
- (CGFloat)maximumLeftDrawerWidth {
|
|
1090
1338
|
if (self.leftDrawerViewController) {
|
|
@@ -1155,107 +1403,420 @@ static NSString *MMDrawerOpenSideKey = @"MMDrawerOpenSide";
|
|
|
1155
1403
|
return _statusBarViewBackgroundColor;
|
|
1156
1404
|
}
|
|
1157
1405
|
|
|
1406
|
+
- (MMDrawerOpenMode)rightDrawerOpenMode {
|
|
1407
|
+
return _rightDrawerOpenMode;
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
- (MMDrawerOpenMode)leftDrawerOpenMode {
|
|
1411
|
+
return _leftDrawerOpenMode;
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1158
1414
|
#pragma mark - Gesture Handlers
|
|
1159
1415
|
|
|
1160
1416
|
- (void)tapGestureCallback:(UITapGestureRecognizer *)tapGesture {
|
|
1161
1417
|
if (self.openSide != MMDrawerSideNone && self.isAnimatingDrawer == NO) {
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1418
|
+
// Get the tap location
|
|
1419
|
+
CGPoint tapLocation = [tapGesture locationInView:self.childControllerContainerView];
|
|
1420
|
+
|
|
1421
|
+
// Get the open drawer view controller
|
|
1422
|
+
UIViewController *sideDrawerViewController = [self sideDrawerViewControllerForSide:self.openSide];
|
|
1423
|
+
|
|
1424
|
+
// Check if we are in above content mode
|
|
1425
|
+
MMDrawerOpenMode openMode = [self getDrawerOpenMode:self.openSide];
|
|
1426
|
+
|
|
1427
|
+
// Only close if not tapping on the drawer itself in above content mode
|
|
1428
|
+
BOOL shouldClose = YES;
|
|
1429
|
+
|
|
1430
|
+
if (openMode == MMDrawerOpenModeAboveContent && sideDrawerViewController) {
|
|
1431
|
+
// Check if tap is inside the drawer view
|
|
1432
|
+
CGPoint tapInDrawerView = [tapGesture locationInView:sideDrawerViewController.view];
|
|
1433
|
+
if (CGRectContainsPoint(sideDrawerViewController.view.bounds, tapInDrawerView)) {
|
|
1434
|
+
shouldClose = NO;
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
if (shouldClose) {
|
|
1439
|
+
[self closeDrawerAnimated:YES
|
|
1440
|
+
completion:^(BOOL finished) {
|
|
1441
|
+
if (self.gestureCompletion) {
|
|
1442
|
+
self.gestureCompletion(self, tapGesture);
|
|
1443
|
+
}
|
|
1444
|
+
}];
|
|
1445
|
+
}
|
|
1168
1446
|
}
|
|
1169
1447
|
}
|
|
1170
1448
|
|
|
1171
1449
|
- (void)panGestureCallback:(UIPanGestureRecognizer *)panGesture {
|
|
1172
1450
|
switch (panGesture.state) {
|
|
1173
|
-
case UIGestureRecognizerStateBegan:
|
|
1174
|
-
|
|
1175
|
-
|
|
1451
|
+
case UIGestureRecognizerStateBegan:
|
|
1452
|
+
[self handlePanGestureBegan:panGesture];
|
|
1453
|
+
break;
|
|
1454
|
+
case UIGestureRecognizerStateChanged:
|
|
1455
|
+
[self handlePanGestureChanged:panGesture];
|
|
1456
|
+
break;
|
|
1457
|
+
case UIGestureRecognizerStateEnded:
|
|
1458
|
+
case UIGestureRecognizerStateCancelled:
|
|
1459
|
+
[self handlePanGestureEnded:panGesture];
|
|
1460
|
+
break;
|
|
1461
|
+
default:
|
|
1462
|
+
break;
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
- (void)handlePanGestureBegan:(UIPanGestureRecognizer *)panGesture {
|
|
1467
|
+
if (self.gestureStart) {
|
|
1468
|
+
self.gestureStart(self, panGesture);
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
if (self.animatingDrawer) {
|
|
1472
|
+
[panGesture setEnabled:NO];
|
|
1473
|
+
return;
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
MMDrawerSide drawerSide = [self determineDrawerSideForPanGesture:panGesture];
|
|
1477
|
+
if (drawerSide == MMDrawerSideNone) {
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
MMDrawerOpenMode openMode = [self getDrawerOpenMode:drawerSide];
|
|
1482
|
+
if (openMode == MMDrawerOpenModeAboveContent) {
|
|
1483
|
+
[self setupPanningStartFrameOverlayMode:drawerSide];
|
|
1484
|
+
} else {
|
|
1485
|
+
[self setupPanningStartFramePushMode];
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
- (MMDrawerSide)determineDrawerSideForPanGesture:(UIPanGestureRecognizer *)panGesture {
|
|
1490
|
+
MMDrawerSide drawerSide = self.openSide;
|
|
1491
|
+
|
|
1492
|
+
if (drawerSide == MMDrawerSideNone) {
|
|
1493
|
+
CGPoint velocity = [panGesture velocityInView:self.view];
|
|
1494
|
+
drawerSide = (velocity.x > 0) ? MMDrawerSideLeft : MMDrawerSideRight;
|
|
1495
|
+
|
|
1496
|
+
if ((drawerSide == MMDrawerSideLeft && !_leftSideEnabled) ||
|
|
1497
|
+
(drawerSide == MMDrawerSideRight && !_rightSideEnabled)) {
|
|
1498
|
+
drawerSide = (drawerSide == MMDrawerSideLeft) ? MMDrawerSideRight : MMDrawerSideLeft;
|
|
1499
|
+
|
|
1500
|
+
if ((drawerSide == MMDrawerSideLeft && !_leftSideEnabled) ||
|
|
1501
|
+
(drawerSide == MMDrawerSideRight && !_rightSideEnabled)) {
|
|
1502
|
+
return MMDrawerSideNone;
|
|
1503
|
+
}
|
|
1176
1504
|
}
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1505
|
+
}
|
|
1506
|
+
return drawerSide;
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
- (void)setupPanningStartFrameOverlayMode:(MMDrawerSide)drawerSide {
|
|
1510
|
+
UIViewController *drawerViewController = [self sideDrawerViewControllerForSide:drawerSide];
|
|
1511
|
+
|
|
1512
|
+
// If drawer is closed, set up initial position
|
|
1513
|
+
if (self.openSide == MMDrawerSideNone) {
|
|
1514
|
+
self.startingPanRect =
|
|
1515
|
+
[self calcClosedDrawerPanStartFrameInOverlay:drawerSide
|
|
1516
|
+
drawerViewController:(UIViewController *)drawerViewController];
|
|
1517
|
+
|
|
1518
|
+
[drawerViewController.view setFrame:self.startingPanRect];
|
|
1519
|
+
|
|
1520
|
+
// Ensure drawer is visible and in front
|
|
1521
|
+
drawerViewController.view.hidden = NO;
|
|
1522
|
+
[self.childControllerContainerView bringSubviewToFront:drawerViewController.view];
|
|
1523
|
+
} else {
|
|
1524
|
+
self.startingPanRect = drawerViewController.view.frame;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
// Save for upcoming gesture updates in above-content mode
|
|
1528
|
+
self.panDrawerSide = drawerSide;
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
- (void)setupPanningStartFramePushMode {
|
|
1532
|
+
self.startingPanRect = self.centerContainerView.frame;
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
- (CGRect)calcClosedDrawerPanStartFrameInOverlay:(MMDrawerSide)drawerSide
|
|
1536
|
+
drawerViewController:(UIViewController *)drawerViewController {
|
|
1537
|
+
CGRect drawerFrame = drawerViewController.view.frame;
|
|
1538
|
+
CGFloat maximumDrawerWidth = [self maximumDrawerWidthForSide:drawerSide];
|
|
1539
|
+
|
|
1540
|
+
drawerFrame.size.width = maximumDrawerWidth;
|
|
1541
|
+
|
|
1542
|
+
// Position off-screen based on side
|
|
1543
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
1544
|
+
drawerFrame.origin.x = -maximumDrawerWidth;
|
|
1545
|
+
} else {
|
|
1546
|
+
drawerFrame.origin.x = self.view.bounds.size.width;
|
|
1547
|
+
}
|
|
1548
|
+
return drawerFrame;
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
- (void)handlePanGestureChanged:(UIPanGestureRecognizer *)panGesture {
|
|
1552
|
+
self.view.userInteractionEnabled = NO;
|
|
1553
|
+
|
|
1554
|
+
MMDrawerSide drawerSide = self.panDrawerSide;
|
|
1555
|
+
MMDrawerOpenMode openMode = [self getDrawerOpenMode:drawerSide];
|
|
1556
|
+
if (openMode == MMDrawerOpenModeAboveContent) {
|
|
1557
|
+
[self handlePanGestureChangedOverlayMode:panGesture forDrawerSide:drawerSide];
|
|
1558
|
+
} else {
|
|
1559
|
+
[self handlePanGestureChangedPushMode:panGesture];
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
- (void)handlePanGestureChangedOverlayMode:(UIPanGestureRecognizer *)panGesture
|
|
1564
|
+
forDrawerSide:(MMDrawerSide)drawerSide {
|
|
1565
|
+
|
|
1566
|
+
UIViewController *drawerViewController = [self sideDrawerViewControllerForSide:drawerSide];
|
|
1567
|
+
if (!drawerViewController) {
|
|
1568
|
+
return;
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
CGFloat maximumDrawerWidth = [self maximumDrawerWidthForSide:drawerSide];
|
|
1572
|
+
CGPoint translatedPoint = [panGesture translationInView:self.view];
|
|
1573
|
+
|
|
1574
|
+
CGRect newFrame = [self calculateNewFrameForOverlayDrawer:drawerViewController
|
|
1575
|
+
withTranslation:translatedPoint
|
|
1576
|
+
forDrawerSide:drawerSide
|
|
1577
|
+
maximumDrawerWidth:maximumDrawerWidth];
|
|
1578
|
+
|
|
1579
|
+
CGFloat percentVisible = [self calculatePercentVisibleForOverlayDrawer:drawerSide
|
|
1580
|
+
withFrame:newFrame
|
|
1581
|
+
maximumDrawerWidth:maximumDrawerWidth];
|
|
1582
|
+
|
|
1583
|
+
// Handle overlay
|
|
1584
|
+
[self updateOverlayWithPercentVisible:percentVisible];
|
|
1585
|
+
|
|
1586
|
+
MMDrawerSide visibleSide = (percentVisible > 0.01) ? drawerSide : MMDrawerSideNone;
|
|
1587
|
+
|
|
1588
|
+
[self updateAppearanceTransitions:self.openSide toSide:visibleSide];
|
|
1589
|
+
|
|
1590
|
+
// Apply new frame
|
|
1591
|
+
drawerViewController.view.frame = newFrame;
|
|
1592
|
+
[self.childControllerContainerView bringSubviewToFront:drawerViewController.view];
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
- (CGRect)calculateNewFrameForOverlayDrawer:(UIViewController *)drawerViewController
|
|
1596
|
+
withTranslation:(CGPoint)translatedPoint
|
|
1597
|
+
forDrawerSide:(MMDrawerSide)drawerSide
|
|
1598
|
+
maximumDrawerWidth:(CGFloat)maximumDrawerWidth {
|
|
1599
|
+
CGRect newFrame = drawerViewController.view.frame;
|
|
1600
|
+
if (self.openSide == drawerSide) {
|
|
1601
|
+
// If drawer is already open, adjust from starting position
|
|
1602
|
+
newFrame.origin.x = self.startingPanRect.origin.x + translatedPoint.x;
|
|
1603
|
+
} else {
|
|
1604
|
+
// If drawer is closed, calculate from off-screen position
|
|
1605
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
1606
|
+
newFrame.origin.x = -maximumDrawerWidth + translatedPoint.x;
|
|
1180
1607
|
} else {
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
}
|
|
1184
|
-
case UIGestureRecognizerStateChanged: {
|
|
1185
|
-
self.view.userInteractionEnabled = NO;
|
|
1186
|
-
CGRect newFrame = self.startingPanRect;
|
|
1187
|
-
CGPoint translatedPoint = [panGesture translationInView:self.centerContainerView];
|
|
1188
|
-
newFrame.origin.x =
|
|
1189
|
-
[self roundedOriginXForDrawerConstriants:CGRectGetMinX(self.startingPanRect) +
|
|
1190
|
-
translatedPoint.x];
|
|
1191
|
-
newFrame = CGRectIntegral(newFrame);
|
|
1192
|
-
CGFloat xOffset = newFrame.origin.x;
|
|
1193
|
-
|
|
1194
|
-
MMDrawerSide visibleSide = MMDrawerSideNone;
|
|
1195
|
-
CGFloat percentVisible = 0.0;
|
|
1196
|
-
if (xOffset > 0) {
|
|
1197
|
-
visibleSide = MMDrawerSideLeft;
|
|
1198
|
-
percentVisible = xOffset / self.maximumLeftDrawerWidth;
|
|
1199
|
-
} else if (xOffset < 0) {
|
|
1200
|
-
visibleSide = MMDrawerSideRight;
|
|
1201
|
-
percentVisible = ABS(xOffset) / self.maximumRightDrawerWidth;
|
|
1202
|
-
}
|
|
1203
|
-
|
|
1204
|
-
if ((!_leftSideEnabled && visibleSide == MMDrawerSideLeft) ||
|
|
1205
|
-
(!_rightSideEnabled && visibleSide == MMDrawerSideRight)) {
|
|
1206
|
-
return;
|
|
1608
|
+
CGFloat screenWidth = self.view.bounds.size.width;
|
|
1609
|
+
newFrame.origin.x = screenWidth + translatedPoint.x;
|
|
1207
1610
|
}
|
|
1611
|
+
}
|
|
1208
1612
|
|
|
1209
|
-
|
|
1210
|
-
|
|
1613
|
+
// Apply constraints based on drawer side
|
|
1614
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
1615
|
+
newFrame.origin.x = MIN(0, newFrame.origin.x);
|
|
1616
|
+
newFrame.origin.x = MAX(-maximumDrawerWidth, newFrame.origin.x);
|
|
1617
|
+
} else {
|
|
1618
|
+
CGFloat screenWidth = self.view.bounds.size.width;
|
|
1619
|
+
newFrame.origin.x = MAX(screenWidth - maximumDrawerWidth, newFrame.origin.x);
|
|
1620
|
+
newFrame.origin.x = MIN(screenWidth, newFrame.origin.x);
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
return newFrame;
|
|
1624
|
+
}
|
|
1211
1625
|
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1626
|
+
- (CGFloat)calculatePercentVisibleForOverlayDrawer:(MMDrawerSide)drawerSide
|
|
1627
|
+
withFrame:(CGRect)frame
|
|
1628
|
+
maximumDrawerWidth:(CGFloat)maximumDrawerWidth {
|
|
1629
|
+
CGFloat percentVisible;
|
|
1630
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
1631
|
+
percentVisible = (maximumDrawerWidth + frame.origin.x) / maximumDrawerWidth;
|
|
1632
|
+
} else {
|
|
1633
|
+
CGFloat rightEdge = self.view.bounds.size.width;
|
|
1634
|
+
percentVisible = (rightEdge - frame.origin.x) / maximumDrawerWidth;
|
|
1635
|
+
}
|
|
1636
|
+
return MAX(0, MIN(1.0, percentVisible));
|
|
1637
|
+
}
|
|
1218
1638
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1639
|
+
- (void)updateOverlayWithPercentVisible:(CGFloat)percentVisible {
|
|
1640
|
+
[self setupCenterContentOverlay];
|
|
1641
|
+
if (self.centerContentOverlay.superview != self.centerContainerView) {
|
|
1642
|
+
[self.centerContainerView addSubview:self.centerContentOverlay];
|
|
1643
|
+
[self.centerContainerView bringSubviewToFront:self.centerContentOverlay];
|
|
1644
|
+
}
|
|
1645
|
+
self.centerContentOverlay.alpha = percentVisible * 0.5;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
- (void)updateAppearanceTransitions:(MMDrawerSide)fromSide toSide:(MMDrawerSide)toSide {
|
|
1649
|
+
if (fromSide != toSide) {
|
|
1650
|
+
if (fromSide != MMDrawerSideNone) {
|
|
1651
|
+
UIViewController *sideDrawerVC = [self sideDrawerViewControllerForSide:fromSide];
|
|
1652
|
+
[sideDrawerVC beginAppearanceTransition:NO animated:NO];
|
|
1653
|
+
[sideDrawerVC endAppearanceTransition];
|
|
1225
1654
|
}
|
|
1226
1655
|
|
|
1227
|
-
|
|
1656
|
+
if (toSide != MMDrawerSideNone) {
|
|
1657
|
+
[self prepareToPresentDrawer:toSide animated:NO];
|
|
1658
|
+
UIViewController *visibleDrawerVC = [self sideDrawerViewControllerForSide:toSide];
|
|
1659
|
+
[visibleDrawerVC endAppearanceTransition];
|
|
1660
|
+
}
|
|
1228
1661
|
|
|
1229
|
-
[self
|
|
1230
|
-
|
|
1662
|
+
[self setOpenSide:toSide];
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1231
1665
|
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
self.centerContainerView.frame = newFrame;
|
|
1666
|
+
- (void)handlePanGestureChangedPushMode:(UIPanGestureRecognizer *)panGesture {
|
|
1667
|
+
CGRect newFrame = self.startingPanRect;
|
|
1668
|
+
CGPoint translatedPoint = [panGesture translationInView:self.centerContainerView];
|
|
1236
1669
|
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1670
|
+
newFrame.origin.x = [self
|
|
1671
|
+
roundedOriginXForDrawerConstriants:CGRectGetMinX(self.startingPanRect) + translatedPoint.x];
|
|
1672
|
+
newFrame = CGRectIntegral(newFrame);
|
|
1673
|
+
CGFloat xOffset = newFrame.origin.x;
|
|
1240
1674
|
|
|
1241
|
-
|
|
1675
|
+
MMDrawerSide visibleSide = MMDrawerSideNone;
|
|
1676
|
+
CGFloat percentVisible = 0.0;
|
|
1677
|
+
if (xOffset > 0) {
|
|
1678
|
+
visibleSide = MMDrawerSideLeft;
|
|
1679
|
+
percentVisible = xOffset / self.maximumLeftDrawerWidth;
|
|
1680
|
+
} else if (xOffset < 0) {
|
|
1681
|
+
visibleSide = MMDrawerSideRight;
|
|
1682
|
+
percentVisible = ABS(xOffset) / self.maximumRightDrawerWidth;
|
|
1242
1683
|
}
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
[self finishAnimationForPanGestureWithXVelocity:velocity.x
|
|
1248
|
-
completion:^(BOOL finished) {
|
|
1249
|
-
if (self.gestureCompletion) {
|
|
1250
|
-
self.gestureCompletion(self, panGesture);
|
|
1251
|
-
}
|
|
1252
|
-
}];
|
|
1253
|
-
self.view.userInteractionEnabled = YES;
|
|
1254
|
-
break;
|
|
1684
|
+
|
|
1685
|
+
if ((!_leftSideEnabled && visibleSide == MMDrawerSideLeft) ||
|
|
1686
|
+
(!_rightSideEnabled && visibleSide == MMDrawerSideRight)) {
|
|
1687
|
+
return;
|
|
1255
1688
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1689
|
+
|
|
1690
|
+
[self handleAppearanceTransitionPushMode:visibleSide];
|
|
1691
|
+
[self updateDrawerVisualStateForDrawerSide:visibleSide percentVisible:percentVisible];
|
|
1692
|
+
[self.centerContainerView
|
|
1693
|
+
setCenter:CGPointMake(CGRectGetMidX(newFrame), CGRectGetMidY(newFrame))];
|
|
1694
|
+
|
|
1695
|
+
newFrame = self.centerContainerView.frame;
|
|
1696
|
+
newFrame.origin.x = floor(newFrame.origin.x);
|
|
1697
|
+
newFrame.origin.y = floor(newFrame.origin.y);
|
|
1698
|
+
self.centerContainerView.frame = newFrame;
|
|
1699
|
+
|
|
1700
|
+
[self.centerContainerView addSubview:self.centerContainerView.overlayView];
|
|
1701
|
+
[self.centerContainerView bringSubviewToFront:self.centerContainerView.overlayView];
|
|
1702
|
+
self.centerContainerView.overlayView.alpha = percentVisible;
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
- (void)handleAppearanceTransitionPushMode:(MMDrawerSide)visibleSide {
|
|
1706
|
+
UIViewController *visibleSideDrawerViewController = [self sideDrawerViewControllerForSide:visibleSide];
|
|
1707
|
+
|
|
1708
|
+
if (self.openSide != visibleSide) {
|
|
1709
|
+
// Handle disappearing the visible drawer
|
|
1710
|
+
UIViewController *sideDrawerVC = [self sideDrawerViewControllerForSide:self.openSide];
|
|
1711
|
+
[sideDrawerVC beginAppearanceTransition:NO animated:NO];
|
|
1712
|
+
[sideDrawerVC endAppearanceTransition];
|
|
1713
|
+
|
|
1714
|
+
// Drawer is about to become visible
|
|
1715
|
+
[self prepareToPresentDrawer:visibleSide animated:NO];
|
|
1716
|
+
[visibleSideDrawerViewController endAppearanceTransition];
|
|
1717
|
+
[self setOpenSide:visibleSide];
|
|
1718
|
+
} else if (visibleSide == MMDrawerSideNone) {
|
|
1719
|
+
[self setOpenSide:MMDrawerSideNone];
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
- (void)handlePanGestureEnded:(UIPanGestureRecognizer *)panGesture {
|
|
1724
|
+
MMDrawerSide drawerSide = self.panDrawerSide;
|
|
1725
|
+
MMDrawerOpenMode openMode = [self getDrawerOpenMode:drawerSide];
|
|
1726
|
+
|
|
1727
|
+
if (openMode == MMDrawerOpenModeAboveContent) {
|
|
1728
|
+
[self completePanningOverlayMode:drawerSide withPanGesture:panGesture];
|
|
1729
|
+
} else {
|
|
1730
|
+
[self completePanningPushMode:panGesture];
|
|
1258
1731
|
}
|
|
1732
|
+
|
|
1733
|
+
self.startingPanRect = CGRectNull;
|
|
1734
|
+
self.view.userInteractionEnabled = YES;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
- (void)completePanningOverlayMode:(MMDrawerSide)drawerSide
|
|
1738
|
+
withPanGesture:(UIPanGestureRecognizer *)panGesture {
|
|
1739
|
+
// Get drawer view controller
|
|
1740
|
+
UIViewController *drawerVC = [self sideDrawerViewControllerForSide:drawerSide];
|
|
1741
|
+
if (!drawerVC) {
|
|
1742
|
+
self.panDrawerSide = MMDrawerSideNone;
|
|
1743
|
+
return;
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
BOOL shouldOpen = [self shouldOpenDrawerForGestureEnd:panGesture withDrawerSide:drawerSide andCurrentPosition:drawerVC.view.frame.origin.x];
|
|
1747
|
+
[self animateOverlayDrawerToFinalState:shouldOpen forDrawerSide:drawerSide withDrawerVC:drawerVC andPanGesture:panGesture];
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
- (BOOL)shouldOpenDrawerForGestureEnd:(UIPanGestureRecognizer *)panGesture withDrawerSide:(MMDrawerSide)drawerSide andCurrentPosition:(CGFloat)currentX {
|
|
1751
|
+
CGPoint velocity = [panGesture velocityInView:self.view];
|
|
1752
|
+
CGFloat maximumDrawerWidth = [self maximumDrawerWidthForSide:drawerSide];
|
|
1753
|
+
CGFloat screenWidth = self.view.bounds.size.width;
|
|
1754
|
+
BOOL shouldOpen = NO;
|
|
1755
|
+
|
|
1756
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
1757
|
+
if (velocity.x > 500) shouldOpen = YES; // Fast right swipe
|
|
1758
|
+
else if (velocity.x < -500) shouldOpen = NO; // Fast left swipe
|
|
1759
|
+
else shouldOpen = (currentX > -maximumDrawerWidth/2.0); // Based on position
|
|
1760
|
+
} else {
|
|
1761
|
+
if (velocity.x < -500) shouldOpen = YES; // Fast left swipe
|
|
1762
|
+
else if (velocity.x > 500) shouldOpen = NO; // Fast right swipe
|
|
1763
|
+
else shouldOpen = (currentX < screenWidth - maximumDrawerWidth/2.0); // Based on position
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
return shouldOpen;
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
- (void)animateOverlayDrawerToFinalState:(BOOL)shouldOpen forDrawerSide:(MMDrawerSide)drawerSide withDrawerVC:(UIViewController *)drawerVC andPanGesture:(UIPanGestureRecognizer *)panGesture {
|
|
1770
|
+
CGFloat maximumDrawerWidth = [self maximumDrawerWidthForSide:drawerSide];
|
|
1771
|
+
CGFloat screenWidth = self.view.bounds.size.width;
|
|
1772
|
+
|
|
1773
|
+
[UIView animateWithDuration:0.25
|
|
1774
|
+
animations:^{
|
|
1775
|
+
CGRect frame = drawerVC.view.frame;
|
|
1776
|
+
|
|
1777
|
+
if (shouldOpen) {
|
|
1778
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
1779
|
+
frame.origin.x = 0;
|
|
1780
|
+
} else {
|
|
1781
|
+
frame.origin.x = screenWidth - maximumDrawerWidth;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
self.centerContentOverlay.alpha = 0.5;
|
|
1785
|
+
} else {
|
|
1786
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
1787
|
+
frame.origin.x = -maximumDrawerWidth;
|
|
1788
|
+
} else {
|
|
1789
|
+
frame.origin.x = screenWidth;
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
self.centerContentOverlay.alpha = 0.0;
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
drawerVC.view.frame = frame;
|
|
1796
|
+
} completion:^(BOOL finished) {
|
|
1797
|
+
if (shouldOpen) {
|
|
1798
|
+
[self setOpenSide:drawerSide];
|
|
1799
|
+
} else {
|
|
1800
|
+
[self setOpenSide:MMDrawerSideNone];
|
|
1801
|
+
[self.centerContentOverlay removeFromSuperview];
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
self.panDrawerSide = MMDrawerSideNone;
|
|
1805
|
+
|
|
1806
|
+
if (self.gestureCompletion) {
|
|
1807
|
+
self.gestureCompletion(self, panGesture);
|
|
1808
|
+
}
|
|
1809
|
+
}];
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
- (void)completePanningPushMode:(UIPanGestureRecognizer *)panGesture {
|
|
1813
|
+
CGPoint velocity = [panGesture velocityInView:self.childControllerContainerView];
|
|
1814
|
+
[self finishAnimationForPanGestureWithXVelocity:velocity.x
|
|
1815
|
+
completion:^(BOOL finished) {
|
|
1816
|
+
if (self.gestureCompletion) {
|
|
1817
|
+
self.gestureCompletion(self, panGesture);
|
|
1818
|
+
}
|
|
1819
|
+
}];
|
|
1259
1820
|
}
|
|
1260
1821
|
|
|
1261
1822
|
- (void)updatePanHandlersState {
|
|
@@ -1270,6 +1831,29 @@ static NSString *MMDrawerOpenSideKey = @"MMDrawerOpenSide";
|
|
|
1270
1831
|
}
|
|
1271
1832
|
}
|
|
1272
1833
|
|
|
1834
|
+
- (void)setupCenterContentOverlay {
|
|
1835
|
+
if (!self.centerContentOverlay) {
|
|
1836
|
+
// Create overlay view if it doesn't exist
|
|
1837
|
+
self.centerContentOverlay = [[UIView alloc] initWithFrame:self.centerContainerView.bounds];
|
|
1838
|
+
self.centerContentOverlay.backgroundColor = [UIColor blackColor];
|
|
1839
|
+
self.centerContentOverlay.alpha = 0.0; // Start fully transparent
|
|
1840
|
+
self.centerContentOverlay.userInteractionEnabled = YES;
|
|
1841
|
+
|
|
1842
|
+
// Add tap gesture to close drawer when tapping overlay
|
|
1843
|
+
UITapGestureRecognizer *tapGesture =
|
|
1844
|
+
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(overlayTapped:)];
|
|
1845
|
+
[self.centerContentOverlay addGestureRecognizer:tapGesture];
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
// Update frame to match current center container bounds
|
|
1849
|
+
self.centerContentOverlay.frame = self.centerContainerView.bounds;
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
- (void)overlayTapped:(UITapGestureRecognizer *)tapGesture {
|
|
1853
|
+
// Close drawer when overlay is tapped
|
|
1854
|
+
[self closeDrawerAnimated:YES completion:nil];
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1273
1857
|
#pragma mark - iOS 7 Status Bar Helpers
|
|
1274
1858
|
- (UIViewController *)childViewControllerForStatusBarStyle {
|
|
1275
1859
|
return [self childViewControllerForSide:self.openSide];
|
|
@@ -1367,23 +1951,46 @@ static NSString *MMDrawerOpenSideKey = @"MMDrawerOpenSide";
|
|
|
1367
1951
|
}
|
|
1368
1952
|
}
|
|
1369
1953
|
|
|
1954
|
+
- (void)side:(MMDrawerSide)drawerSide openMode:(MMDrawerOpenMode)openMode {
|
|
1955
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
1956
|
+
self.leftDrawerOpenMode = openMode;
|
|
1957
|
+
} else if (drawerSide == MMDrawerSideRight) {
|
|
1958
|
+
self.rightDrawerOpenMode = openMode;
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1370
1962
|
- (void)applyOvershootScaleTransformForDrawerSide:(MMDrawerSide)drawerSide
|
|
1371
1963
|
percentVisible:(CGFloat)percentVisible {
|
|
1372
|
-
|
|
1373
1964
|
if (percentVisible >= 1.f) {
|
|
1374
1965
|
CATransform3D transform = CATransform3DIdentity;
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
transform,
|
|
1966
|
+
|
|
1967
|
+
MMDrawerOpenMode openMode = [self getDrawerOpenMode:drawerSide];
|
|
1968
|
+
UIViewController *sideDrawerViewController = [self sideDrawerViewControllerForSide:drawerSide];
|
|
1969
|
+
|
|
1970
|
+
if (openMode == MMDrawerOpenModePushContent) {
|
|
1971
|
+
CGFloat stretchFactor = MIN(percentVisible, 1.1);
|
|
1972
|
+
|
|
1973
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
1974
|
+
transform = CATransform3DMakeScale(stretchFactor, 1.f, 1.f);
|
|
1975
|
+
transform = CATransform3DTranslate(transform, self.maximumLeftDrawerWidth * (stretchFactor - 1.f) / 2, 0.f, 0.f);
|
|
1976
|
+
} else if (drawerSide == MMDrawerSideRight) {
|
|
1977
|
+
transform = CATransform3DMakeScale(stretchFactor, 1.f, 1.f);
|
|
1978
|
+
transform = CATransform3DTranslate(transform, -self.maximumRightDrawerWidth * (stretchFactor - 1.f) / 2, 0.f, 0.f);
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
sideDrawerViewController.view.layer.transform = transform;
|
|
1982
|
+
}
|
|
1983
|
+
else if (openMode == MMDrawerOpenModeAboveContent) {
|
|
1984
|
+
if (drawerSide == MMDrawerSideLeft) {
|
|
1985
|
+
transform = CATransform3DMakeScale(percentVisible, 1.f, 1.f);
|
|
1986
|
+
transform = CATransform3DTranslate(transform, self.maximumLeftDrawerWidth * (percentVisible - 1.f) / 2, 0.f, 0.f);
|
|
1987
|
+
} else if (drawerSide == MMDrawerSideRight) {
|
|
1988
|
+
transform = CATransform3DMakeScale(percentVisible, 1.f, 1.f);
|
|
1989
|
+
transform = CATransform3DTranslate(transform, -self.maximumRightDrawerWidth * (percentVisible - 1.f) / 2, 0.f, 0.f);
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
sideDrawerViewController.view.layer.transform = transform;
|
|
1385
1993
|
}
|
|
1386
|
-
sideDrawerViewController.view.layer.transform = transform;
|
|
1387
1994
|
}
|
|
1388
1995
|
}
|
|
1389
1996
|
|
|
@@ -1679,4 +2286,18 @@ static inline CGFloat originXForDrawerOriginAndTargetOriginOffset(CGFloat origin
|
|
|
1679
2286
|
return (CGRectContainsPoint(rightBezelRect, point) &&
|
|
1680
2287
|
[self isPointContainedWithinCenterViewContentRect:point]);
|
|
1681
2288
|
}
|
|
2289
|
+
|
|
2290
|
+
- (MMDrawerOpenMode)getDrawerOpenMode:(MMDrawerSide)drawerSide {
|
|
2291
|
+
return (drawerSide == MMDrawerSideLeft) ? self.leftDrawerOpenMode : self.rightDrawerOpenMode;
|
|
2292
|
+
}
|
|
2293
|
+
|
|
2294
|
+
- (CGFloat)maximumDrawerWidthForSide:(MMDrawerSide)drawerSide {
|
|
2295
|
+
return (drawerSide == MMDrawerSideLeft) ? self.maximumLeftDrawerWidth : self.maximumRightDrawerWidth;
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2298
|
+
// Helper method to calculate animation duration based on distance and velocity
|
|
2299
|
+
- (NSTimeInterval)animationDurationForDistance:(CGFloat)distance velocity:(CGFloat)velocity {
|
|
2300
|
+
return MAX(distance / ABS(velocity), MMDrawerMinimumAnimationDuration);
|
|
2301
|
+
}
|
|
2302
|
+
|
|
1682
2303
|
@end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#import "RNNSideMenuPresenter.h"
|
|
2
2
|
#import "RNNSideMenuController.h"
|
|
3
|
+
#import "RNNSideMenuSideOptions.h"
|
|
3
4
|
|
|
4
5
|
@implementation RNNSideMenuPresenter
|
|
5
6
|
|
|
@@ -52,6 +53,20 @@
|
|
|
52
53
|
|
|
53
54
|
[self.sideMenuController.view
|
|
54
55
|
setBackgroundColor:[withDefault.layout.backgroundColor withDefault:nil]];
|
|
56
|
+
|
|
57
|
+
MMDrawerOpenMode openModeLeft = MMDrawerOpenModePushContent; // Default value
|
|
58
|
+
if (withDefault.sideMenu.left.openMode.hasValue) {
|
|
59
|
+
NSString *openModeString = withDefault.sideMenu.left.openMode.get;
|
|
60
|
+
openModeLeft = MMDrawerOpenModeFromString(openModeString);
|
|
61
|
+
}
|
|
62
|
+
[self.sideMenuController side:MMDrawerSideLeft openMode:openModeLeft];
|
|
63
|
+
|
|
64
|
+
MMDrawerOpenMode openModeRight = MMDrawerOpenModePushContent; // Default value
|
|
65
|
+
if (withDefault.sideMenu.right.openMode.hasValue) {
|
|
66
|
+
NSString *openModeString = withDefault.sideMenu.right.openMode.get;
|
|
67
|
+
openModeRight = MMDrawerOpenModeFromString(openModeString);
|
|
68
|
+
}
|
|
69
|
+
[self.sideMenuController side:MMDrawerSideRight openMode:openModeRight];
|
|
55
70
|
}
|
|
56
71
|
|
|
57
72
|
- (void)applyOptionsOnInit:(RNNNavigationOptions *)initialOptions {
|
|
@@ -112,6 +127,18 @@
|
|
|
112
127
|
options.sideMenu.right.shouldStretchDrawer.get;
|
|
113
128
|
}
|
|
114
129
|
|
|
130
|
+
if (options.sideMenu.left.openMode.hasValue) {
|
|
131
|
+
NSString *openModeString = options.sideMenu.left.openMode.get;
|
|
132
|
+
MMDrawerOpenMode openMode = MMDrawerOpenModeFromString(openModeString);
|
|
133
|
+
[self.sideMenuController side:MMDrawerSideLeft openMode:openMode];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (options.sideMenu.right.openMode.hasValue) {
|
|
137
|
+
NSString *openModeString = options.sideMenu.right.openMode.get;
|
|
138
|
+
MMDrawerOpenMode openMode = MMDrawerOpenModeFromString(openModeString);
|
|
139
|
+
[self.sideMenuController side:MMDrawerSideRight openMode:openMode];
|
|
140
|
+
}
|
|
141
|
+
|
|
115
142
|
if (options.sideMenu.left.animationVelocity.hasValue) {
|
|
116
143
|
self.sideMenuController.animationVelocityLeft = options.sideMenu.left.animationVelocity.get;
|
|
117
144
|
}
|
|
@@ -8,5 +8,11 @@
|
|
|
8
8
|
@property(nonatomic, strong) Double *width;
|
|
9
9
|
@property(nonatomic, strong) Bool *shouldStretchDrawer;
|
|
10
10
|
@property(nonatomic, strong) Double *animationVelocity;
|
|
11
|
+
@property (nonatomic, strong) Text *openMode;
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Converts a string open mode to the equivalent MMDrawerOpenMode enum value
|
|
15
|
+
*/
|
|
16
|
+
MMDrawerOpenMode MMDrawerOpenModeFromString(NSString *openModeString);
|
|
17
|
+
|
|
12
18
|
@end
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
self.width = [DoubleParser parse:dict key:@"width"];
|
|
11
11
|
self.shouldStretchDrawer = [BoolParser parse:dict key:@"shouldStretchDrawer"];
|
|
12
12
|
self.animationVelocity = [DoubleParser parse:dict key:@"animationVelocity"];
|
|
13
|
-
|
|
13
|
+
self.openMode = [TextParser parse:dict key:@"openMode"];
|
|
14
14
|
return self;
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -25,6 +25,18 @@
|
|
|
25
25
|
self.shouldStretchDrawer = options.shouldStretchDrawer;
|
|
26
26
|
if (options.animationVelocity.hasValue)
|
|
27
27
|
self.animationVelocity = options.animationVelocity;
|
|
28
|
+
if (options.openMode.hasValue)
|
|
29
|
+
self.openMode = options.openMode;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
Converts a string open mode to the equivalent MMDrawerOpenMode enum value
|
|
34
|
+
*/
|
|
35
|
+
MMDrawerOpenMode MMDrawerOpenModeFromString(NSString *openModeString) {
|
|
36
|
+
if ([openModeString isEqualToString:@"aboveContent"]) {
|
|
37
|
+
return MMDrawerOpenModeAboveContent;
|
|
38
|
+
}
|
|
39
|
+
return MMDrawerOpenModePushContent;
|
|
28
40
|
}
|
|
29
41
|
|
|
30
42
|
@end
|
|
@@ -1078,10 +1078,19 @@ export interface SideMenuSide {
|
|
|
1078
1078
|
height?: number;
|
|
1079
1079
|
/**
|
|
1080
1080
|
* Stretch sideMenu contents when opened past the width
|
|
1081
|
+
*
|
|
1082
|
+
* **Not applicable when `openMode` is `aboveContent`**
|
|
1083
|
+
*
|
|
1081
1084
|
* #### (iOS specific)
|
|
1082
1085
|
* @default true
|
|
1083
1086
|
*/
|
|
1084
1087
|
shouldStretchDrawer?: boolean;
|
|
1088
|
+
/**
|
|
1089
|
+
* Configure the opening mode of the side menu
|
|
1090
|
+
* #### (iOS specific)
|
|
1091
|
+
* @default 'pushContent'
|
|
1092
|
+
*/
|
|
1093
|
+
openMode?: 'pushContent' | 'aboveContent';
|
|
1085
1094
|
}
|
|
1086
1095
|
|
|
1087
1096
|
export interface OptionsSideMenu {
|