在实际开发中,UIWebView控件接受一个HTML内容,用于相应的界面,下面是该API的接口:

- (void)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL

由于HTML内容通常是变化的,所以我们需要在内存中生成该HTML内容。比较简单粗暴的做法是将该HTML的基本内容定义在一个NSString中,然后用[NSString stringWothFormat]方法将内容进行格式化,示例如下:

//给对应的标签格式化内容
-(NSString *)demoFormatWithName:(NSString *)name value:(NSString *)value{
NSString *html =
@"<!DOCTYPE html>\n"
"<html lang=\"zh-cn\">\n"
"<head>""\n"
"<meta charset=\"utf-8\">\n"
"<title>这是一个HTML测试</title>\n"
"</head>\n"
"<body>\n"
"<h1>%@</h1>\n"
"<p>%@</p>\n"
"<img src=\"http://img3.redocn.com/20131012/Redocn_2013101208320171.jpg\" width=\"256\" height=\"128\"><br><hr>\n"
"</body>\n"
"</html>";
NSString *content = [NSString stringWithFormat:html,name,value];
return content;
}

但其实我们可以看出,这样写并不舒服,因为:

1、模板内容和代码混在一起,既不方便阅读,也不方便更改;

2、模板内容的渲染逻辑使用简单的[NSString stringWothFormat]来完成,功能单一。在实际开发中,我们很可能需要就原始数据进行二次处理,而这些如果模板渲染模块不能支持,我们就只能自己手工鞋这部分数据二次处理,费时费力。例如,微博的详情页面,如果微博的发送时间小于1天,则需要显示成"xxx小时前",如果小于1分钟,则需要显示成"刚刚"。这些界面渲染方便的逻辑如果能够抽取到专门的排版代码中,则会清晰很多。

所以我们需要一个模板引擎,专门负责这类渲染的工作。

模板引擎复杂的有:MGTemplateEngine(http://mattgemmell.com/mgtemplateengine-templates-with-cocoa/),它的模板语言比较像Smarty、FreeMarker和Django。另外它可以自由的定义Filter,以便实现上面提到的自定义渲染逻辑。它需要依赖RegexKit,RegexKit是一个正则表达式工具类,提供强大的表达式匹配和替换功能。

也有简单的是:GRMustache(https://github.com/groue/GRMustache),它比MGTemplateEngine的功能更简单。另外GRMustache在开源社区更加活跃、更新更加频繁。

对于上面的示例代码,在使用GRMustache模板后,我们首先需要调整模板的内容:

1、将模板内容放在一个单独的文件中,方便日后更改,如template.html

2、将原来的%@替换成{{ name }}的形式。

例如调整后的模板内容为:(文件名为:template.html)

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<title>这是一个HTML测试</title>
</head>
<body>
<h1> {{ name }} </h1>
<p> {{ content }} </p>
<img src="http://img3.redocn.com/20131012/Redocn_2013101208320171.jpg" width="256" height="128"><br><hr>
</body>
</html>

即如图:template.html

然后我们在代码中将该文件读取到内存中,再使用GRMustache的renderObject方法生成渲染后的HTML内容,示例代码如下:

//给template.html中对应的标签格式化内容
-(NSString *)demoFormatWithName:(NSString *)name value:(NSString *)value{
NSString *fileName = @"template.html";
NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:fileName];
NSString *template = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSDictionary *renderObject = @{@"name":name,@"content":value};
NSString *content = [GRMustacheTemplate renderObject:renderObject fromString:template error:nil];
return content;
}

这样,我们使用GRMustache模板引擎成功完成了HTML内容的渲染工作,之后就可以通过UIWebView来加载HTML的内容了:

    _webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:_webView]; //通得模板渲染得到内容(可以随时修改对应标签的内容)
NSString *rendering = [self demoFormatWithName:@"标题" value:@"内容"];
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseUrl = [NSURL fileURLWithPath:path];
[self.webView loadHTMLString:rendering baseURL:baseUrl];

下载GRMustache框架如下:

  

Code:

#import "ViewController.h"
#import <GRMustache.h> @interface ViewController ()
@property (strong,nonatomic)UIWebView *webView;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
_webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:_webView]; //通得模板渲染得到内容(可以随时修改对应标签的内容)
NSString *rendering = [self demoFormatWithName:@"标题" value:@"内容"];
NSLog(@"\n%@",rendering);
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseUrl = [NSURL fileURLWithPath:path];
[self.webView loadHTMLString:rendering baseURL:baseUrl];
} //给template.html中对应的标签格式化内容
-(NSString *)demoFormatWithName:(NSString *)name value:(NSString *)value{ NSString *fileName = @"template.html";
NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:fileName];
NSString *template = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSDictionary *renderObject = @{@"name":name,@"content":value};
NSString *content = [GRMustacheTemplate renderObject:renderObject fromString:template error:nil];
return content;
} @end

打印渲染后HTML内容如下:

-- ::42.629 JSWeb[:] 

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<title>这是一个HTML测试</title>
</head>
<body>
<h1> 标题 </h1>
<p> 内容 </p>
<img src="http://img3.redocn.com/20131012/Redocn_2013101208320171.jpg" width="" height=""><br><hr>
</body>
</html>

webView显示渲染后的HTML内容如下:

GRMutstache提供的渲染HTML内容的核心类方法大概有如下这些:

+ (instancetype)templateFromString:(NSString *)templateString error:(NSError **)error;

+ (instancetype)templateFromResource:(NSString *)name bundle:(NSBundle *)bundle error:(NSError **)error;

+ (instancetype)templateFromContentsOfFile:(NSString *)path error:(NSError **)error;

+ (instancetype)templateFromContentsOfURL:(NSURL *)URL error:(NSError **)error;

+ (NSString *)renderObject:(id)object fromString:(NSString *)templateString error:(NSError **)error;

+ (NSString *)renderObject:(id)object fromResource:(NSString *)name bundle:(NSBundle *)bundle error:(NSError **)error;

作者提供的示例如:

// Renders "Hello Arthur!"
NSString *rendering = [GRMustacheTemplate renderObject:@{ @"name": @"Arthur" } fromString:@"Hello {{name}}!" error:NULL];
// Renders the `Profile.mustache` resource of the main bundle
NSString *rendering = [GRMustacheTemplate renderObject:user fromResource:@"Profile" bundle:nil error:NULL];
//Reuse templates in order to avoid parsing the same template several times:
GRMustacheTemplate *template = [GRMustacheTemplate templateFromResource:@"Profile" bundle:nil error:nil];
rendering = [template renderObject:arthur error:NULL];
rendering = [template renderObject:barbara error:NULL];
rendering = ...

更多详情内容查看github上的源码:https://github.com/groue/GRMustache

本文参考书籍:《iOS开发进阶--唐巧》

iOS:使用模板引擎渲染HTML界面的更多相关文章

  1. Spring Boot☞ 使用Thymeleaf模板引擎渲染web视图

    静态资源访问 在我们开发Web应用的时候,需要引用大量的js.css.图片等静态资源. 默认配置 Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则: /s ...

  2. SpringBoot:2.SpringBoot整合Thymeleaf模板引擎渲染web视图

    在Web开发过程中,Spring Boot可以通过@RestController来返回json数据,那如何渲染Web页面?Spring Boot提供了多种默认渲染html的模板引擎,主要有以下几种: ...

  3. express使用ejs模板引擎渲染html文件

    小场景小知识点. 在使用express过程中,按照官网教程,利用express生成器很容易初始化express项目模板. 那么初始化项目之后应该如何使用ejs作为模板引擎呢?如下 // 注释掉默认生成 ...

  4. Spring Boot☞ 使用freemarker模板引擎渲染web视图

    效果图 代码 package com.wls.integrateplugs.hello.controller; /** * Created by wls on 2017/8/24. */ import ...

  5. Handlebars模板引擎渲染页面

    基本使用 js: var testTpl = Handlebars.compile($('#test').html()); //模板 var arr = [1,2,3] //数据 $('#box'). ...

  6. 用模板引擎Art-Template渲染空格或换行符引发的一场“命案”

    一.绪论 说实话,真的不知道如何给这篇博客命名,因为我觉得应该有一些小伙伴遇到跟我同样的问题正在抓耳挠腮中. 二.导火索 最近在做一个移动H5翻页的功能,类似于MAKA模板那种.假设大致框架如下 ​ ...

  7. 高性能JavaScript模板引擎原理解析

    随着 web 发展,前端应用变得越来越复杂,基于后端的 javascript(Node.js) 也开始崭露头角,此时 javascript 被寄予了更大的期望,与此同时 javascript MVC ...

  8. SpringBoot系列:Spring Boot使用模板引擎FreeMarker

    一.Java模板引擎 模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档. 在jav ...

  9. SpringBoot系列:Spring Boot使用模板引擎Thymeleaf

    一.Java模板引擎 模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档. 在jav ...

随机推荐

  1. centos7修改主机名

    临时修改: hostname centos7 永久修改: # hostnamectl set-hostname cen07

  2. 测试Oracle 11gr2 RAC 非归档模式下,offline drop数据文件后的数据库的停止与启动测试全过程

    测试Oracle 11gr2 RAC 非归档模式下,offline drop数据文件后的数据库的停止与启动测试全过程 最近系统出现问题,由于数据库产生的日志量太大无法开启归档模式,导致offline的 ...

  3. C++ 系列:C++ 基础 001

    Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...

  4. opencv2 使用鼠标绘制矩形并截取和保存矩形区域图像

    前言 好长时间没写博文了,今天偷偷懒写篇关于opencv2中鼠标响应操作的文章. 鼠标操作属于用户接口设计,以前一直使用Qt来做,但是如果只需要简单的鼠标,键盘操作,直接调用opencv库的函数也未尝 ...

  5. Log4j2 - 配置

    官方文档:http://logging.apache.org/log4j/2.x/index.html 1 概述 Log4j2的配置包含四种方式,其中3种都是在程序中直接调用Log4j2的方法进行配置 ...

  6. 关于AJAX中函数的执行顺序

    考察w3school上的一个实际的例子[1]: <html> <head> <script type="text/javascript"> fu ...

  7. 【软件推荐】 Moom-窗口布局软件(V.3.2.2)【破解+汉化】

    本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书”     下载地址: 软件:https://yunpan.cn/cuTg8rCMTsLT6 ...

  8. 【Unity3d游戏开发】unity3D OnTriggerEnter和OnCollisionEnter的一点个人心得(转载)

    此文为转载,因为最近在做U3D,有一些概念弄得不是很清楚,看到这篇博客讲的不错,就转载过来了,方便自己随时查看. ------------------------------------------- ...

  9. 洛谷 P1387 最大正方形 Label:奇怪的解法

    题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m ...

  10. js 爱恨情仇说 this

    this 相信大家在写代码的时候都会遇到,可是怎么样才能用好this,估计这个还是有点困难的,虽然你有时候你会用到,但是他所在的具体的几个场景中所代表的是什么意思了?可能这个你就不是很清楚啊.这个就会 ...