将 Contentful 富文本字段渲染为原生字符串和视图
当集成到 iOS 项目中时,此库将 Contentful RichText 渲染为嵌入原生 UIView
的 NSAttributedString
。这是由于该库基于 TextKit 构建,并提供了强大的插件系统来渲染嵌入到 RichText
中的 Contentful 条目和资源。
什么是 Contentful?
Contentful 为数字团队提供内容基础设施,以驱动网站、应用程序和设备。与 CMS 不同,Contentful 是为与现代化软件堆栈集成而构建的。它提供了一个结构化内容的中心枢纽、强大的管理和交付 API,以及可定制的 Web 应用程序,使开发人员和内容创作者能够更快地将他们的产品发布上市。
入门
安装
CocoaPods 安装
platform :ios, '11.0'
use_frameworks!
pod 'ContentfulRichTextRenderer'
Carthage 安装
您还可以使用 Carthage 进行集成,只需将以下内容添加到您的 Cartfile
github "contentful/rich-text-renderer-swift"
将渲染器集成到您的
库的主要入口点为 RichTextViewController
。您可以单独使用它,也可以创建它的子类。RichTextViewController
的 view
实例包含一个使用自定义的 NSLayoutManager
和 NSTextContainer
来布局文本的 UITextView
子视图,允许文本在嵌套视图中自动换行以显示嵌入式资源条目,并且还能实现类似网站上的引用块样式。
import Contentful
import RichTextRenderer
import UIKit
class ViewController: RichTextViewController {
private let client = ContentfulService() /// Your service fetching data from Contentful.
init() {
/// Default configuration of the renderer.
let configuration = DefaultRendererConfiguration()
let renderer = RichTextDocumentRenderer(configuration: configuration)
super.init(renderer: renderer)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
fetchContent()
}
private func fetchContent() {
client.fetchArticle { [weak self] result in
switch result {
case .success(let article):
self?.richTextDocument = article.content
case .failure(let error):
break
}
}
}
}
您可以通过修改 DefaultRendererConfiguration
实例或创建一个符合 RendererConfiguration
协议的新实例来配置渲染器渲染内容。
初始化 DefaultRendererConfiguration
实例提供一组合理的默认设置。只需创建一个实例,然后对其进行修改以进一步自定义渲染。
ResourceLinkBlock
节点渲染视图。
为 您可以通过将视图提供程序传递给配置对象来为 ResourceLinkBlock
节点渲染自定义视图。
var configuration = DefaultRendererConfiguration()
configuration.resourceLinkBlockViewProvider = ExampleBlockViewProvider()
以下是一个示例实现,展示了如何为 Car
模型和 Asset
提供程序进行渲染。
struct ExampleViewProvider: ResourceLinkBlockViewProviding {
func view(for resource: Link, context: [CodingUserInfoKey: Any]) -> ResourceLinkBlockViewRepresentable? {
switch resource {
case .entryDecodable(let entryDecodable):
if let car = entryDecodable as? Car {
return CarView(car: car)
}
return nil
case .entry:
return nil
case .asset(let asset):
guard asset.file?.details?.imageInfo != nil else { return nil }
let imageView = ResourceLinkBlockImageView(asset: asset)
imageView.backgroundColor = .gray
imageView.setImageToNaturalHeight()
return imageView
default:
return nil
}
}
}
final class CarView: UIView, ResourceLinkBlockViewRepresentable {
private let car: Car
var surroundingTextShouldWrap: Bool = false
var context: [CodingUserInfoKey : Any] = [:]
public init(car: Car) {
self.car = car
super.init(frame: .zero)
let title = UILabel(frame: .zero)
title.text = "🚗 " + car.model + " 🚗"
title.translatesAutoresizingMaskIntoConstraints = false
addSubview(title)
title.topAnchor.constraint(equalTo: topAnchor).isActive = true
title.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
title.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
title.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
title.sizeToFit()
frame = title.bounds
backgroundColor = .lightGray
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func layout(with width: CGFloat) {}
}
ResourceLinkInline
节点。
渲染 在 RichTextDocument
中的内联元素可以渲染为 NSMutableAttributedString
对象。
var configuration = DefaultRendererConfiguration()
configuration.resourceLinkInlineStringProvider = ExampleInlineStringProvider()
以下是对应的行内字符串提供者的实现,用于渲染Cat
类型。
import Contentful
import RichTextRenderer
import UIKit
final class ExampleInlineStringProvider: ResourceLinkInlineStringProviding {
func string(
for resource: Link,
context: [CodingUserInfoKey : Any]
) -> NSMutableAttributedString {
switch resource {
case .entryDecodable(let entryDecodable):
if let cat = entryDecodable as? Cat {
return CatInlineProvider.string(for: cat)
}
default:
break
}
return NSMutableAttributedString(string: "")
}
}
private final class CatInlineProvider {
static func string(for cat: Cat) -> NSMutableAttributedString {
return NSMutableAttributedString(
string: "🐈 \(cat.name) ❤️",
attributes: [
.foregroundColor: UIColor.rtrLabel
]
)
}
}
自定义渲染器
库已经实现,允许为特定节点类型提供自定义渲染器。
简单地创建一个继承自默认渲染器之一的类,编写你自己的代码。然后将其附加到DefaultRenderersProvider
即可。
final class ExampleParagraphRenderer: ParagraphRenderer {
typealias NodeType = Paragraph
override func render(
node: Paragraph,
rootRenderer: RichTextDocumentRendering,
context: [CodingUserInfoKey : Any]
) -> [NSMutableAttributedString] {
/// Your code for rendering paragraphs.
}
}
let configuration = DefaultRendererConfiguration()
var renderersProvider = DefaultRenderersProvider()
renderersProvider.paragraph = ExampleParagraphRenderer()
let renderer = RichTextDocumentRenderer(
configuration: configuration,
nodeRenderers: renderersProvider
)
super.init(renderer: renderer)
示例用法
要熟悉在iOS应用程序中使用此库,请查看该存储库中的示例代码。特别是请注意视图提供者和行内提供者,以便了解如何渲染嵌入在富文本中的条目和资源。
你对如何使用此库有疑问吗?
版权
本仓库遵循MIT许可证。
行为准则
我们希望为所有参与者提供一个安全、包容、友好、无骚扰的空间和体验,无论其性别认同、性取向、残疾、外貌、社会经济地位、体型、种族、国籍、经验水平、年龄、宗教(或无宗教)、或其他身份标志。