以编程方式将段落标题添加到 UITextView
Posted
技术标签:
【中文标题】以编程方式将段落标题添加到 UITextView【英文标题】:Adding paragraph headings programmatically to a UITextView 【发布时间】:2017-06-16 07:33:32 【问题描述】:我有一个包含 UITextView 的视图控制器。这个 UITextView 根据控制它的数据模型(大约 30 个不同的文本选项)以编程方式更新文本。 UITextView 中的内容总是很长,每个大约 450 个字。段落范围为 2 - 5。
一切都很完美。我只需要一种视觉方式来分解段落。现在,我正在使用 \n\n 在段落之间创建几个换行符。虽然这可行,但我最终还是需要标题。
在 IB 中,我将 text 属性从 Plain 更改为 Attributed。这允许我在 Xcode 中以类似 WYSIWYG 的方式修改文本。效果很好,但我没有使用 IB 来更改文本。
我确实尝试过使用 WebView(下面的代码)。我用 H1 和 P 标签创建了一个非常基本的 html 文件。不幸的是,这将在我的项目中创建 30 多个 HTML 文件。从可管理性的角度来看,我不喜欢这样。文本也不能选择,它与 webview 一起使用(我不想诉诸 CSS [-webkit-user-select] 来缓解这个问题。)
let path: String? = Bundle.main.path(forResource: "myHTML", ofType: "html")
let file = try? String(contentsOfFile: path!, encoding: String.Encoding.utf8)
let baseURL = URL(fileURLWithPath: Bundle.main.bundlePath)
self.myWebView.loadHTMLString(file!, baseURL: baseURL)
我的理想解决方案
我可以坚持我目前的设置吗?使用我的数据模型以编程方式更改 UITextView 文本,同时能够更改代码中的文本属性以创建我的段落标题?
编辑 - 试图让它与 MVC 一起使用
allFormattedDescriptions: [
Formatted(heading: "heading 1", descriptionText: "Lorem Ipsum Paragraph 1"),
Formatted(heading: "heading 2", descriptionText: "Lorem Ipsum Paragraph 2"),
Formatted(heading: "heading 3", descriptionText: "Lorem Ipsum Paragraph 3")
]
// Ideal formatting; every paragraph will have a heading. Can handle that with one object that requires both a heading and description text (paragraph).
struct Formatted
var heading: String!
var descriptionText: String!
var bodyParagraphStyle: NSMutableParagraphStyle =
let style = NSMutableParagraphStyle()
style.lineSpacing = 10
style.paragraphSpacingBefore = 6
style.paragraphSpacing = 6
return style
()
var headerParagraphStyle: NSMutableParagraphStyle =
let style = NSMutableParagraphStyle()
style.paragraphSpacingBefore = 24
return style
()
var bodyAttributes: [String: AnyObject]!
var headerAttributes: [String: AnyObject]!
【问题讨论】:
你绝对可以在代码中做到这一点。NSMutableAttributedString
允许您随意添加和删除属性。您还可以使用它来显示 HTML。如果您不需要 HTML 显示,那么您可以调用 enumerateAttributesInRange
来获取所有属性并修改它们,或者您可以调用 addAttributes
或 setAttributes
来设置各种样式。这包括段落样式和缩进、行距、颜色、下划线、删除线、字体等。
【参考方案1】:
使用NS(Mutable)ParagraphStyle
和NS(Mutable)AttributedString
。例如:
class ViewController: UIViewController
@IBOutlet weak var textView: UITextView!
var allFormattedDescriptions = [
Formatted(heading: "Introduction to Bacon Ipsum", descriptionText: "Bacon ipsum dolor amet jerky pig pastrami capicola biltong turkey, ball tip fatback andouille porchetta flank swine brisket bacon pork loin. Tongue shank cupim, pastrami spare ribs meatball drumstick pork pork chop. Sirloin flank tenderloin bresaola doner, cupim ribeye drumstick ham hock t-bone pork short ribs shoulder. Fatback ribeye pastrami pancetta, chuck turkey andouille boudin burgdoggen shoulder tongue kielbasa doner shankle turducken. Rump strip steak drumstick, shankle cupim prosciutto jerky bacon doner. Pork chop jowl burgdoggen, cow turkey ball tip doner. Cow ham meatball chuck flank meatloaf prosciutto."),
Formatted(heading: "Kielbasa?", descriptionText: "Spare ribs boudin ham leberkas landjaeger filet mignon. Short loin fatback hamburger leberkas chicken. Frankfurter chuck short ribs ball tip, ground round cupim shank brisket venison turducken boudin. Pig sirloin pork loin meatloaf short loin turkey swine.")
]
override func viewDidLoad()
super.viewDidLoad()
let textContent = NSMutableAttributedString()
for (index, desc) in allFormattedDescriptions.enumerated()
let includeLinebreak = index < allFormattedDescriptions.count - 1
textContent.append(desc.attributeString(includeLineBreak: includeLinebreak))
textView.attributedText = textContent
struct Formatted
var heading: String
var descriptionText: String
var bodyParagraphStyle: NSMutableParagraphStyle =
let style = NSMutableParagraphStyle()
style.lineSpacing = 10
style.paragraphSpacingBefore = 6
style.paragraphSpacing = 6
return style
()
var headerParagraphStyle: NSMutableParagraphStyle =
let style = NSMutableParagraphStyle()
style.paragraphSpacingBefore = 24
return style
()
var bodyAttributes: [NSAttributedStringKey: Any]
var headerAttributes: [NSAttributedStringKey: Any]
func attributeString(includeLineBreak: Bool = true) -> NSAttributedString
let result = NSMutableAttributedString()
result.append(NSAttributedString(string: self.heading + "\n", attributes: self.headerAttributes))
result.append(NSAttributedString(string: self.descriptionText, attributes: self.bodyAttributes))
if includeLineBreak
result.append(NSAttributedString(string: "\n", attributes: self.bodyAttributes))
return result as NSAttributedString
init(heading: String, descriptionText: String)
self.heading = heading
self.descriptionText = descriptionText
self.bodyAttributes = [
NSAttributedStringKey.font: UIFont(name: "Hoefler Text", size: 14)!,
NSAttributedStringKey.paragraphStyle: bodyParagraphStyle
]
self.headerAttributes = [
NSAttributedStringKey.font: UIFont(name: "Avenir", size: 22)!,
NSAttributedStringKey.paragraphStyle: headerParagraphStyle,
NSAttributedStringKey.foregroundColor: UIColor.red
]
结果:
【讨论】:
这很好。我喜欢你将正文和段落属性分开的方式。我正在尝试将其分解为 MVC,但经历了一段艰难时期。我只想让模型处理标题和段落文本输入。我的原始帖子有一个小的编辑,以显示我试图向下的路径。任何进一步的建议将不胜感激。以上是关于以编程方式将段落标题添加到 UITextView的主要内容,如果未能解决你的问题,请参考以下文章
如何使用TdxRichEditControl以编程方式添加和获取富文本?
以编程方式将 UISearchBar 添加到普通 ViewController 中以编程方式添加的 UITableView