iOS實現(xiàn)webView附件預覽

我們有個需求需要實現(xiàn)攔截點擊webView的附件進行附件下載和預覽咕幻,安卓成功實現(xiàn)渔伯,iOS端一直下載不下來,最后發(fā)現(xiàn)問題在于webView代理拿到的url不全谅河,和安卓對比發(fā)現(xiàn)安卓多了userId和token字段咱旱,iOS攔截下來沒有該參數(shù)确丢,導致下載失敗绷耍。
后面想著直接用webView預覽即可。但是不知道為什么有部分手機不支持預覽鲜侥,直接是打不來的狀態(tài)褂始。
最后使用navigationAction.targetFrame.isMainFrame實現(xiàn)附件預覽。最后遇到返回webView時候會遇到整體字體放大的情況描函,使用navigationAction.targetFrame.isMainFrame還遇到導航欄返回按鈕的處理崎苗。

好在最后這些問題都解決了,記錄下~~~

代碼如下:

#import "C2CustomWebVC.h"
#import "C2GetWhiteListReq.h"

@interface C2CustomWebVC ()<WKNavigationDelegate>
@property (nonatomic, copy) NSString *confValue;
@property (nonatomic, strong) NSArray *whiteListArray;// 白名單列表
@property (nonatomic, copy) NSString *recordUrl;
@property (nonatomic, assign) BOOL needReload;
@property (nonatomic, copy) NSString *url;
@property (nonatomic, strong) UIProgressView *progressView;
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) UIButton *closeButtion;
@property (nonatomic, strong) UIButton *backButton;
@end

@implementation C2CustomWebVC

- (instancetype)initWithUrl:(NSString *)url {
    if (self = [super init]) {
        self.url = url;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self addWebViewObserver];
    [self loadUrl];
    [self buildUI];
}

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self configWebViewFrame];
}

- (void)dealloc{
    [self prepareForClose];
}

- (void)addWebViewObserver{
    if ([self isLocalUrl:self.url]) return;
    [self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:NULL];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
//    DLog(@"keyPath = %@, change = %@", keyPath, change);
    if ([keyPath isEqualToString:@"estimatedProgress"]) {
        if (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 {
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

- (void)prepareForClose{
    @try {
        if ([self isLocalUrl:self.url]) return;
        [self.webView removeObserver:self forKeyPath:@"estimatedProgress" context:NULL];
    } @catch (NSException *exception) {
        
    } @finally {
        [self.webView removeFromSuperview];
    }
}

- (void)configWebViewFrame {
    CGFloat naviHeight = (self.navigationController && !self.navigationController.isNavigationBarHidden) ?kNavigationBarHeight:0;
    CGFloat tabbarHeight = (self.tabBarController && self.navigationController.viewControllers.count==1)?kTabBarHeight:0;
    self.progressView.hidden = [self isLocalUrl:self.url];
    self.webView.frame = CGRectMake(0, 0, kScreenW, kScreenH - naviHeight - tabbarHeight);
}

- (BOOL)isLocalUrl:(NSString *)url {
    return ![url hasPrefix:@"http"];
}

- (void)addLeftBarButtonItems {
    self.backButton.frame = CGRectMake(0, 20+(kIs_iPhoneX?20:0), 55, 44);
    self.closeButtion.frame = CGRectMake(55, 20+(kIs_iPhoneX?20:0), 35, 44);
    UIBarButtonItem *backBarItem = [[UIBarButtonItem alloc] initWithCustomView:self.backButton];
    UIBarButtonItem *closeBarItem = [[UIBarButtonItem alloc] initWithCustomView:self.closeButtion];
    self.navigationItem.leftBarButtonItems = @[backBarItem,closeBarItem];
}

#pragma mark - WKNavigationDelegate

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
       _recordUrl = navigationAction.request.URL.absoluteString;
       if (navigationAction.targetFrame == nil || !navigationAction.targetFrame.isMainFrame) {
           [webView loadRequest:navigationAction.request];
           _needReload = YES;
           decisionHandler(WKNavigationActionPolicyCancel);
           return;
       }
       if (_needReload && ![_recordUrl containsString:@"file/loginlessDownloadFile"]) {
           [webView loadRequest:navigationAction.request];
           _needReload = NO;
       }
        decisionHandler(WKNavigationActionPolicyAllow);
}

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
    DLog(@"開始加載");
                
    WEAKSELF
    [self.webView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error) {
        NSString *userAgent = result;
        //修改UserAgent
        NSString *newUserAgent = [userAgent stringByAppendingString:@"C2Mobile/{1.0.0}"];
        NSString *barHeight = [NSString stringWithFormat:@";statusBarHeight:%f",kStatusBarHeight];
        newUserAgent = [newUserAgent stringByAppendingString:barHeight];
        [wkSelf.webView setCustomUserAgent:newUserAgent];
    }];
    
}
 
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {
    DLog(@"內(nèi)容開始返回");
}
 
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
    DLog(@"加載完成");
    // 禁用縮放
    [self.webView evaluateJavaScript:[self disableZoom] completionHandler:nil];
    // 禁用選中效果
    [self.webView evaluateJavaScript:@"document.documentElement.style.webkitUserSelect='none'" completionHandler:nil];
    [self.webView evaluateJavaScript:@"document.documentElement.style.webkitTouchCallout='none'" completionHandler:nil];
}
 
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error{
    DLog(@"加載navi失敗 error : %@",error.description);
//    WEAKSELF
//    [self showNetworkErrorWithRetryBlock:^{
//        [wkSelf loadUrl];
//    }];
}

- (void)webView:(WKWebView *)webView didFailLoadWithError:(nonnull NSError *)error {
    DLog(@"加載失敗 error : %@",error.description);
}

#pragma mark - Event

- (void)buildUI{
    [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
    self.navigationController.navigationBar.shadowImage = [[UIImage alloc]init];
    if (@available(iOS 11.0, *)) {
        self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    } else {
        self.edgesForExtendedLayout = UIRectEdgeNone;
    }
    [self.view addSubview:self.webView];
    [self.webView addSubview:self.progressView];
    [self addLeftBarButtonItems];
}

- (void)loadUrl{
    if (!self.url.length) {
        DLog(@"url is nil");
        return;
    }
    self.webView.navigationDelegate = self;
    NSString * url = [NSString convertCNtoUnicode:self.url];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    [self.webView loadRequest:request];
}

- (void)close {
    [self backToLastPage];
}

-(BOOL)canGoBack{
    return [self.webView canGoBack];
}

- (void)goBack{
    [self.webView goBack];
}

- (void)actionPopBack{
    if (self.webView.backForwardList.backList.count > 0) {
        WKBackForwardListItem *item = self.webView.backForwardList.currentItem;
        [self goBack];
        [self.webView goToBackForwardListItem:[self.webView.backForwardList.backList firstObject]];
    } else{
        [self backToLastPage];
    }
}

- (void)backToLastPage{
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark - Lazy Load

- (UIProgressView *)progressView {
    if (!_progressView) {
        _progressView = [[UIProgressView alloc]initWithFrame:CGRectMake(0, 0, kScreenW, 1)];
        _progressView.trackTintColor = [UIColor clearColor];
        _progressView.progressTintColor = kColor(40, 178, 254);
    }
    return _progressView;
}

- (WKWebView *)webView {
    if (!_webView) {
        WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc]init];
        WKUserContentController *userCC = [[WKUserContentController alloc] init];
        config.userContentController = userCC;
        
        _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, kScreenW, kScreenH - kNavigationBarHeight) configuration:config];
        _webView.scrollView.showsVerticalScrollIndicator = NO;
        _webView.scrollView.showsHorizontalScrollIndicator = NO;
        if (@available(iOS 13.0,*)) {
            config.defaultWebpagePreferences.preferredContentMode = WKContentModeMobile;
        }
    }
    return _webView;
}

- (UIButton *)closeButtion{
    if (!_closeButtion) {
        _closeButtion = [UIButton buttonWithType:UIButtonTypeCustom];
        [_closeButtion setTitle:@"關閉" forState:UIControlStateNormal];
        _closeButtion.titleLabel.font = [UIFont systemFontOfSize:17];
        _closeButtion.titleLabel.textAlignment = NSTextAlignmentCenter;
        [_closeButtion setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [_closeButtion addTarget:self action:@selector(close) forControlEvents:UIControlEventTouchUpInside];
        _closeButtion.exclusiveTouch = YES;
//        _closeButtion.hidden = YES;
    }
    return _closeButtion;
}

- (UIButton *)backButton{
    if (!_backButton) {
        _backButton = [UIButton buttonWithType:UIButtonTypeCustom];
//        UIImage *btnImage = [UIImage iconWithInfo:TBCityIconInfoMake(@"\U0000E623", 30, [UIColor blackColor])];
        [_backButton setImage:[NSBundle bundleImageWithName:@"back"] forState:UIControlStateNormal];
        [_backButton setTitle:@" 返回" forState:UIControlStateNormal];
        _backButton.titleLabel.font = [UIFont systemFontOfSize:17];
        [_backButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [_backButton addTarget:self action:@selector(actionPopBack) forControlEvents:UIControlEventTouchUpInside];
        _backButton.exclusiveTouch = YES;
    }
    return _backButton;
}

#pragma mark - NSString

- (NSString *)disableZoom {
    return @"var script = document.createElement('meta');"
    "script.name = 'viewport';"
    "script.content=\"width=device-width, user-scalable=no\";"
    "document.getElementsByTagName('head')[0].appendChild(script);";
}

- (NSString *)webViewBridgeScript {
    DLog(@"注入JS");
    return @"";
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舀寓,一起剝皮案震驚了整個濱河市胆数,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌互墓,老刑警劉巖必尼,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異篡撵,居然都是意外死亡判莉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門育谬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來券盅,“玉大人,你說我怎么就攤上這事膛檀∶潭疲” “怎么了娘侍?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長互站。 經(jīng)常有香客問我私蕾,道長,這世上最難降的妖魔是什么胡桃? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任踩叭,我火速辦了婚禮,結果婚禮上翠胰,老公的妹妹穿的比我還像新娘容贝。我一直安慰自己,他們只是感情好之景,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布斤富。 她就那樣靜靜地躺著,像睡著了一般锻狗。 火紅的嫁衣襯著肌膚如雪满力。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天轻纪,我揣著相機與錄音油额,去河邊找鬼。 笑死刻帚,一個胖子當著我的面吹牛潦嘶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播崇众,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼掂僵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了顷歌?” 一聲冷哼從身側響起锰蓬,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎眯漩,沒想到半個月后芹扭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡坤塞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年冯勉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摹芙。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡灼狰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出浮禾,到底是詐尸還是另有隱情交胚,我是刑警寧澤份汗,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站蝴簇,受9級特大地震影響杯活,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜熬词,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一旁钧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧互拾,春花似錦歪今、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至骑疆,卻和暖如春田篇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背箍铭。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工泊柬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坡疼。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓彬呻,卻偏偏與公主長得像衣陶,于是被迫代替她去往敵國和親柄瑰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容