The opening
Suddenly found that recently only on duty to write things, the middle of the update of two other broken mall related articles, carefully looked at before feel dry goods too little, today write some practical bar, less said mall related updates continue today, ha ha. The first two articles :iOS approaching mall APP(a),iOS approaching mall APP(two shopping cart common controls)(today on duty the whole building as always quiet, timid blame me -_-,).
The main content
- Use WKWebView to replace Webview WKWebView HTML page loading method WKWebView display page base page encapsulation, click page interception method product details page adaptive layout
- The commodity specification selection framework is based on content width adaptive framework packaging, optimizing the problems introduced previously by third party frameworks
Replace Webview with WKWebView
In the mall, the use of HTML pages to do the display page, commodity details, activity page is very common, however, there are often many, but a lot of use of Webview will exist memory explosion, if you use WKWebView can greatly reduce the memory, the following is a specific introduction to the use process, As for the principle of WKWebView and the basic agent here is not a list, actual combat, ha ha.
- Active page Webview replacement
As shown in the figure, when we click “Sign in now” and “sign in now”, different click events will be triggered. Of course, in many other pages, we click on the content of the web page and jump to the interface of the software itself. How do we deal with it? In the old Webview we followed the delegate method of UIWebViewDelegate, and we did this
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
}Copy the code
Intercept the click event and process it in the method
NSString* urlString=[[request URL] absoluteString];
NSLog(@ "% @",urlString);
NSArray* actionArray=[urlString componentsSeparatedByString:@ "-"];
for (NSString* actionStr in actionArray) {
if ([actionStr isEqualToString:@"SignNew.StartSign"]) {// Jump to the page -action
[webView stopLoading];
[self gotoSignIn];
}else if([actionStr isEqualToString:@"Task.TaskDetail"]) {// Jump to the interface. Code principle is the same as above}else if([actionStr isEqualToString:@"Task.TaskList"]) {// Jump to the page. Code principle is the same as above}Copy the code
The principle is that we intercept the click event and process it according to the url returned by the background, and jump to the page we want to jump to according to the different fields in the URL. In WKWebView we do this by following the WKNavigationDelegate proxy method and then calling the method
#pragma mark - WKWebviewDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
}Copy the code
To do that in this method,
NSString *urlString = [navigationAction.request.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@ "% @",urlString);
NSArray* actionArray=[urlString componentsSeparatedByString:@ "-"];
for (NSString* actionStr in actionArray) {
if ([actionStr isEqualToString:@"SignNew.StartSign"]) {// Jump to page -action[webView stopLoading]; . }else if([actionStr isEqualToString:@"Task.TaskDetail"]) {// Jump to the interface. }Copy the code
Remember to add this code after handling the jump logic
decisionHandler(WKNavigationActionPolicyAllow); // Allow a jumpCopy the code
Here are two more load-time protocol methods
// called after the page has finished loading
- (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];
});
}
// called when page load fails
- (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];
});
}Copy the code
- WKWebView adaptive layout of product details page
As shown, the commodity details when we according to the different details of each item to adaptive his graphic layouts, he is not as easy as our events page, because the quantity is more, the content is not fixed, therefore we have to do at the time of loading the page processing (but this generally do not need to click on the interactive processing, haha), the code is as follows
-(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;
}Copy the code
Add a section of JS code to the layout of the page.
Frame encapsulation of commodity details
In iOS near mall APP (2 shopping cart controls) is commonly used article, we introduced a commodity details the layout of the control, although there are advantages, but also has limitations, because if the product specification is unitary, and the length of the shorter or fixed, it is very beautiful, but if we want to according to the different length of specification of the adaptive, The problem is that the product display is incomplete, so let’s put a repackaged framework based on that version today. The renderings are as follows
The main operation is to optimize the calculation criteria for label length and line feed to be more practical depending on the specification. The main code for tag adaptive calculation is as follows (see the source code in Git for details) : First, create the system function as follows, its effect is similar to for in traversal
- (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);Copy the code
And then the processing in the function
[_filterData.elements enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
Btnx += btnGap;
CGFloat btnWidth = [self WidthWithString:obj fontSize:14 height:BtnHeight];
btnWidth += 10; // Leave space between the two ends of the text
if(btnWidth<minBtnLength)
btnWidth = minBtnLength;
if(btnWidth>maxBtnLength)
btnWidth = maxBtnLength;
if(Btnx + btnWidth > oneLineBtnWidtnLimit)
{
BtnlineNum ++; // Change to the next line
Btnx = btnGap;
}
UIButton *button = [[UIButton alloc] init];//Y coordinate CGFloat height = btnGapY+(BtnlineNum*(BtnHeight+btnGapY));
// NSLog(@"Y -- -- -- -- -- -- -- -- -- -- -- - % f",height);
button.frame = CGRectMake(Btnx, height, btnWidth,BtnHeight );// Omit the specific properties of the button here[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; // The row height is the maximum Y coordinate plus the heightCopy the code
Below is a detailed example of the GIF effect.
Code portal GSFilterView, useful can point a star oh.
Afterword.
In the next article, I will write about runloop’s application to order lists, obtaining phone numbers in the contact list, and processing in iOS9 and iOS8.