iOS類微信返回導航WebViewController
AXWebViewController 是一款易用的基于 UIWebView (20160716更新:iOS8.0以上使用 WKWebView 實現)封裝的網頁瀏覽控制器. 在系統功能的基礎上添加了工具條導航,可以刷新、返回、前進、等操作,同時, AXWebViewController 還實現了 微信樣式 的導航返回支持,集成簡單,使用方便。如圖所示:
特性
- 手勢滑動返回上個網頁
- 微信樣式導航返回
- 網頁加載失敗提示(iOS8.0以下)
- 網頁加載進度提示
- 網頁來源提示
- 支持 Peek 和 Pop 瀏覽網頁,并且commit之后在本網頁進行加載,不用跳轉到Safari進行瀏覽,這里使用到了很多運行時的方法,因此,在使用的過程中可能會拋異常。
要求
AXWebViewController 對系統版本支持到iOS7.0,需要使用到:
- Foundation.framework
- UIKit.framework
使用的時候最好使用最新版Xcode。
使用
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;
注意,在設置 navigationType 為 AXWebViewControllerNavigationToolItem 之后,須確認 showsToolBar 為 YES 才能生效.
使用微信樣式導航
在 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;
}
}
}
本文由用戶 yeliz 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!