diff --git a/RxWebViewController/RxWebViewNavigationViewController.h b/RxWebViewController/RxWebViewNavigationViewController.h deleted file mode 100644 index 0074be7..0000000 --- a/RxWebViewController/RxWebViewNavigationViewController.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// RxWebViewNavigationViewController.h -// RxWebViewController -// -// Created by roxasora on 15/10/23. -// Copyright © 2015年 roxasora. All rights reserved. -// - -#import - -@interface RxWebViewNavigationViewController : UINavigationController - -@end diff --git a/RxWebViewController/RxWebViewNavigationViewController.m b/RxWebViewController/RxWebViewNavigationViewController.m deleted file mode 100644 index ea9868a..0000000 --- a/RxWebViewController/RxWebViewNavigationViewController.m +++ /dev/null @@ -1,76 +0,0 @@ -// -// RxWebViewNavigationViewController.m -// RxWebViewController -// -// Created by roxasora on 15/10/23. -// Copyright © 2015年 roxasora. All rights reserved. -// - -#import "RxWebViewNavigationViewController.h" -#import "RxWebViewController.h" - -@interface RxWebViewNavigationViewController () - -/** - * 由于 popViewController 会触发 shouldPopItems,因此用该布尔值记录是否应该正确 popItems - */ -@property BOOL shouldPopItemAfterPopViewController; - -@end - -@implementation RxWebViewNavigationViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - self.shouldPopItemAfterPopViewController = NO; - // Do any additional setup after loading the view. -} - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - --(UIViewController*)popViewControllerAnimated:(BOOL)animated{ - self.shouldPopItemAfterPopViewController = YES; - return [super popViewControllerAnimated:animated]; -} - --(NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated{ - self.shouldPopItemAfterPopViewController = YES; - return [super popToViewController:viewController animated:animated]; -} - --(NSArray *)popToRootViewControllerAnimated:(BOOL)animated{ - self.shouldPopItemAfterPopViewController = YES; - return [super popToRootViewControllerAnimated:animated]; -} --(BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item{ - - //! 如果应该pop,说明是在 popViewController 之后,应该直接 popItems - if (self.shouldPopItemAfterPopViewController) { - self.shouldPopItemAfterPopViewController = NO; - return YES; - } - - //! 如果不应该 pop,说明是点击了导航栏的返回,这时候则要做出判断区分是不是在 webview 中 - if ([self.topViewController isKindOfClass:[RxWebViewController class]]) { - RxWebViewController* webVC = (RxWebViewController*)self.viewControllers.lastObject; - if (webVC.webView.canGoBack) { - [webVC.webView goBack]; - - //!make sure the back indicator view alpha back to 1 - self.shouldPopItemAfterPopViewController = NO; - [[self.navigationBar subviews] lastObject].alpha = 1; - return NO; - }else{ - [self popViewControllerAnimated:YES]; - return NO; - } - }else{ - [self popViewControllerAnimated:YES]; - return NO; - } -} - -@end diff --git a/RxWebViewController/UINavigationController+RxWebViewNavigation.m b/RxWebViewController/UINavigationController+RxWebViewNavigation.m new file mode 100755 index 0000000..2e7d0e9 --- /dev/null +++ b/RxWebViewController/UINavigationController+RxWebViewNavigation.m @@ -0,0 +1,59 @@ +// +// UINavigationController+RxWebViewNavigation.m +// RxWebViewController +// +// Created by roxasora on 15/10/23. +// Copyright © 2015年 roxasora. All rights reserved. +// + +#import "RxWebViewController.h" +#import + +@implementation UINavigationController (RxWebViewNavigation) + ++ (void)load +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // UINavigationController 实现了协议方法 navigationBar:shouldPopItem:,因此为了省事就直接交换了 + method_exchangeImplementations(class_getInstanceMethod(self, @selector(navigationBar:shouldPopItem:)), + class_getInstanceMethod(self, @selector(rx_navigationBar:shouldPopItem:))); + }); +} + +// 改进思路来自 [截获导航控制器系统返回按钮的点击pop及右滑pop事件](http://www.jianshu.com/p/6376149a2c4c) +- (BOOL)rx_navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item +{ + UIViewController *topVC = self.topViewController; + + // 通过代码 pop 时,顶层视图控制器出栈后,此方法才会被调用 + // 也就是说,此时获取到的顶层视图控制器其实是原顶层视图控制器的上一层视图控制器 + // 而参数 item 却依然是原顶层视图控制器的 navigationItem + // 因此,如果 navigationItem 不同,就说明此方法是因为通过代码 pop 而调用的,此时应该沿用默认实现 + if (item != topVC.navigationItem) { + return [self rx_navigationBar:navigationBar shouldPopItem:item]; + } + + // 能来到这里说明此方法是由于点击返回按钮而调用的,此时顶层视图控制器尚未出栈 + // 若顶层视图控制器是 RxWebViewController,并且网页可以返回,此时应该将网页返回,而不是 pop 顶层视图控制器 + if ([topVC isKindOfClass:[RxWebViewController class]]) { + RxWebViewController *webVC = (RxWebViewController*)topVC; + if (webVC.webView.canGoBack) { + [webVC.webView goBack]; + // 最后一个子视图即是返回按钮图片,由于 pop 操作,它会变淡 + // 而此时希望取消 pop 操作,并不希望返回按钮图片变淡,因此重新恢复它的透明度 + [[self.navigationBar subviews] lastObject].alpha = 1; + // 由于此时不希望 pop,因此返回 NO + return NO; + } + // 虽然顶层视图控制器是 RxWebViewController,但是网页不可返回上一页了 + // 此时应该像普通情况一样 pop 顶层视图控制器,因此这里应该沿用默认实现 + return [self rx_navigationBar:navigationBar shouldPopItem:item]; + } + + // 来到这里说明此方法是由于点击返回按钮而调用的,此时顶层视图控制器尚未出栈,但它不是 RxWebViewController + // 此时也应该像普通情况一样 pop 顶层视图控制器,因此这里同样应该沿用默认实现 + return [self rx_navigationBar:navigationBar shouldPopItem:item]; +} + +@end diff --git a/RxWebViewControllerTest.xcodeproj/project.pbxproj b/RxWebViewControllerTest.xcodeproj/project.pbxproj index a636162..6de04ca 100644 --- a/RxWebViewControllerTest.xcodeproj/project.pbxproj +++ b/RxWebViewControllerTest.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 2DE53C3B1CCF04C2006B9162 /* UINavigationController+RxWebViewNavigation.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE53C3A1CCF04C2006B9162 /* UINavigationController+RxWebViewNavigation.m */; }; F53D31EC1BDB339D002322E1 /* Reveal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F53D31EB1BDB339D002322E1 /* Reveal.framework */; }; F59CDE9F1C1FBFB9008B5358 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CDE801C1FBFB9008B5358 /* AppDelegate.m */; }; F59CDEA01C1FBFB9008B5358 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F59CDE811C1FBFB9008B5358 /* Assets.xcassets */; }; @@ -14,9 +15,7 @@ F59CDEA21C1FBFB9008B5358 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F59CDE841C1FBFB9008B5358 /* Main.storyboard */; }; F59CDEA31C1FBFB9008B5358 /* demo.gif in Resources */ = {isa = PBXBuildFile; fileRef = F59CDE861C1FBFB9008B5358 /* demo.gif */; }; F59CDEA41C1FBFB9008B5358 /* icon-140.png in Resources */ = {isa = PBXBuildFile; fileRef = F59CDE871C1FBFB9008B5358 /* icon-140.png */; }; - F59CDEA51C1FBFB9008B5358 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = F59CDE881C1FBFB9008B5358 /* Info.plist */; }; F59CDEA61C1FBFB9008B5358 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CDE891C1FBFB9008B5358 /* main.m */; }; - F59CDEA71C1FBFB9008B5358 /* myNavigationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CDE8B1C1FBFB9008B5358 /* myNavigationViewController.m */; }; F59CDEA81C1FBFB9008B5358 /* RxLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CDE8E1C1FBFB9008B5358 /* RxLabel.m */; }; F59CDEA91C1FBFB9008B5358 /* RxTextLinkTapView.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CDE901C1FBFB9008B5358 /* RxTextLinkTapView.m */; }; F59CDEB01C1FBFB9008B5358 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CDE9E1C1FBFB9008B5358 /* ViewController.m */; }; @@ -27,10 +26,10 @@ F59CDEC71C1FC6AE008B5358 /* NJKWebViewProgress.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CDEBE1C1FC6AE008B5358 /* NJKWebViewProgress.m */; }; F59CDEC81C1FC6AE008B5358 /* NJKWebViewProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CDEC01C1FC6AE008B5358 /* NJKWebViewProgressView.m */; }; F59CDEC91C1FC6AE008B5358 /* RxWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CDEC21C1FC6AE008B5358 /* RxWebViewController.m */; }; - F59CDECA1C1FC6AE008B5358 /* RxWebViewNavigationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CDEC41C1FC6AE008B5358 /* RxWebViewNavigationViewController.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 2DE53C3A1CCF04C2006B9162 /* UINavigationController+RxWebViewNavigation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UINavigationController+RxWebViewNavigation.m"; sourceTree = ""; }; F53D31991BDA4FCA002322E1 /* RxWebViewControllerTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RxWebViewControllerTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; F53D31EB1BDB339D002322E1 /* Reveal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Reveal.framework; sourceTree = ""; }; F59CDE7F1C1FBFB9008B5358 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -42,8 +41,6 @@ F59CDE871C1FBFB9008B5358 /* icon-140.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-140.png"; sourceTree = ""; }; F59CDE881C1FBFB9008B5358 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F59CDE891C1FBFB9008B5358 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - F59CDE8A1C1FBFB9008B5358 /* myNavigationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = myNavigationViewController.h; sourceTree = ""; }; - F59CDE8B1C1FBFB9008B5358 /* myNavigationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = myNavigationViewController.m; sourceTree = ""; }; F59CDE8D1C1FBFB9008B5358 /* RxLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RxLabel.h; sourceTree = ""; }; F59CDE8E1C1FBFB9008B5358 /* RxLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxLabel.m; sourceTree = ""; }; F59CDE8F1C1FBFB9008B5358 /* RxTextLinkTapView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RxTextLinkTapView.h; sourceTree = ""; }; @@ -61,8 +58,6 @@ F59CDEC01C1FC6AE008B5358 /* NJKWebViewProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJKWebViewProgressView.m; sourceTree = ""; }; F59CDEC11C1FC6AE008B5358 /* RxWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RxWebViewController.h; sourceTree = ""; }; F59CDEC21C1FC6AE008B5358 /* RxWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxWebViewController.m; sourceTree = ""; }; - F59CDEC31C1FC6AE008B5358 /* RxWebViewNavigationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RxWebViewNavigationViewController.h; sourceTree = ""; }; - F59CDEC41C1FC6AE008B5358 /* RxWebViewNavigationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxWebViewNavigationViewController.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -98,8 +93,6 @@ F59CDE7E1C1FBFB9008B5358 /* RxWebViewControllerTest */ = { isa = PBXGroup; children = ( - F59CDE8A1C1FBFB9008B5358 /* myNavigationViewController.h */, - F59CDE8B1C1FBFB9008B5358 /* myNavigationViewController.m */, F59CDEB41C1FC06B008B5358 /* myNormalViewController.h */, F59CDEB51C1FC06B008B5358 /* myNormalViewController.m */, F59CDEB61C1FC06B008B5358 /* myNormalViewController.xib */, @@ -138,8 +131,7 @@ F59CDEBC1C1FC6AE008B5358 /* NJKWebViewProgress */, F59CDEC11C1FC6AE008B5358 /* RxWebViewController.h */, F59CDEC21C1FC6AE008B5358 /* RxWebViewController.m */, - F59CDEC31C1FC6AE008B5358 /* RxWebViewNavigationViewController.h */, - F59CDEC41C1FC6AE008B5358 /* RxWebViewNavigationViewController.m */, + 2DE53C3A1CCF04C2006B9162 /* UINavigationController+RxWebViewNavigation.m */, ); path = RxWebViewController; sourceTree = ""; @@ -181,7 +173,7 @@ F53D31911BDA4FCA002322E1 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0700; + LastUpgradeCheck = 0730; ORGANIZATIONNAME = roxasora; TargetAttributes = { F53D31981BDA4FCA002322E1 = { @@ -220,7 +212,6 @@ F59CDEB81C1FC06B008B5358 /* myNormalViewController.xib in Resources */, F59CDEC61C1FC6AE008B5358 /* backItemImage_hl@2x.png in Resources */, F59CDEA21C1FBFB9008B5358 /* Main.storyboard in Resources */, - F59CDEA51C1FBFB9008B5358 /* Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -234,10 +225,9 @@ F59CDEC71C1FC6AE008B5358 /* NJKWebViewProgress.m in Sources */, F59CDEA61C1FBFB9008B5358 /* main.m in Sources */, F59CDE9F1C1FBFB9008B5358 /* AppDelegate.m in Sources */, + 2DE53C3B1CCF04C2006B9162 /* UINavigationController+RxWebViewNavigation.m in Sources */, F59CDEA81C1FBFB9008B5358 /* RxLabel.m in Sources */, F59CDEB01C1FBFB9008B5358 /* ViewController.m in Sources */, - F59CDEA71C1FBFB9008B5358 /* myNavigationViewController.m in Sources */, - F59CDECA1C1FC6AE008B5358 /* RxWebViewNavigationViewController.m in Sources */, F59CDEB71C1FC06B008B5358 /* myNormalViewController.m in Sources */, F59CDEC81C1FC6AE008B5358 /* NJKWebViewProgressView.m in Sources */, F59CDEA91C1FBFB9008B5358 /* RxTextLinkTapView.m in Sources */, diff --git a/RxWebViewControllerTest/Base.lproj/Main.storyboard b/RxWebViewControllerTest/Base.lproj/Main.storyboard index f4912e6..38fff6f 100644 --- a/RxWebViewControllerTest/Base.lproj/Main.storyboard +++ b/RxWebViewControllerTest/Base.lproj/Main.storyboard @@ -1,7 +1,7 @@ - + - + @@ -65,10 +65,10 @@ - + - + diff --git a/RxWebViewControllerTest/myNavigationViewController.h b/RxWebViewControllerTest/myNavigationViewController.h deleted file mode 100644 index 73ad019..0000000 --- a/RxWebViewControllerTest/myNavigationViewController.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// myNavigationViewController.h -// RxWebViewController -// -// Created by 范斌 on 15/12/9. -// Copyright © 2015年 roxasora. All rights reserved. -// - -#import "RxWebViewNavigationViewController.h" - -@interface myNavigationViewController : RxWebViewNavigationViewController - -@end diff --git a/RxWebViewControllerTest/myNavigationViewController.m b/RxWebViewControllerTest/myNavigationViewController.m deleted file mode 100644 index b43610a..0000000 --- a/RxWebViewControllerTest/myNavigationViewController.m +++ /dev/null @@ -1,37 +0,0 @@ -// -// myNavigationViewController.m -// RxWebViewController -// -// Created by 范斌 on 15/12/9. -// Copyright © 2015年 roxasora. All rights reserved. -// - -#import "myNavigationViewController.h" - -@interface myNavigationViewController () - -@end - -@implementation myNavigationViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - // Do any additional setup after loading the view. -} - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -/* -#pragma mark - Navigation - -// In a storyboard-based application, you will often want to do a little preparation before navigation -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - // Get the new view controller using [segue destinationViewController]. - // Pass the selected object to the new view controller. -} -*/ - -@end