KNAXWebVC4BC 1.0.1

KNAXWebVC4BC 1.0.1

zhangkn 维护。



 
依赖项
AXPracticalHUD>= 0
AXNavigationBackItemInjection>= 0
NJKWebViewProgress>= 0
方面>= 0
 

  • 作者
  • kunnan

image

pod KNAXWebViewController

➜  AXWebViewController git:(master) ✗ kngit 0.7.4
➜  AXWebViewController git:(master) git tag -a 0.7.4 -m "0.7.4"                                           
➜  AXWebViewController git:(master) git push origin --tags                                                
➜  AXWebViewController git:(master) ✗ pod lib lint KNAXWebViewController.podspec --allow-warnings --no-clean

pod trunk push  KNAXWebViewController.podspec --allow-warnings


如何使用

#import <KNAXWebViewController/AXWebViewController.h>

[(AXWebViewController*)nav.topViewController loadURL:[NSURL URLWithString:responseObject[@"wap_url"]]];
[(AXWebViewController*)nav.topViewController setHomeUrl:responseObject[@"wap_url"]];

另请参阅

确保在 Xcode -> Window -> Devices 中列出至少一个ios 模拟器或在验证期间添加一个。)

➜  AXWebViewController git:(master) ✗ sudo gem install cocoapods 

🎉  Congrats

🚀  KNAXWebViewController (0.7.6) successfully published
📅  May 28th, 21:00
🌎  https://cocoapods.org.cn/pods/KNAXWebViewController
👍  Tell your friends!

AXWebViewController

BuildVersionLicensePlatform996.icu

总结

AXWebViewController 是一款基于 WKWebView(WebKit) 封装的 view controller,高度集成,一行代码即可使用;能够满足大部分的 App 加载 html 网页的场景,AXWebViewController 实现了 WKUIDelegateWKNavigationDelegate 两个协议,在使用过程中,若需要自定义功能,可自行 Overrides 相关方法予以实现;

AXWebViewController 可实现 微信样式 的网页浏览导航控制,可在导航栏显示 返回关闭 两个功能按钮,这个功能主要基于 AXNavigationBackItemInjection 实现,AXNavigationBackItemInjection 可以拦截点击返回导航或者手势滑动返回,有兴趣的朋友可以了解了解!

sample2 sample

视频链接

功能

  • 手势滑动返回上个页面
  • 微信样式导航返回、关闭
  • 网页加载失败提示
  • 网页加载进度提示
  • 网页来源 host 提示
  • 支持 __Peek____Pop__ 浏览网页,并且 commit 之后在本网页进行加载,不用跳转到 Safari 进行浏览,这里使用到了很多运行时的方法,因此,谨慎使用!

要求

AXWebViewController 对系统版本支持到 iOS 7.0;版本 0.7.0 以后仅支持 Xcode 9,需要使用到:

  • Foundation.framework
  • UIKit.framework

使用的时候最好使用最新版 Xcode。

将 AXWebViewController 添加到项目中

CocoaPods

CocoaPods 是向项目中添加 AXWebViewController 的推荐方式。

  1. 在 Podfile 中添加 AXWebViewController 的 pod 条目 pod 'AXWebViewController', '~> 0.6.0'
  2. 运行 pod install 安装 pod。
  3. 使用 AXWebViewController 时,包含 AXWebViewController.h

源文件

或者,您可以直接把路径 */AXWebViewController/ 下的源文件直接添加到您的项目中。

  1. 下载最新的代码版本 master.zip 或者将存储库作为 git 子模块添加到您的 git 追踪项目中。
  2. 在 Xcode 中打开项目,然后将源文件拖放到项目中(如果代码归档未在项目中提取,选择复制项目时使用“产品导航视图”)。确保当被问及时选择复制项目。
  3. 使用 AXWebViewController 时,包含 AXWebViewController.h

许可证

此代码在 MIT 许可证 的条款和条件下分发。

使用

AXWebViewController 的使用和保护普通 UIViewController 一样简单,只需要在需要的位置使用 URL 初始化即可:

AXWebViewController *webVC = [[AXWebViewController alloc] initWithAddress:@"http://www.baidu.com"];
webVC.showsToolBar = NO;
webVC.navigationController.navigationBar.translucent = NO;
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0.100f green:0.100f blue:0.100f alpha:0.800f];
self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:0.996f green:0.867f blue:0.522f alpha:1.00f];
[self.navigationController pushViewController:webVC animated:YES];

使用工具条导航

在使用工具条时,只需在 AXWebViewController 初始化后加入一句代码:

webVC.navigationType = AXWebViewControllerNavigationToolItem;
webVC.showsToolBar = YES;

注意,设置 navigationTypeAXWebViewControllerNavigationToolItem 之后,须确保 showsToolBarYES 才能生效。

使用微信样式导航

AXWebViewController 初始化后加入一句代码:

webVC.navigationType = AXWebViewControllerNavigationBarItem;

即可生效。

Peek&Pop

Peek和Pop使用的是原生的系统功能,在使用时只需要将 webView.allowsLinkPreview 设置为 YES 即可使用,这里需要注意,在实现Peek和Pop时,使用了Runtime的相关知识,并且使用AOP的一个框架__Aspects__ 进行了编程,在使用过程中可能会出错,当然,出错的几率也很小(苹果不可能隔三差五去修改自家的Private API吧= =),实现原理就不多讲了,基本就是运行时的一些知识,代码如下:


- (void)hookWebContentCommitPreviewHandler {
    // Find the `WKContentView` in the webview.
    __weak typeof(self) wself = self;
    for (UIView *_view in _webView.scrollView.subviews) {
    if ([_view isKindOfClass:NSClassFromString(@"WKContentView")]) {
    id _previewItemController = object_getIvar(_view, class_getInstanceVariable([_view class], "_previewItemController"));
    Class _class = [_previewItemController class];
    SEL _performCustomCommitSelector = NSSelectorFromString(@"previewInteractionController:interactionProgress:forRevealAtLocation:inSourceView:containerView:");
    [_previewItemController aspect_hookSelector:_performCustomCommitSelector withOptions:AspectPositionAfter usingBlock:^() {
        UIViewController *pred = [_previewItemController valueForKeyPath:@"presentedViewController"];
        [pred aspect_hookSelector:NSSelectorFromString(@"_addRemoteView") withOptions:AspectPositionAfter usingBlock:^() {
            UIViewController *_remoteViewController = object_getIvar(pred, class_getInstanceVariable([pred class], "_remoteViewController"));
            
            [_remoteViewController aspect_hookSelector:@selector(viewDidLoad) withOptions:AspectPositionAfter usingBlock:^() {
                _remoteViewController.view.tintColor = wself.navigationController.navigationBar.tintColor;
            } error:NULL];
        } error:NULL];
        
        NSArray *ddActions = [pred valueForKeyPath:@"ddActions"];
        id openURLAction = [ddActions firstObject];
        
        [openURLAction aspect_hookSelector:NSSelectorFromString(@"perform") withOptions:AspectPositionInstead usingBlock:^ () {
            NSURL *_url = object_getIvar(openURLAction, class_getInstanceVariable([openURLAction class], "_url"));
            [wself loadURL:_url];
        } error:NULL];
        
        id _lookupItem = object_getIvar(_previewItemController, class_getInstanceVariable([_class class], "_lookupItem"));
        [_lookupItem aspect_hookSelector:NSSelectorFromString(@"commit") withOptions:AspectPositionInstead usingBlock:^() {
            NSURL *_url = object_getIvar(_lookupItem, class_getInstanceVariable([_lookupItem class], "_url"));
            [wself loadURL:_url];
        } error:NULL];
        [_lookupItem aspect_hookSelector:NSSelectorFromString(@"commitWithTransitionForPreviewViewController:inViewController:completion:") withOptions:AspectPositionInstead usingBlock:^() {
            NSURL *_url = object_getIvar(_lookupItem, class_getInstanceVariable([_lookupItem class], "_url"));
            [wself loadURL:_url];
        } error:NULL];
        /*
         UIWindow
         -UITransitionView
         --UIVisualEffectView
         ---_UIVisualEffectContentView
         ----UIView
         -----_UIPreviewActionSheetView
         */
        /*
         for (UIView * transitionView in [UIApplication sharedApplication].keyWindow.subviews) {
         if ([transitionView isMemberOfClass:NSClassFromString(@"UITransitionView")]) {
         transitionView.tintColor = wself.navigationController.navigationBar.tintColor;
         for (UIView *__view in transitionView.subviews) {
         if ([__view isMemberOfClass:NSClassFromString(@"UIVisualEffectView")]) {
         for (UIView *___view in __view.subviews) {
         if ([___view isMemberOfClass:NSClassFromString(@"_UIVisualEffectContentView")]) {
         for (UIView *____view in ___view.subviews) {
         if ([____view isMemberOfClass:NSClassFromString(@"UIView")]) {
         __weak typeof(____view) w____view = ____view;
         [____view aspect_hookSelector:@selector(addSubview:) withOptions:AspectPositionAfter usingBlock:^() {
         for (UIView *actionSheet in w____view.subviews) {
         if ([actionSheet isMemberOfClass:NSClassFromString(@"_UIPreviewActionSheetView")]) {
         break;
         }
         }
         } error:NULL];
         }
         }break;
         }
         }break;
         }
         }break;
         }
         }
         */
    } error:NULL];
    break;
    }
    }
}

致谢

RxWebViewController 为我提供了思路,有些地方做了参考。

iOS8.0 以下使用 NJKWebViewProgress 作为进度条,感谢!

更新日志

0.1.10

使用基于UIWebView的实现,进度条使用NJKWebViewProgress实现。

0.2.0

iOS8.0以上使用WKWebView实现,进度条使用UIProgressView实现。实现了本页面Peek&Pop而不需要跳转到Safari进行浏览。

0.3.0

使用AXNavigationBackItemInjection实现微信导航样式,也可以自定义返回的操作,只需要几行代码就可以搞定!

查看更多日志请移步最新版本

KNAXWebViewController

KNAXWebVC4BC