Files
2026-07-13 12:35:01 +08:00

337 lines
12 KiB
Objective-C

//
// TLWebViewController.m
// TLChat
//
// Created by 李伯坤 on 16/2/10.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import "TLWebViewController.h"
#import "UIBarButtonItem+Back.h"
#import "WKWebView+Post.h"
#define WEBVIEW_NAVBAR_ITEMS_FIXED_SPACE 9
@interface TLWebViewController ()
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) UIProgressView *progressView;
@property (nonatomic, strong) UIBarButtonItem *backButtonItem;
@property (nonatomic, strong) UIBarButtonItem *closeButtonItem;
@property (nonatomic, strong) UILabel *authLabel;
@end
@implementation TLWebViewController
- (id)init
{
if (self = [super init]) {
self.useMPageTitleAsNavTitle = YES;
self.showLoadingProgress = YES;
self.showPageInfo = YES;
}
return self;
}
- (id)initWithUrl:(NSString *)urlString
{
if (self = [self init]) {
[self setUrl:urlString];
}
return self;
}
- (id)initWithRequest:(NSURLRequest *)request
{
if (self = [super init]) {
[self loadRequest:request];
}
return self;
}
- (void)loadView
{
[super loadView];
[self.view addSubview:self.authLabel];
[self.view addSubview:self.webView];
[self.view addSubview:self.progressView];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setBackgroundColor:RGBAColor(46.0, 49.0, 50.0, 1.0)];
[self.webView.scrollView setBackgroundColor:[UIColor clearColor]];
for (id vc in self.webView.scrollView.subviews) {
NSString *className = NSStringFromClass([vc class]);
if ([className isEqualToString:@"WKContentView"]) {
[vc setBackgroundColor:[UIColor whiteColor]];
break;
}
}
[self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:NULL];
[self.webView.scrollView addObserver:self forKeyPath:@"backgroundColor" options:NSKeyValueObservingOptionNew context:NULL];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
- (void)dealloc
{
[self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
[self.webView.scrollView removeObserver:self forKeyPath:@"backgroundColor"];
#ifdef DEBUG_MEMERY
NSLog(@"dealloc WebVC");
#endif
}
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
CGFloat statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height;
CGFloat width = self.view.bounds.size.width;
[self.progressView setY:statusBarHeight + navBarHeight];
[self.authLabel setFrame:CGRectMake(20, statusBarHeight + navBarHeight + 13, width - 40, self.authLabel.frame.size.height)];
}
#pragma mark - # Public Methods
- (void)setUrl:(NSString *)url
{
if (_url && url && [_url isEqualToString:url]) {
return;
}
_url = url;
[self.progressView setProgress:0.0f];
[self.webView loadRequest:[NSURLRequest requestWithURL:TLURL(self.url)]];
}
- (void)setShowLoadingProgress:(BOOL)showLoadingProgress
{
_showLoadingProgress = showLoadingProgress;
[self.progressView setHidden:!showLoadingProgress];
}
- (void)loadRequest:(NSURLRequest *)request
{
[self.webView loadRequest:request];
}
- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL
{
if (string) {
[self.webView loadHTMLString:string baseURL:baseURL];
}
}
#pragma mark - # Delegate
//MARK: WKNavigationDelegate
// 开始加载页面
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}
// 开始返回页面内容
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
{
if (webView.canGoBack) {
[self.navigationItem setLeftBarButtonItems:@[[UIBarButtonItem fixItemSpace:-WEBVIEW_NAVBAR_ITEMS_FIXED_SPACE], self.backButtonItem, self.closeButtonItem]];
}
}
// 加载完成
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
if (self.useMPageTitleAsNavTitle) {
[self.navigationItem setTitle:webView.title];
}
if (self.showPageInfo) {
if (webView.URL.host.length > 0) {
[self.authLabel setText:[NSString stringWithFormat:@"网页由 %@ 提供", webView.URL.host]];
}
else {
[self.authLabel setText:@""];
}
[self.authLabel setHeight:[self.authLabel sizeThatFits:CGSizeMake(self.authLabel.width, MAXFLOAT)].height];
}
}
// 加载失败
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
[TLUIUtility showAlertWithTitle:nil message:[error description]];
}
// 页面跳转处理
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation
{
}
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
decisionHandler(WKNavigationResponsePolicyAllow);
}
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSString *urlString = navigationAction.request.URL.absoluteString;
if ([urlString hasPrefix:@"itms-apps://itunes.apple.com"]
|| [urlString hasPrefix:@"https://itunes.apple.com"]
|| [urlString hasPrefix:@"itms-services:"]
|| [urlString hasPrefix:@"tel:"]
|| [urlString hasPrefix:@"mailto:"]
|| [urlString hasPrefix:@"mqqwpa:"]) {
[[UIApplication sharedApplication] openURL:navigationAction.request.URL];
decisionHandler(WKNavigationActionPolicyCancel);
}
else {
decisionHandler(WKNavigationActionPolicyAllow);
}
}
//MARK: WKUIDelegate
// web界面中有弹出警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(nonnull NSString *)message initiatedByFrame:(nonnull WKFrameInfo *)frame completionHandler:(nonnull void (^)(void))completionHandler
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler();
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
// web界面中有确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(nonnull NSString *)message initiatedByFrame:(nonnull WKFrameInfo *)frame completionHandler:(nonnull void (^)(BOOL))completionHandler
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"确定"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
completionHandler(YES);
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"取消"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action){
completionHandler(NO);
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
// web界面中有弹出输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(nonnull NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(nonnull WKFrameInfo *)frame completionHandler:(nonnull void (^)(NSString * _Nullable))completionHandler {
completionHandler(@"Client Not handler");
}
#pragma mark - # Event Response
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (self.showLoadingProgress && [keyPath isEqualToString:@"estimatedProgress"] && object == self.webView) {
[self.progressView setAlpha:1.0f];
[self.progressView setProgress:self.webView.estimatedProgress animated:YES];
if(self.webView.estimatedProgress >= 1.0f) {
[UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{
[self.progressView setAlpha:0.0f];
} completion:^(BOOL finished) {
[self.progressView setProgress:0.0f animated:NO];
}];
}
}
else if ([keyPath isEqualToString:@"backgroundColor"] && object == self.webView.scrollView) {
UIColor *color = [change objectForKey:@"new"];
if (!CGColorEqualToColor(color.CGColor, [UIColor clearColor].CGColor)) {
[object setBackgroundColor:[UIColor clearColor]];
}
}
}
- (void)navBackButotnDown
{
if (self.webView.canGoBack) {
[self.webView goBack];
}
else {
[self.navigationController popViewControllerAnimated:YES];
}
}
- (void)navCloseButtonDown
{
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - # Getters
- (WKWebView *)webView
{
if (_webView == nil) {
_webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, STATUSBAR_HEIGHT + NAVBAR_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - STATUSBAR_HEIGHT - NAVBAR_HEIGHT)];
[_webView setAllowsBackForwardNavigationGestures:YES];
[_webView setNavigationDelegate:self];
[_webView setUIDelegate:self];
[_webView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
}
return _webView;
}
- (UIProgressView *)progressView
{
if (_progressView == nil) {
_progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, NAVBAR_HEIGHT + STATUSBAR_HEIGHT, SCREEN_WIDTH, 10.0f)];
[_progressView setTransform:CGAffineTransformMakeScale(1.0f, 2.0f)];
[_progressView setProgressTintColor:RGBAColor(2.0, 187.0, 0.0, 1.0f)];
[_progressView setTrackTintColor:[UIColor clearColor]];
[_progressView setProgress:0];
}
return _progressView;
}
- (UIBarButtonItem *)backButtonItem
{
if (_backButtonItem == nil) {
_backButtonItem = [[UIBarButtonItem alloc] initWithBackTitle:@"返回" target:self action:@selector(navBackButotnDown)];
}
return _backButtonItem;
}
- (UIBarButtonItem *)closeButtonItem
{
if (_closeButtonItem == nil) {
_closeButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:self action:@selector(navCloseButtonDown)];
}
return _closeButtonItem;
}
- (UILabel *)authLabel
{
if (_authLabel == nil) {
_authLabel = [[UILabel alloc] init];
[_authLabel setFont:[UIFont systemFontOfSize:12.0f]];
[_authLabel setTextAlignment:NSTextAlignmentCenter];
[_authLabel setTextColor:[UIColor grayColor]];
[_authLabel setNumberOfLines:0];
}
return _authLabel;
}
@end