開篇
忽然發現最近也只有值班才能寫東西了,中間更新了兩篇其他的斷了下商城相關的文章,仔細看了看之前覺得干貨太少,今天寫點實際的吧,閑說少說商城相關的更新今天繼續吧,哈哈。前兩篇文章:iOS走近商城APP(一) ,iOS走近商城APP(二 購物車常用控件)(今天值班整座大樓一如既往的靜悄悄,膽小怪我咯-_-、)。
主要內容
- 使用WKWebView替換Webview
WKWebView的html網頁的加載方法
WKWebView顯示網頁的base頁面的封裝,點擊頁面的攔截方法
商品詳情頁頁面的自適應布局 - 商品規格選擇框架
基于內容寬度自適應的框架封裝,優化之前介紹的第三方框架帶來的問題
使用WKWebView替換Webview
在商城中,使用html網頁做展示頁面,商品詳情,活動頁面再常見不過,往往有許多,但是
Webview大量使用會存在內存暴增,如果用WKWebView就能大大減少內存,下面就具體介紹一下使用過程,至于WKWebView的原理以及基本的代理這里就不一一列舉了,實戰出發,哈哈。
- 活動頁Webview的替換
簽到頁面.png
如圖我們點擊立即簽到和立即簽錢,會觸發不同的點擊事件,當然在許多別的頁面,我們點擊網頁上的內容還要跳轉到軟件本身的界面,我們的怎么處理他呢?在老的Webview中我們遵循UIWebViewDelegate的代理方法,然后處理方式如下
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
}
攔截點擊事件,然后再方法中做出處理
NSString* urlString=[[request URL] absoluteString];
NSLog(@"%@",urlString);
NSArray* actionArray=[urlString componentsSeparatedByString:@"-"];
for (NSString* actionStr in actionArray) {
if ([actionStr isEqualToString:@"SignNew.StartSign"]) {//跳轉簽到頁面-action
[webView stopLoading];
[self gotoSignIn];
}else if([actionStr isEqualToString:@"Task.TaskDetail"]){//跳轉界面
....代碼原理同上
}else if([actionStr isEqualToString:@"Task.TaskList"]){//跳轉頁面
...代碼原理同上
}
原理就是我們截取到點擊事件然后根據后臺返回的網址進行處理,根據網址中不同的字段跳轉到我們想要跳轉的頁面。
在WKWebView中我們的處理方式如下遵循WKNavigationDelegate代理方法,然后調用方法
#pragma mark - WKWebviewDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
}
在這個方法中進行上述的處理,
NSString *urlString = [navigationAction.request.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@",urlString);
NSArray* actionArray=[urlString componentsSeparatedByString:@"-"];
for (NSString* actionStr in actionArray) {
if ([actionStr isEqualToString:@"SignNew.StartSign"]) {//跳轉頁面-action
[webView stopLoading];
...
}else if([actionStr isEqualToString:@"Task.TaskDetail"]){//跳轉界面
...
}
在處理完跳轉邏輯之后記得加上這句代碼
decisionHandler(WKNavigationActionPolicyAllow);//允許跳轉
下面再放兩個加載時的協議方法
// 頁面加載完成之后調用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
});
}
// 頁面加載失敗時調用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
});
}
- WKWebView 商品詳情頁的自適應布局
如圖所示,商品詳情的時候我們要根據每個商品詳情的不同來對他進行自適應的圖文布局,他并不像我們的活動頁面那么簡單,由于數量比較多,內容不固定因此我們在加載頁面的時候要做處理(但是這個一般就不需要做點擊交互處理了,哈哈),代碼如下
-(WKWebView *)webView{
if (_webView==nil) {
NSString *jScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO];
WKUserContentController *wkUController = [[WKUserContentController alloc] init];
[wkUController addUserScript:wkUScript];
WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
wkWebConfig.userContentController = wkUController;
_webView=[[WKWebView alloc] initWithFrame:CGRectZero configuration:wkWebConfig];
_webView.navigationDelegate = self;
NSURLRequest* request=[NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[_webView loadRequest:request];
}
return _webView;
}
加入一段JS代碼對頁面進行布局處理。
商品詳情的框架封裝
在iOS走近商城APP(二 購物車常用控件)文章中,我們介紹了一個商品詳情布局的控件,雖然有優點,但是也有他的局限性,因為如果在商品規格比較單一,且長度較短或者固定的時候,是很美觀的,但是如果我們想要根據不同的規格長度進行自適應,問題就來了,就出現了商品顯示不完整的情況,今天放一個在那個版本的基礎上自己又重新封裝過的框架吧。效果圖如下
詳情頁布局.png
主要的操作就是優化了根據規格不同,對標簽長度以及換行的計算標準更加的趨向于實際應用。
標簽的自適應計算主要代碼如下(具體可以看git中的源碼):
首先創建系統的函數如下,其效果類似于for in遍歷
- (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
然后再函數中的處理
[_filterData.elements enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
Btnx += btnGap;
CGFloat btnWidth = [self WidthWithString:obj fontSize:14 height:BtnHeight];
btnWidth += 10;//讓文字兩端留出間距
if(btnWidth<minBtnLength)
btnWidth = minBtnLength;
if(btnWidth>maxBtnLength)
btnWidth = maxBtnLength;
if(Btnx + btnWidth > oneLineBtnWidtnLimit)
{
BtnlineNum ++;//長度超出換到下一行
Btnx = btnGap;
}
UIButton *button = [[UIButton alloc] init];
//Y坐標
CGFloat height = btnGapY+ (BtnlineNum*(BtnHeight+btnGapY));
// NSLog(@"Y坐標-------------%f",height);
button.frame = CGRectMake(Btnx, height,
btnWidth,BtnHeight );
//此處省略按鈕的具體屬性的設置
[button addTarget:self action:@selector(buttonSelected:)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
[_buttons addObject:button];
Btnx = button.frame.origin.x + button.frame.size.width + btnGap;
totalHeight = height; //行高為最大的Y坐標加高度
下面放上一個詳細舉例的gif效果圖。
代碼傳送門GSFilterView,有用的可以點個星哦。
后記
慣例閑扯時間,哈哈,下一篇將寫一下runloop在訂單列表中的實際應用,獲取通訊錄手機號碼以及iOS9與iOS8下的處理等,督促自己一波哈哈。