前言:本人原本是ios開發工程師,但由於現今H5的興起,行內刮起了一陣混合開發的風氣,趁着這股勁,我也學了前端開發,不說研究的多深,但也能勝任日常的開發工作。長話短說,現今的混合開發應該還處於摸索階段,我們的項目主要頁面都是由網頁做的,只有一些IM、支付、分享、推送、上傳照片這些用的是原生功能,大家都知道ios原生app的體驗一直是很好的,現在改成了混合開發,無疑中就有些舍棄了ios原生的用戶體驗,而這個作為一個向來以用戶體驗為先的開發人員來說,這個真的是難以忍受,所以開始了以優化用戶體驗的為目標的各種嘗試。
優化頁面跳轉功能
app中的翻頁常用的分為兩類,一種通過導航,一種直接跳
1、第一種 直接跳轉 思路大致就是new一個目的頁面,然后設置下頁面跳轉動畫 中間還可以做點目的頁面的數據初始化:
1 ValueInputView *valueView = [[ValueInputView alloc] initWithNibName:@"ValueInputView"bundle:[NSBundle mainBundle]]; 2 3 valueView.delegate = self; 4 5 [valueView setModalTransitionStyle:UIModalTransitionStyleCoverVertical]; 6 7 [self presentModalViewController:valueView animated:YES]; 8 9 //返回 10 11 [self dismissModalViewControllerAnimated:YES];
2、利用UINavigationController,調用pushViewController,進行跳轉;這種采用壓棧和出棧的方式,進行Controller的管理。調用popViewControllerAnimated方法可以返回
PickImageViewController *ickImageViewController = [[PickImageViewController alloc] init]; [self.navigationController pushViewController: ickImageViewController animated:true];
而我們在網頁中的跳轉就很直接,一個webview中轉換不同的URL,很明顯這樣的方法呈現給用戶的體驗很差,所以得想辦法去優化,最好的解決辦法就是去模仿原生的頁面跳轉。為此我查看了很多的知名app,但我發現大多數混合開發的app都只是某幾個頁面用的是網頁開發,然后再webview所在頁面加上進度條,所以給用戶感覺不是很突兀,比如餓了么之類的。但這很明顯不適用於我們的APP,所以我當時想的是這樣做的,加載一個UIScrollView,然后在ScrollView上去添加webview,每點擊一次webview里面的跳轉時,生成一個新的webview添加在第二屏的位置,以此類推每次進入新頁面都可以用這種方式。
//初始化頁面的操作 -(void)initView{ _scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 20, kWidth, kHeight-20)]; _scrollView.backgroundColor = [UIColor whiteColor]; _scrollView.contentSize = CGSizeMake(60*kWidth, kHeight); _scrollView.pagingEnabled = YES; _scrollView.scrollEnabled = NO; _scrollView.bounces = NO; //隱藏水平滾動條 _scrollView.showsHorizontalScrollIndicator = NO; //隱藏垂直滾動條 _scrollView.showsVerticalScrollIndicator = NO; _scrollView.contentOffset = CGPointMake(0, 0); //創建初始的WebView _myWebView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, kWidth, kHeight-20)]; _myWebView.backgroundColor = [UIColor grayColor]; //地址是我亂寫的 NSString *urlString = @"http://www.baidu.com" NSURL *url = [NSURL URLWithString:urlString]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; _myWebView.scrollView.bounces = NO; _myWebView.scalesPageToFit = NO; _myWebView.delegate = self; [_myWebView loadRequest:request]; [self.scrollView addSubview:_myWebView]; [self.view addSubview:_scrollView]; //執行交互操作 [self mutualOCwithJS]; }
//進入下一頁 -(void)nextWeb{ //翻頁動效 CGPoint offSet = self.scrollView.contentOffset; //在新頁面里創建webview UIWebView *webView = [[UIWebView alloc]initWithFrame:CGRectMake(offSet.x+kWidth, 0, kWidth, kHeight-20)]; webView.backgroundColor = [UIColor grayColor]; NSString *urlString = _urlWeb; NSURL *url = [NSURL URLWithString:urlString]; _lastoffset = offSet.x; NSURLRequest *request = [NSURLRequest requestWithURL:url]; webView.scrollView.bounces = NO; webView.scalesPageToFit = YES; webView.delegate = self; [webView loadRequest:request]; [self.scrollView addSubview:webView]; offSet.x += kWidth; [self.scrollView setContentOffset:offSet animated:YES]; //寫入字典 [_webArray addObject:webView]; [_urlArray addObject:urlString]; _count++; [_webDict setObject:_webArray[_count] forKey:_urlArray[_count]]; // [self startAnimation]; //執行交互操作 [self mutualOCwithJS]; }
但這種方式帶來的問題是內存暴漲,顯然還需要優化,於是我想到添加兩個數組去分別存儲新打開頁面的url和webview,
//初始化數組和字典 _webArray = [[NSMutableArray alloc]init]; [_webArray addObject:_myWebView]; _urlArray = [[NSMutableArray alloc]init]; [_urlArray addObject:urlString]; _webDict = [NSMutableDictionary dictionary]; [_webDict setObject:_webArray[_count] forKey:_urlArray[_count]];
當跳轉至頻道頁首頁的時候將數組清空,同時把當前位置變為ScrollView的0位置,
NSString *resultStr = [webView stringByEvaluatingJavaScriptFromString:@"document.body.getAttribute('data')"]; //頁面中含有頻道頁首頁標記 if (![resultStr isEqualToString:@""]) { for (int i = 0; i<_count; i++) { [_webDict removeObjectForKey:_urlArray[0]]; [_webArray[0] stopLoading]; [_webArray[0] removeFromSuperview]; [_webArray removeObjectAtIndex:0]; [_urlArray removeObjectAtIndex:0]; } _count = _webArray.count-1; }
當頁面返回時,把數組的最后一個數據移除,
//返回上一頁 -(void)lastWeb{ //翻頁動效 CGPoint offSet = self.scrollView.contentOffset; if (offSet.x==0) { return; } offSet.x -= kWidth; [self.scrollView setContentOffset:offSet animated:YES]; //銷毀不用的webView [_webArray[_count] stopLoading]; [_webArray[_count] removeFromSuperview]; //刪除字典 [_webDict removeObjectForKey:_urlArray[_count]]; [_webArray removeObjectAtIndex:_count]; [_urlArray removeObjectAtIndex:_count]; _count--; [self mutualOCwithJS]; }
這兩條措施都有效降低內存損耗,同時保證了app頁面跳轉的平滑過渡,當然如果想要想原生app中的手勢右划返回,我們這個也同樣可以完成。
//滑動手勢 - (void)handleSwipes:(UISwipeGestureRecognizer *)sender{ if (sender.direction == UISwipeGestureRecognizerDirectionRight) { [self lastWeb]; } }
當然,我只是提供我的一種思路,而且我們也是這樣做的,可能還會有更好的思路,希望能多補充,共同進步。
