diff --git a/Demo/.DS_Store b/Demo/.DS_Store new file mode 100644 index 0000000..1a38c15 Binary files /dev/null and b/Demo/.DS_Store differ diff --git a/Demo/Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Demo/Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..02a6973 --- /dev/null +++ b/Demo/Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Demo/Demo.xcodeproj/project.xcworkspace/xcuserdata/yann.xcuserdatad/UserInterfaceState.xcuserstate b/Demo/Demo.xcodeproj/project.xcworkspace/xcuserdata/yann.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..e5071dd Binary files /dev/null and b/Demo/Demo.xcodeproj/project.xcworkspace/xcuserdata/yann.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Demo/Demo.xcodeproj/xcuserdata/yann.xcuserdatad/xcschemes/Demo.xcscheme b/Demo/Demo.xcodeproj/xcuserdata/yann.xcuserdatad/xcschemes/Demo.xcscheme new file mode 100644 index 0000000..b39e4a4 --- /dev/null +++ b/Demo/Demo.xcodeproj/xcuserdata/yann.xcuserdatad/xcschemes/Demo.xcscheme @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/Demo.xcodeproj/xcuserdata/yann.xcuserdatad/xcschemes/xcschememanagement.plist b/Demo/Demo.xcodeproj/xcuserdata/yann.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..25efddf --- /dev/null +++ b/Demo/Demo.xcodeproj/xcuserdata/yann.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + Demo.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + F8938452163AD2BE0085C3BB + + primary + + + + + diff --git a/Demo/Demo/AppDelegate.m b/Demo/Demo/AppDelegate.m index f163eab..652bb1e 100644 --- a/Demo/Demo/AppDelegate.m +++ b/Demo/Demo/AppDelegate.m @@ -22,14 +22,36 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( NSMutableArray *viewControllers = [NSMutableArray array]; - for (int i=0; i<8; i++) + NSMutableArray *viewControllerA = [NSMutableArray array]; + NSMutableArray *viewControllerB = [NSMutableArray array]; + NSMutableArray *viewControllerC = [NSMutableArray array]; + + for (int i=0; i<3; i++) + { + DemoRootViewController *rootViewController = [[DemoRootViewController alloc] init]; + [rootViewController setTitle:[NSString stringWithFormat:@"Root VC A %i", i+1]]; + UINavigationController *rootNavController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; + [viewControllerA addObject:rootNavController]; + } + [viewControllers addObject:viewControllerA]; + + for (int i=0; i<2; i++) { DemoRootViewController *rootViewController = [[DemoRootViewController alloc] init]; - [rootViewController setTitle:[NSString stringWithFormat:@"Root VC %i", i+1]]; + [rootViewController setTitle:[NSString stringWithFormat:@"Root VC B %i", i+1]]; UINavigationController *rootNavController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; - [viewControllers addObject:rootNavController]; + [viewControllerB addObject:rootNavController]; } + [viewControllers addObject:viewControllerB]; + for (int i=0; i<3; i++) + { + DemoRootViewController *rootViewController = [[DemoRootViewController alloc] init]; + [rootViewController setTitle:[NSString stringWithFormat:@"Root VC C %i", i+1]]; + UINavigationController *rootNavController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; + [viewControllerC addObject:rootNavController]; + } + [viewControllers addObject:viewControllerC]; [_menuController setViewControllers:viewControllers]; diff --git a/Demo/Demo/DemoMenuController.m b/Demo/Demo/DemoMenuController.m index c6365a4..3744626 100644 --- a/Demo/Demo/DemoMenuController.m +++ b/Demo/Demo/DemoMenuController.m @@ -64,10 +64,10 @@ - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NS } - UIViewController *viewController = self.viewControllers[indexPath.row]; + UIViewController *viewController = self.viewControllers[indexPath.section][indexPath.row]; [cell.textLabel setText:viewController.title]; - if (indexPath.row==self.selectedIndex) + if (indexPath.section==self.selectedIndexPath.section && indexPath.row==self.selectedIndexPath.row) { [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; } diff --git a/PaperFoldMenuController.podspec b/PaperFoldMenuController.podspec new file mode 100644 index 0000000..9b6ee6b --- /dev/null +++ b/PaperFoldMenuController.podspec @@ -0,0 +1,35 @@ +# +# Be sure to run `pod lib lint PaperFoldMenuController.podspec' to ensure this is a +# valid spec and remove all comments before submitting the spec. +# +# Any lines starting with a # are optional, but encouraged +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = "PaperFoldMenuController" + s.version = "1.0.1-1.0.1" + s.summary = "Left side menu with paper fold effect" + s.description = <<-DESC + PaperFoldMenuController is a UITabBarController replacement, but displays the view controllers in a table view on the left side of the screen. This table view is shown/hidden using PaperFold-for-iOS. Selecting from the menu on the left changes the view controller on the right. PaperFoldMenuController uses view controller containment. + DESC + s.homepage = "https://github.com/cielliang/PaperFoldMenuController" + # s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2" + s.license = 'MIT' + s.author = { "hongcheng" => "hongcheng@gmail.com", "Weiyin LIANG" => "weiyin.liang@gmail.com" } + s.source = { :git => "https://github.com/cielliang/PaperFoldMenuController.git", :tag => s.version.to_s } + # s.social_media_url = 'https://twitter.com/' + + s.platform = :ios, '7.0' + s.requires_arc = true + + s.source_files = 'PaperFoldMenuController' + #s.resource_bundles = { + # 'PanelTableView2' => ['Pod/Assets/*.png'] + #} + + # s.public_header_files = 'Pod/Classes/**/*.h' + s.frameworks = 'UIKit' + s.dependency 'PaperFold', '~> 1.1' +end diff --git a/PaperFoldMenuController/PaperFoldMenuController.h b/PaperFoldMenuController/PaperFoldMenuController.h index fa10b5d..84d9be7 100644 --- a/PaperFoldMenuController/PaperFoldMenuController.h +++ b/PaperFoldMenuController/PaperFoldMenuController.h @@ -51,7 +51,8 @@ /** * Set and return the index of the current view controller */ -@property (nonatomic, assign) NSUInteger selectedIndex; +//@property (nonatomic, assign) NSUInteger selectedIndex; +@property (nonatomic, strong) NSIndexPath *selectedIndexPath; @property (nonatomic, assign, readonly) float menuWidth; @property (nonatomic, assign, readonly) int numberOfFolds; /** @@ -65,4 +66,11 @@ * @param animated A boolean value to indicate if the folding/unfolding should be animated */ - (void)showMenu:(BOOL)show animated:(BOOL)animated; + +- (void)insertViewController:(UIViewController *)viewController atSectionIndex:(NSInteger)sectionIndex rowIndex:(NSInteger)rowIndex; + +- (void)addViewController:(UIViewController *)viewController atSectionIndex:(NSInteger)sectionIndex; + +- (void)removeViewControllerAtSectionIndex:(NSInteger)sectionIndex rowIndex:(NSInteger)rowIndex; + @end diff --git a/PaperFoldMenuController/PaperFoldMenuController.m b/PaperFoldMenuController/PaperFoldMenuController.m index 253d361..92be9c9 100644 --- a/PaperFoldMenuController/PaperFoldMenuController.m +++ b/PaperFoldMenuController/PaperFoldMenuController.m @@ -64,38 +64,60 @@ + (BOOL)automaticallyNotifiesObserversOfSelectedViewController + (NSSet *)keyPathsForValuesAffectingSelectedViewController { - return [NSSet setWithObjects:@"selectedIndex", nil]; +// return [NSSet setWithObjects:@"selectedIndex", nil]; + return [NSSet setWithObjects:@"selectedIndexPath", nil]; } - (UIViewController *)selectedViewController { - if (self.selectedIndex == NSNotFound) +// if (self.selectedIndex == NSNotFound) + if (self.selectedIndexPath == nil) { return nil; } else { - return self.viewControllers[self.selectedIndex]; +// return self.viewControllers[self.selectedIndex]; + return self.viewControllers[self.selectedIndexPath.section][self.selectedIndexPath.row]; } } - (void)setSelectedViewController:(UIViewController *)theSelectedViewController { - NSUInteger theSelectedIndex = [self.viewControllers indexOfObject:theSelectedViewController]; +// NSUInteger theSelectedIndex = [self.viewControllers indexOfObject:theSelectedViewController]; - if (theSelectedIndex == NSNotFound) - { +// if (theSelectedIndex == NSNotFound) +// { +// [NSException raise:NSInternalInconsistencyException format:@"Could not selected view controller because it is not registered.\n%@", theSelectedViewController]; +// return; +// } + +// self.selectedIndex = theSelectedIndex; + + NSInteger theSelectedSectionIndex = 0; + NSInteger theSelectedRowIndex = NSNotFound; + for (NSArray *viewControllers in self.viewControllers) { + theSelectedRowIndex = [viewControllers indexOfObject:theSelectedViewController]; + if (theSelectedRowIndex != NSNotFound) { + self.selectedIndexPath = [NSIndexPath indexPathForRow:theSelectedRowIndex inSection:theSelectedSectionIndex]; + break; + } else { + theSelectedSectionIndex ++; + } + } + + if (theSelectedRowIndex == NSNotFound) { [NSException raise:NSInternalInconsistencyException format:@"Could not selected view controller because it is not registered.\n%@", theSelectedViewController]; return; } - - self.selectedIndex = theSelectedIndex; + } + (BOOL)automaticallyNotifiesObserversOfSelectedIndex { return NO; } +/* - (void)setSelectedIndex:(NSUInteger)theSelectedIndex { if (!self.isViewLoaded) @@ -151,9 +173,72 @@ - (void)setSelectedIndex:(NSUInteger)theSelectedIndex } } } +*/ + +- (void)setSelectedIndexPath:(NSIndexPath *)theSelectedIndexPath +{ + if (!self.isViewLoaded) + { + __weak __typeof(*&self) theWeakSelf = self; + [self.viewDidLoadBlocks addObject:[^{ + __strong __typeof(*&self) theStrongSelf = theWeakSelf; + if (theStrongSelf == nil) { + return; + } +// theStrongSelf.selectedIndex = theSelectedIndex; + theStrongSelf.selectedIndexPath = theSelectedIndexPath; + } copy]]; + } + else + { +// NSUInteger theOldSelectedIndex = self.selectedIndex; +// NSUInteger theNewSelectedIndex = theSelectedIndex; + NSIndexPath *theOldSelectedIndexPath = self.selectedIndexPath; + NSIndexPath *theNewSelectedIndexPath = theSelectedIndexPath; + + if (theOldSelectedIndexPath == theNewSelectedIndexPath) { + return; + } + + [self willChangeValueForKey:@"selectedIndex"]; + +// if (theOldSelectedIndex != NSNotFound) + if (theOldSelectedIndexPath != nil) + { + UIViewController *theOldViewController = self.viewControllers[theOldSelectedIndexPath.section][theOldSelectedIndexPath.row]; + [theOldViewController willMoveToParentViewController:nil]; + [theOldViewController.view removeFromSuperview]; + [theOldViewController removeFromParentViewController]; + + [self.menuTableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:theOldSelectedIndexPath.row inSection:theOldSelectedIndexPath.section] animated:YES]; + } + + _selectedIndexPath = theNewSelectedIndexPath; + +// if (theNewSelectedIndex != NSNotFound) + if (theNewSelectedIndexPath != nil) + { + UIViewController *theNewViewController = self.viewControllers[theNewSelectedIndexPath.section][theNewSelectedIndexPath.row]; + theNewViewController.view.frame = self.contentView.bounds; + [self addChildViewController:theNewViewController]; + [self.contentView addSubview:theNewViewController.view]; + [theNewViewController didMoveToParentViewController:self]; + + [self.menuTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:theNewSelectedIndexPath.row inSection:theNewSelectedIndexPath.section] animated:YES scrollPosition:UITableViewScrollPositionNone]; + } + + [self didChangeValueForKey:@"selectedIndexPath"]; + + if (self.paperFoldView.state != PaperFoldStateLeftUnfolded) + { + [self reloadMenu]; + } + } +} - (void)commonInit { - _selectedIndex = NSNotFound; +// _selectedIndex = NSNotFound; + _selectedIndexPath = nil; } - (id)initWithMenuWidth:(float)menuWidth numberOfFolds:(int)numberOfFolds @@ -221,20 +306,50 @@ - (void)viewDidLoad theBlock(); } self.viewDidLoadBlocks = nil; + + self.selectedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0]; } - (void)setViewControllers:(NSMutableArray *)viewControllers { - self.selectedIndex = NSNotFound; // Forces any child view controller to be removed. +// self.selectedIndex = NSNotFound; // Forces any child view controller to be removed. + self.selectedIndexPath = nil; // Forces any child view controller to be removed. _viewControllers = viewControllers; - if ([_viewControllers count]>0) [self setSelectedIndex:0]; +// if ([_viewControllers count]>0) [self setSelectedIndex:0]; + if ([_viewControllers count]>0) [self setSelectedIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; + [self reloadMenu]; +} + +//- (void)addViewController:(UIViewController*)viewController; +//{ +// if (!_viewControllers) _viewControllers = [NSMutableArray array]; +// [self.viewControllers addObject:viewController]; +// [self reloadMenu]; +//} + +- (void)addViewController:(UIViewController *)viewController atSectionIndex:(NSInteger)sectionIndex +{ + if (!_viewControllers) _viewControllers = [NSMutableArray array]; + for (int i=0; i <= sectionIndex; i++) { + if (!_viewControllers[i]) _viewControllers[i] = [NSMutableArray array]; + } + [self.viewControllers[sectionIndex] addObject:viewController]; [self reloadMenu]; } -- (void)addViewController:(UIViewController*)viewController; +- (void)insertViewController:(UIViewController *)viewController atSectionIndex:(NSInteger)sectionIndex rowIndex:(NSInteger)rowIndex { if (!_viewControllers) _viewControllers = [NSMutableArray array]; - [self.viewControllers addObject:viewController]; + for (int i=0; i <= sectionIndex; i++) { + if (!_viewControllers[i]) _viewControllers[i] = [NSMutableArray array]; + } + [self.viewControllers[sectionIndex] insertObject:viewController atIndex:rowIndex]; + [self reloadMenu]; +} + +- (void)removeViewControllerAtSectionIndex:(NSInteger)sectionIndex rowIndex:(NSInteger)rowIndex +{ + [_viewControllers[sectionIndex] removeObjectAtIndex:rowIndex]; [self reloadMenu]; } @@ -250,10 +365,16 @@ - (void)reloadMenu - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - if (tableView==self.menuTableView) return [self.viewControllers count]; +// if (tableView==self.menuTableView) return [self.viewControllers count]; + if (tableView==self.menuTableView) return [self.viewControllers[section] count]; else return 0; } +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return [self.viewControllers count]; +} + - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (tableView==self.menuTableView) @@ -265,10 +386,10 @@ - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NS cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; } - UIViewController *viewController = self.viewControllers[indexPath.row]; + UIViewController *viewController = self.viewControllers[indexPath.section][indexPath.row]; [cell.textLabel setText:viewController.title]; - if (indexPath.row==self.selectedIndex) + if (indexPath.section==self.selectedIndexPath.section && indexPath.row==self.selectedIndexPath.row) { [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; } @@ -285,11 +406,11 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath BOOL shouldSelect = YES; if ([self.delegate respondsToSelector:@selector(paperFoldMenuController:shouldSelectViewController:)]) { - shouldSelect = [self.delegate paperFoldMenuController:self shouldSelectViewController:self.viewControllers[indexPath.row]]; + shouldSelect = [self.delegate paperFoldMenuController:self shouldSelectViewController:self.viewControllers[indexPath.section][indexPath.row]]; } if (shouldSelect) { - [self setSelectedIndex:indexPath.row]; + [self setSelectedIndexPath:indexPath]; if ([self.delegate respondsToSelector:@selector(paperFoldMenuController:didSelectViewController:)]) { [self.delegate paperFoldMenuController:self didSelectViewController:self.selectedViewController];