Skip to content

Commit fe9ea2f

Browse files
committed
Added support for state preservation and restoration
1 parent 6a58213 commit fe9ea2f

File tree

7 files changed

+112
-57
lines changed

7 files changed

+112
-57
lines changed

CHANGELOG

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#1.2.1
2+
* Dropped support for OS <= 6
3+
* Removed warning about project configuration
4+
* Moved to modern O-C syntax
5+
* Added support for childViewControllerForStatusBarStyle
6+
* Added f suffix on float values
7+
* Fixed an issue with fake status bar and rotation
8+
* Added support for state preservation and restoration

PPRevealSideViewController/PPRevealSideviewController/PPRevealSideViewController.m

Lines changed: 53 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,43 +26,7 @@
2626
@interface PPRevealSideViewController ()
2727

2828
@property (nonatomic, strong) UIView *underStatusBarView;
29-
@property (nonatomic, assign) BOOL hideStatusBar;
30-
31-
- (void)setRootViewController:(UIViewController *)controller replaceToOrigin:(BOOL)replace;
32-
- (void)setRootViewController:(UIViewController *)controller;
33-
- (void)addShadow;
34-
- (void)removeShadow;
35-
- (void)handleShadows;
36-
- (void)informDelegateWithOptionalSelector:(SEL)selector withParam:(id)param;
37-
- (void)popViewControllerWithNewCenterController:(UIViewController *)centerController animated:(BOOL)animated andPresentNewController:(UIViewController *)controllerToPush withDirection:(PPRevealSideDirection)direction andOffset:(CGFloat)offset;
38-
- (void)addGesturesToCenterController;
39-
- (void)addPanGestureToController:(UIViewController *)controller;
40-
- (void)addTapGestureToController:(UIViewController *)controller;
41-
- (void)addGesturesToController:(UIViewController *)controller;
42-
- (void)removeAllPanGestures;
43-
- (void)removeAllTapGestures;
44-
- (void)removeAllGestures;
45-
- (void)setOffset:(CGFloat)offset forDirection:(PPRevealSideDirection)direction;
46-
- (void)removeControllerFromView:(UIViewController *)controller animated:(BOOL)animated;
47-
- (void)preloadViewController:(UIViewController *)controller forSide:(PPRevealSideDirection)direction withOffset:(CGFloat)offset forceRemoval:(BOOL)force;
48-
49-
- (BOOL)isLeftControllerClosed;
50-
- (BOOL)isRightControllerClosed;
51-
- (BOOL)isTopControllerClosed;
52-
- (BOOL)isBottomControllerClosed;
53-
- (BOOL)isOptionEnabled:(PPRevealSideOptions)option;
54-
- (BOOL)canCrossOffsets;
55-
56-
- (PPRevealSideDirection)getSideToClose;
57-
58-
- (CGRect)getSlidingRectForOffset:(CGFloat)offset forDirection:(PPRevealSideDirection)direction;
59-
- (CGRect)getSideViewFrameFromRootFrame:(CGRect)rootFrame andDirection:(PPRevealSideDirection)direction;
60-
61-
- (UIEdgeInsets)getEdgetInsetForDirection:(PPRevealSideDirection)direction;
62-
63-
- (CGFloat)getOffsetForDirection:(PPRevealSideDirection)direction andInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;
64-
- (CGFloat)getOffsetForDirection:(PPRevealSideDirection)direction;
65-
- (void)tryToRemoveObserverOnFrame;
29+
@property (nonatomic, assign) BOOL hideStatusBar;
6630

6731
@end
6832

@@ -73,14 +37,6 @@ - (void)setRevealSideViewController:(PPRevealSideViewController *)revealSideView
7337

7438
#pragma mark -
7539
@implementation PPRevealSideViewController
76-
@synthesize rootViewController = _rootViewController;
77-
@synthesize panInteractionsWhenClosed = _panInteractionsWhenClosed;
78-
@synthesize panInteractionsWhenOpened = _panInteractionsWhenOpened;
79-
@synthesize tapInteractionsWhenOpened = _tapInteractionsWhenOpened;
80-
@synthesize directionsToShowBounce = _directionsToShowBounce;
81-
@synthesize options = _options;
82-
@synthesize bouncingOffset = _bouncingOffset;
83-
@synthesize delegate = _delegate;
8440
@synthesize underStatusBarView = _underStatusBarView;
8541

8642
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController {
@@ -1549,13 +1505,65 @@ - (BOOL)prefersStatusBarHidden {
15491505
}
15501506

15511507
- (UIViewController *)childViewControllerForStatusBarStyle {
1508+
if (self.sideDirectionOpened != PPRevealSideDirectionNone) {
1509+
return [self controllerForSide:self.sideDirectionOpened];
1510+
}
15521511
return self.rootViewController;
15531512
}
15541513

15551514
- (UIViewController *)childViewControllerForStatusBarHidden {
1515+
if (self.sideDirectionOpened != PPRevealSideDirectionNone) {
1516+
return [self controllerForSide:self.sideDirectionOpened];
1517+
}
15561518
return self.rootViewController;
15571519
}
15581520

1521+
#pragma mark - State Restoration
1522+
1523+
static NSString *kPPRevealStatePreservationCenterController = @"PPRevealStatePreservationCenterController";
1524+
static NSString *kPPRevealStatePreservationSideController = @"PPRevealStatePreservationSideController";
1525+
static NSString *kPPRevealStatePreservationOpenSide = @"PPRevealStatePreservationOpenSide";
1526+
1527+
- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
1528+
[super encodeRestorableStateWithCoder:coder];
1529+
1530+
// Encode center controller
1531+
[coder encodeObject:self.rootViewController forKey:kPPRevealStatePreservationCenterController];
1532+
1533+
// Encode side controllers
1534+
for (id key in _viewControllers) {
1535+
UIViewController *c = _viewControllers[key];
1536+
if (c) {
1537+
[coder encodeObject:c forKey:[NSString stringWithFormat:@"%@_%@", kPPRevealStatePreservationSideController, key]];
1538+
}
1539+
}
1540+
1541+
// Encode opened side
1542+
[coder encodeInteger:self.sideDirectionOpened forKey:kPPRevealStatePreservationOpenSide];
1543+
}
1544+
1545+
- (void)decodeRestorableStateWithCoder:(NSCoder *)coder{
1546+
[super decodeRestorableStateWithCoder:coder];
1547+
1548+
UIViewController *rootController = [coder decodeObjectForKey:kPPRevealStatePreservationCenterController];
1549+
if (rootController) {
1550+
// This resizing address an issue where the center controller does not have the correct height
1551+
[rootController.view setHeight:PPScreenHeight()];
1552+
[self setRootViewController:rootController];
1553+
}
1554+
1555+
for (id side in @[@(PPRevealSideDirectionTop), @(PPRevealSideDirectionLeft), @(PPRevealSideDirectionRight), @(PPRevealSideDirectionBottom)]) {
1556+
UIViewController *controller = [coder decodeObjectForKey:[NSString stringWithFormat:@"%@_%@", kPPRevealStatePreservationSideController, side]];
1557+
1558+
if (controller) {
1559+
_viewControllers[side] = controller;
1560+
}
1561+
}
1562+
1563+
PPRevealSideDirection openedDirection = [coder decodeIntegerForKey:kPPRevealStatePreservationOpenSide];
1564+
[self pushOldViewControllerOnDirection:openedDirection animated:NO];
1565+
}
1566+
15591567
#pragma mark - Memory management things
15601568

15611569
- (void)viewWillUnload {

PPRevealSideViewController/Sample/AppDelegate.m

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@ @implementation AppDelegate
1919
@synthesize window = _window;
2020
@synthesize revealSideViewController = _revealSideViewController;
2121

22-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
22+
23+
-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
2324
self.window = PP_AUTORELEASE([[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]);
2425

2526
MainViewController *main = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
2627

2728
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:main];
29+
nav.restorationIdentifier = @"MainNav";
2830
_revealSideViewController = [[PPRevealSideViewController alloc] initWithRootViewController:nav];
31+
_revealSideViewController.restorationIdentifier = @"PPReveal";
2932

3033
_revealSideViewController.delegate = self;
3134

@@ -37,17 +40,22 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
3740
PP_RELEASE(main);
3841
PP_RELEASE(nav);
3942

43+
self.revealSideViewController.fakeiOS7StatusBarColor = UIColorFromRGB(0x340085);
44+
4045
self.window.backgroundColor = [UIColor whiteColor];
41-
[self.window makeKeyAndVisible];
46+
47+
return YES;
48+
}
49+
50+
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
51+
[self.window makeKeyAndVisible];
4252

4353
if (PPSystemVersionGreaterOrEqualThan(7.0)) {
4454
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
4555
[[UINavigationBar appearance] setBarTintColor:UIColorFromRGB(0x34B085)];
4656
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
4757
}
4858

49-
self.revealSideViewController.fakeiOS7StatusBarColor = UIColorFromRGB(0x340085);
50-
5159
return YES;
5260
}
5361

@@ -138,4 +146,12 @@ - (void)applicationWillTerminate:(UIApplication *)application {
138146
*/
139147
}
140148

149+
- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder {
150+
return YES;
151+
}
152+
153+
- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder {
154+
return YES;
155+
}
156+
141157
@end

PPRevealSideViewController/Sample/MainViewController.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ - (void)didReceiveMemoryWarning {
3434

3535
- (void)viewDidLoad {
3636
[super viewDidLoad];
37+
38+
self.restorationIdentifier = @"MainController";
39+
3740
UIBarButtonItem *left = [[UIBarButtonItem alloc] initWithTitle:@"Left"
3841
style:UIBarButtonItemStylePlain
3942
target:self

PPRevealSideViewController/Sample/SecondViewController.m

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
#import "SecondViewController.h"
1010

11+
@interface SecondViewController () <UIViewControllerRestoration>
12+
13+
@end
14+
1115
@implementation SecondViewController
1216

1317
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
@@ -29,9 +33,16 @@ - (void)didReceiveMemoryWarning {
2933

3034
- (void)viewDidLoad {
3135
[super viewDidLoad];
36+
37+
self.restorationIdentifier = @"SecondController";
38+
self.restorationClass = [self class];
39+
3240
// Do any additional setup after loading the view from its nib.
3341
}
3442

43+
+ (UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder {
44+
return [[self class] new];
45+
}
3546
- (void)viewDidUnload {
3647
[super viewDidUnload];
3748
// Release any retained subviews of the main view.

PPRevealSideViewController/Sample/TableViewController.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
#import "WebViewController.h"
1616
#import "ModalViewController.h"
1717

18+
@interface TableViewController () <UIViewControllerRestoration>
19+
20+
@end
21+
1822
@implementation TableViewController
1923

2024
- (instancetype)initWithStyle:(UITableViewStyle)style {
@@ -37,10 +41,16 @@ - (void)didReceiveMemoryWarning {
3741
// Release any cached data, images, etc that aren't in use.
3842
}
3943

44+
+ (UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder {
45+
return [[[self class] alloc] initWithStyle:UITableViewStylePlain];
46+
}
47+
4048
#pragma mark - View lifecycle
4149

4250
- (void)viewDidLoad {
4351
[super viewDidLoad];
52+
self.restorationIdentifier = @"LeftTableController";
53+
self.restorationClass = [self class];
4454

4555
[self.tableView addObserver:self
4656
forKeyPath:@"revealSideInset"

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,13 @@ PPRevealSideViewController fully supports ARC *and* non-ARC modes out of the box
7070

7171
# Compatibility
7272

73-
The class if fully compatible from iOS 4 to iOS 7. Not tested yet on older versions like iOS 3, but there is no reasons it doesn't work.
74-
Please note that this class use the new container methods of UIViewController since iOS 5. By using this class on iOS 4 for example, you need to be careful with rotation handling, and presentModalViewController stuff.
75-
Some things you need to be aware on iOS 4 or older :
76-
77-
* the currentOrientation property is not passed to child controllers, so only the window rootViewController knows the currentOrientation. Always use the status bar orientation from UIApplication
78-
* override willAnimateRotationToInterfaceOrientation method to relayout the subviews
79-
* ALWAYS present modal view controller from reveal side view controller, not from the controller itself. Otherwise, you will see strange bug with memory warning and/or rotation (bad layout)
80-
* There is no support on iOS 4 and older of hiding and showing status bar in the app. It's ok if the status bar is initially hidden or not
73+
The class if fully compatible from iOS 7. I recently dropped support for previous version. So if needed, please grab a previous commit / version than [this one](https://github.com/ipup/PPRevealSideViewController/commit/6ae0c43278ec251c2d22c897d610d017bbd47dec).
74+
75+
## State preservation and restoration
76+
PPReveal supports state preservation and restoration. All you need is to set a `restorationIdentifier` to all the controllers you want to restore, maybe a `restorationClass` and you're all set
77+
78+
## Status bar style / hidden
79+
The status bar style and hidden are forwarded to the child controllers. If you want to remove this behavior, simply subclasse PPReveal and override both `childViewControllerForStatusBarStyle` and `childViewControllerForStatusBarHidden` to return `nil`.
8180

8281
# Documentation
8382

0 commit comments

Comments
 (0)