iOS开源项目:DYNavigationController
DYNavigationController是一个实现了左右滑动导航的项目。
https://github.com/dyang/DYNavigationController
首先用之前的跟视图初始化DYNavigationController
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application launch. RootViewController *rootViewController = [[[RootViewController alloc] init] autorelease]; DYNavigationController *navigationController = [[[DYNavigationController alloc] initWithRootViewController:rootViewController] autorelease]; self.window.rootViewController = navigationController; [self.window makeKeyAndVisible]; return YES; }
这个方法定义了左右滑动的手势操作
- (void)setUpGestureRecognizers:(UIViewController *)viewController { // Swipe right: pop the current view and go back one level UISwipeGestureRecognizer *rightSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(popCurrentViewOut:)]; rightSwipeGesture.direction = UISwipeGestureRecognizerDirectionRight; [viewController.view addGestureRecognizer:rightSwipeGesture]; [rightSwipeGesture release]; // Swipe left: push a new view UISwipeGestureRecognizer *leftSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(pushNewViewIn:)]; leftSwipeGesture.direction = UISwipeGestureRecognizerDirectionLeft; [viewController.view addGestureRecognizer:leftSwipeGesture]; [leftSwipeGesture release]; }
当向右滑动的时候,当前的视图会被移动的屏幕的左边,并加入到导航的栈里
- (void)pushViewController:(UIViewController *)viewController { // Place the new view to the right next to the current view viewController.view.frame = CGRectOffset(self.view.bounds, self.view.bounds.size.width, 0); // Add the new view to our view hierarchy so that it displays on screen. [self.view addSubview:viewController.view]; // Start animation [UIView animateWithDuration:ANIMATION_DURATION delay:ANIMATION_DELAY options:UIViewAnimationCurveEaseInOut animations:^{ [self currentViewController].view.frame = CGRectOffset(self.view.bounds, -self.view.bounds.size.width, 0); viewController.view.frame = self.view.bounds; } completion:^(BOOL finished) { if (finished) { // Connect DYNavigationController to viewController if needed [self setNavigatorIfNeeded:viewController]; // Set up gesture recognizer so that we can respond to swipes [self setUpGestureRecognizers:viewController]; // Add the new controller to our viewControllerStack [self.viewControllerStack addObject:viewController]; } }]; }
这里使用了UIView的类方法animateWithDuration实现了跳转的动画。
当向左滑动的时候,当前视图被移除导航栈,左边的视图向右移到屏幕中央。
- (void)popViewController { // Sanity check - We only pop when there are at least two viewControllers in the stack, // otherwise there is nothing to pop if (self.viewControllerStack.count < 2) return; // Start animation [UIView animateWithDuration:ANIMATION_DURATION delay:ANIMATION_DELAY options:UIViewAnimationCurveEaseInOut animations:^{ [self currentViewController].view.frame = CGRectOffset(self.view.bounds, self.view.bounds.size.width, 0); [self previousViewController].view.frame = self.view.bounds; } completion:^(BOOL finished) { if (finished) { // Tear down gesture recognizers [self tearDownGestureRecognizers:[self currentViewController]]; // Remove current viewController.view from self. [[self currentViewController].view removeFromSuperview]; // Remove current viewController from self. [[self currentViewController] removeFromParentViewController]; // Remove current view controller from viewControllerStack [self.viewControllerStack removeLastObject]; } }]; }
导航的具体实现在DYNavigationController中,DYNavigationControllerDelegate持有一个DYNavigationController的property,在RootViewController中进行了synthesize,RootViewController实现了DYNavigationControllerDelegate协议,DetailViewController也实现了DYNavigationControllerDelegate协议,所以DetailViewController中可以直接使用这个DYNavigationController的引用,来实现导航功能。