返回 导航

Swift

hangge.com

Swift - 使用Highlightr库实现语法高亮、代码高亮展示(支出实时编辑渲染)

作者:hangge | 2018-11-02 08:19

一、基本介绍

1,什么是 Highlightr ?

  • Highlightr 是一个使用 Swift 编写的语法高亮编辑组件库。其内部核心使用的是 highlight.js
  • Highlightr 可以将原始的代码字符串着色转换成 NSAttributedString,然后在文本框中显示,从而实现代码的语法高亮。

2,安装配置

(1)从 GitHub 上下载最新的代码:https://github.com/raspu/Highlightr
(2)将下载下来的源码包中 Highlightr.xcodeproj 拖拽至你的工程中

(3)工程 -> General -> Embedded Binaries 项,把 iOS 版的 framework 添加进来:Highlightr.framework

(4)最后,在需要使用 Highlightr 的地方 import 进来就可以了
import Highlightr

二、基本用法

1,代码语法高亮显示

下面样例在界面上显示一段简单的代码文字,可以看到关键字都自动有高亮效果:
import UIKit
import Highlightr

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //使用highlightr将代码着色成相应的NSAttributedString
        let highlightr = Highlightr()!
        let code = "let age = 8 //hangge.com"
        let highlightedCode = highlightr.highlight(code, as: "swift")
        
        //创建一个textView用于显示代码
        let textView = UITextView(frame: self.view.frame)
        textView.isEditable = false  //只读
        self.view.addSubview(textView)
        
        //设置显示内容
        textView.attributedText = highlightedCode
    }
}

2,实时编辑着色

上面样式中,代码是预先转换再显示的。如果我们想在输入框编辑时,里面内容能实时渲染(类似做一个 IDE),可以这么做:
import UIKit
import Highlightr

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //将代码着色成响应的NSAttributedString
        let highlightr = Highlightr()!
        let code = "let age = 8 //hangge.com"
        let highlightedCode = highlightr.highlight(code, as: "swift")
        
        //创建 CodeAttributedString
        let textStorage = CodeAttributedString()
        textStorage.language = "Swift"
        let layoutManager = NSLayoutManager()
        textStorage.addLayoutManager(layoutManager)
        
        let textContainer = NSTextContainer(size: view.bounds.size)
        layoutManager.addTextContainer(textContainer)
        
        //创建一个textView用于显示代码
        let textView = UITextView(frame: self.view.frame, textContainer: textContainer)
        self.view.addSubview(textView)
        
        //设置显示内容
        textView.attributedText = highlightedCode
    }
}

三、进阶用法

1,支持的语言

(1)前面提到 Highlightr 库内部使用的是 highlight.js,因此它可以渲染的语言同 highlight.js 一样,目前有 185 种。
(2)除了前面演示的 Swift 外,对于其它语言(比如:xmljavac#phpjssql....)的高亮都是支持的。我们只需设置成对应的语言即可,下面是一个 xml 渲染效果:
let highlightedCode = highlightr.highlight(code, as: "xml")

2,切换主题

(1)同样的,由于 Highlightr 库内部使用的是 highlight.js,那么它一样可以使用 highlight.js 提供的 89 种主题样式。
(2)如果觉得默认的浅色(亮色)主题不好看,我们可以通过 setTheme() 方法设置一个新的主题。比如下面我将其改成一个暗色主题:
注意:主题改变后记得同步修改 UI 颜色,使其风格保持一致。
import UIKit
import Highlightr

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //使用highlightr将代码着色成相应的NSAttributedString
        let highlightr = Highlightr()!
        highlightr.setTheme(to: "paraiso-dark")  //设置渲染主题
        let code = "let age = 8 //hangge.com"
        let highlightedCode = highlightr.highlight(code, as: "swift")
        
        //创建一个textView用于显示代码
        let textView = UITextView(frame: self.view.frame)
        textView.isEditable = false  //只读
        self.view.addSubview(textView)
        
        //设置显示内容
        textView.attributedText = highlightedCode
        
        //根据主题同步改变UI配色
        textView.backgroundColor = highlightr.theme.themeBackgroundColor
        if let navBar = self.navigationController?.navigationBar {
            navBar.barTintColor = highlightr.theme.themeBackgroundColor
            navBar.tintColor = invertColor(navBar.barTintColor!)
            navBar.titleTextAttributes = [.foregroundColor: navBar.tintColor]
        }
    }
    
    //获取反色
    func invertColor(_ color: UIColor) -> UIColor {
        var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0
        color.getRed(&r, green: &g, blue: &b, alpha: nil)
        return UIColor(red:1.0-r, green: 1.0-g, blue: 1.0-b, alpha: 1)
    }
}

附:从外部文件中读取代码并显示

如果要显示的代码比较多,建议将其保存在一个文件中,然后读取并渲染显示:
import UIKit
import Highlightr

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //使用highlightr将代码着色成相应的NSAttributedString
        let highlightr = Highlightr()!
        highlightr.setTheme(to: "paraiso-dark")  //设置渲染主题
        //从文件中读取代码内容
        let file = Bundle.main.path(forResource: "sampleCode", ofType: "txt")!
        let code = try! String.init(contentsOfFile: file)
        let highlightedCode = highlightr.highlight(code, as: "swift")
        
        //创建一个textView用于显示代码
        let textView = UITextView(frame: self.view.frame)
        textView.isEditable = false  //只读
        self.view.addSubview(textView)
        
        //设置显示内容
        textView.attributedText = highlightedCode
        
        //根据主题同步改变UI配色
        textView.backgroundColor = highlightr.theme.themeBackgroundColor
        if let navBar = self.navigationController?.navigationBar {
            navBar.barTintColor = highlightr.theme.themeBackgroundColor
            navBar.tintColor = invertColor(navBar.barTintColor!)
            navBar.titleTextAttributes = [.foregroundColor: navBar.tintColor]
        }
    }
    
    //获取反色
    func invertColor(_ color: UIColor) -> UIColor {
        var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0
        color.getRed(&r, green: &g, blue: &b, alpha: nil)
        return UIColor(red:1.0-r, green: 1.0-g, blue: 1.0-b, alpha: 1)
    }
}
评论

全部评论(0)

回到顶部