在 Swift 中,如何交错 NSMutableParagraphStyle() 和 NSMutableAttributedString 来格式化要在 UITextView 中显示的字符串?

2024-01-26

回应我之前发布的一个例子,Andreas Oetjen 展示了一种巧妙的方法来显示分数和小数表textView使用属性字符串 https://stackoverflow.com/a/42153358/2348597对齐数字,使小数点或正斜杠字符出现在同一列中,如示例 1 所示below。通过对属性字符串的介绍,我被提示问:如何以不同的颜色或字体显示每一列? (将数据与应用程序中其他位置找到的文件类型相关联)

When I try to do this the closest I get is the display shown in Example 2 below and I can’t figure out why the text is not displayed in two columns, one in blue, the other in red with numbers in the red column aligned the same as in Example 1. Example 2 has two issues. Firstly, paragraph formatting of Example 1 is lost when font formatting is introduced and secondly, there are two versions of the text, one in colour, the other in black. I suspect both issues have the same underlying cause. enter image description here

根据 Andreas 的回答,第一个代码示例below组装组成每一行的字符串,然后使用NSMutableParagraphStyle()创建示例 1 中所示的布局 (above)。第二个代码示例在每行附加格式化字符串之前对字符串应用格式化 - 我尝试交错NSMutableParagraphStyle()and NSMutableAttributedString- 创建示例 2 中所示的布局(above)。两者都在 Playground 中进行了测试。在第二个示例中,我尝试切换调用格式化函数的顺序,例如

    appendLeftColumnParagraph(textIn: column1)
    appendLeftColumnFont(i: i)

and

    appendRightColumnParagraph(textIn: column2)
    appendRightColumnFont(i: i)

代替

    appendLeftColumnFont(i: i)
    appendLeftColumnParagraph(textIn: column1)

and

    appendRightColumnFont(i: i)
    appendRightColumnParagraph(textIn: column2)

但这只会使彩色字符出现在黑色字符之后而不是之前。几乎就像我只能期望使用以下任一方法附加属性字符串NSMutableAttributedString or NSMutableParagraphStyle()但不是两者兼而有之。要么是这样,要么是我不理解附加属性字符串的一些基本内容。

所以,假设这是正确的问题,我该如何交错NSMutableParagraphStyle()and NSMutableAttributedString格式化显示的字符串UITextView分为两列,一列为蓝色,另一列为红色,红色列中的数字与示例 1 中的对齐方式相同?

如果有脑细胞新鲜的人能帮我回答这个问题,我将不胜感激。谢谢。

代码示例 1 - 仅使用 NSMutableParagraphStyle()

import UIKit
import PlaygroundSupport

var tuningArray                     = ["1/1", "76.04900", "193.15686", "310.26471", "5/4", "503.42157", "579.47057", "696.57843", "25/16", "889.73529", "1006.84314", "1082.89214"]

var keyArray                        = ["x", "1", "x", "x", "4", "x", "6", "x", "x", "9", "x", "11"]
let scaleSize                       = tuningArray.count
var textMessage                     = ""

for i in 0..<scaleSize {
    var textLine                    = "\t" + keyArray[i] + "\t" + tuningArray[i] + "\n"
    textMessage                     += textLine
}

let paragraphStyle                  = NSMutableParagraphStyle()

let leftTabLocation                 = CGFloat(50)
let rightTabLocation                = CGFloat(185)

var leftTab                         = NSTextTab(textAlignment: .left, location: leftTabLocation, options: [:])

let rightTerminators:CharacterSet   = [".", "/"]
let rightTabOptions                 = [NSTabColumnTerminatorsAttributeName:rightTerminators]
var rightTab                        = NSTextTab(textAlignment: .natural, location: rightTabLocation, options:rightTabOptions)

paragraphStyle.tabStops             = [leftTab, rightTab]

var attributedText                  = NSAttributedString(string:textMessage,attributes: [NSParagraphStyleAttributeName: paragraphStyle])

let formattedText                   = UITextView(frame:CGRect(x:0, y:0, width:300, height:200))
formattedText.attributedText        = attributedText

PlaygroundPage.current.liveView     = formattedText

代码示例 2 - NSMutableParagraphStyle() 和 NSMutableAttributedString.init(string: )

import UIKit
import PlaygroundSupport

var tuningArray                         = ["1/1", "76.04900", "193.15686", "310.26471", "5/4", "503.42157", "579.47057", "696.57843", "25/16", "889.73529", "1006.84314", "1082.89214"]

var keyArray                            = ["x", "1", "x", "x", "4", "x", "6", "x", "x", "9", "x", "11"]

let scaleSize                           = tuningArray.count
var textMessage                         = ""

var textString                          = String()
var formattedString                     = NSAttributedString()

var rangeOfKeyString                    = NSRange()
var attributeKey                        = NSMutableAttributedString()
var rangeOfTuningString                 = NSRange()
var attributeTuning                     = NSMutableAttributedString()

let attributedTextMessage               = NSMutableAttributedString()


func appendLeftColumnParagraph(textIn: String) {
    let paragraphStyle                  = NSMutableParagraphStyle()        
    let leftTabLocation                 = CGFloat(50.0)
    let leftTab                         = NSTextTab(textAlignment: .left, location: leftTabLocation, options: [:])
    paragraphStyle.tabStops             = [leftTab]
    let attributedLeftColumnParagraph   = NSAttributedString(string:textIn, attributes: [NSParagraphStyleAttributeName: paragraphStyle])
    attributedTextMessage.append(attributedLeftColumnParagraph)
}

func appendRightColumnParagraph(textIn: String) {
    let paragraphStyle                  = NSMutableParagraphStyle()
    let rightTabLocation                = CGFloat(185.0)
    let rightSeparators:CharacterSet    = [".", "/"]
    let rightTabOptions                 = [NSTabColumnTerminatorsAttributeName: rightSeparators]
    let rightTab                        = NSTextTab(textAlignment: .natural, location: rightTabLocation, options: rightTabOptions)
    paragraphStyle.tabStops             = [rightTab]
    let attributedRightColumnParagraph  = NSAttributedString(string:textIn, attributes: [NSParagraphStyleAttributeName: paragraphStyle])
    attributedTextMessage.append(attributedRightColumnParagraph)
}

func appendLeftColumnFont(i: Int){
    rangeOfKeyString                    = (keyArray[i] as NSString).range(of: keyArray[i])
    attributeKey                        = NSMutableAttributedString.init(string: keyArray[i])
    attributeKey.addAttribute(NSForegroundColorAttributeName, value: UIColor.blue, range: rangeOfKeyString)
    attributedTextMessage.append(attributeKey)
}

func appendRightColumnFont(i: Int){
    rangeOfTuningString                 = (tuningArray[i] as NSString).range(of: tuningArray[i])
    attributeTuning                     = NSMutableAttributedString.init(string: tuningArray[i])
    attributeTuning.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: rangeOfTuningString)
    attributedTextMessage.append(attributeTuning)
}

func appendTab(){
    let attributedTab                   = NSMutableAttributedString.init(string: "\t")
    attributedTextMessage.append(attributedTab)
}

func appendNewLine(){
    let attributedNewLine               = NSMutableAttributedString.init(string: "\n")
    attributedTextMessage.append(attributedNewLine)
}


for i in 0..<scaleSize {

//    var textLine                        = "\t" + keyArray[i] + "\t" + tuningArray[i] + "\n"

    let column1                         = keyArray[i]
    let column2                         = tuningArray[i]

    appendTab()
    appendLeftColumnFont(i: i)
    appendLeftColumnParagraph(textIn: column1)

    appendTab()
    appendRightColumnFont(i: i)
    appendRightColumnParagraph(textIn: column2)

    appendNewLine()

}

    formattedString                     = attributedTextMessage

let formattedText                       = UITextView(frame:CGRect(x:0, y:0, width:300, height:200))
formattedText.attributedText            = formattedString

PlaygroundPage.current.liveView         = formattedText

您必须将段落样式添加到您附加的每个属性字符串(例如,还添加到新行和制表符);最简单的方法是将样式添加到整个范围的最后:

import UIKit
import PlaygroundSupport

var tuningArray                         = ["1/1", "76.04900", "193.15686", "310.26471", "5/4", "503.42157", "579.47057", "696.57843", "25/16", "889.73529", "1006.84314", "1082.89214"]

var keyArray                            = ["x", "1", "x", "x", "4", "x", "6", "x", "x", "9", "x", "11"]

let scaleSize                           = tuningArray.count
var textMessage                         = ""

var textString                          = String()
var formattedString                     = NSAttributedString()

var rangeOfKeyString                    = NSRange()
var attributeKey                        = NSMutableAttributedString()
var rangeOfTuningString                 = NSRange()
var attributeTuning                     = NSMutableAttributedString()

let attributedTextMessage               = NSMutableAttributedString()

func getParagraphStyles() -> NSMutableParagraphStyle {
    let paragraphStyle                  = NSMutableParagraphStyle()
    let leftTabLocation                 = CGFloat(50.0)
    let leftTab                         = NSTextTab(textAlignment: .left, location: leftTabLocation, options: [:])

    let rightTabLocation                = CGFloat(185.0)
    let rightSeparators:CharacterSet    = [".", "/"]
    let rightTabOptions                 = [NSTabColumnTerminatorsAttributeName: rightSeparators]
    let rightTab                        = NSTextTab(textAlignment: .natural, location: rightTabLocation, options: rightTabOptions)

    paragraphStyle.tabStops             = [leftTab, rightTab]
    return paragraphStyle
}


func appendLeftColumnFont(i: Int){
    rangeOfKeyString                    = (keyArray[i] as NSString).range(of: keyArray[i])
    attributeKey                        = NSMutableAttributedString.init(string: keyArray[i])
    attributeKey.addAttribute(NSForegroundColorAttributeName, value: UIColor.blue, range: rangeOfKeyString)
    attributedTextMessage.append(attributeKey)
}

func appendRightColumnFont(i: Int){
    rangeOfTuningString                 = (tuningArray[i] as NSString).range(of: tuningArray[i])
    attributeTuning                     = NSMutableAttributedString.init(string: tuningArray[i])
    attributeTuning.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: rangeOfTuningString)
    attributedTextMessage.append(attributeTuning)
}

func appendTab(){
    let attributedTab                   = NSMutableAttributedString.init(string: "\t")
    attributedTextMessage.append(attributedTab)
}

func appendNewLine(){
    let attributedNewLine               = NSMutableAttributedString.init(string: "\n")
    attributedTextMessage.append(attributedNewLine)
}


for i in 0..<scaleSize {

    //    var textLine                        = "\t" + keyArray[i] + "\t" + tuningArray[i] + "\n"

    let column1                         = keyArray[i]
    let column2                         = tuningArray[i]

    appendTab()
    appendLeftColumnFont(i: i)

    appendTab()
    appendRightColumnFont(i: i)

    appendNewLine()

}

// Apply paragraph to whole string:
var paragraphStyle = getParagraphStyles()
let fullRange = NSRange(location: 0, length: attributedTextMessage.length)
attributedTextMessage.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: fullRange)

formattedString                     = attributedTextMessage


let formattedText                       = UITextView(frame:CGRect(x:0, y:0, width:300, height:200))
formattedText.attributedText            = formattedString

PlaygroundPage.current.liveView         = formattedText
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Swift 中,如何交错 NSMutableParagraphStyle() 和 NSMutableAttributedString 来格式化要在 UITextView 中显示的字符串? 的相关文章

  • Xcode 11 - 在 Catalyst Swift 中禁用调整大小模式

    We are 将我们基于 Swift 的 iOS 应用程序转换为 Mac兼容使用Catalyst在 Xcode 11 中 当用户使用时 我们在 UI 中面临一个问题resize应用程序窗口 那么我们可以禁用调整大小模式并为应用程序窗口提供修
  • 是否可以对 UILabel 的文本颜色变化进行动画处理? [复制]

    这个问题在这里已经有答案了 UIView animateWithDuration 5 animations myLabel textColor UIColor redColor 标签文本颜色立即改变 Try this UIView tran
  • 视频中的图像/文本叠加 swift

    我正在使用 swift 在视频中使用图像叠加来实现水印效果 我正在使用AVFoundation为此 但不知何故我没有成功 以下是我的覆盖图像 文本的代码 let path NSBundle mainBundle pathForResourc
  • 2 使用我的代码在数组中查询

    我使用滑块来显示我的 WordPress 精选文章 它选择一个自定义类别并返回一定数量的帖子 如何将显示的第一篇帖子设为自定义帖子 我可以直接在滑块代码中添加特定帖子的 ID吗使该帖子首先出现 然后是原始查询返回的其他内容 例如 在页面上
  • UNTimeIntervalNotificationTrigger nextTriggerDate() 是否给出了错误的日期?

    我正在更新本地通知以与 iOS 10 配合使用 但遇到了一个问题 我认为 nextTrigger 函数返回的不是 满足触发条件的下一个日期 而是返回当前日期时间加上您最初设置 UNTimeInvervalNotificationTrigge
  • 如何将项目插入到特定索引处的空数组中?

    我想将一个项目插入到空数组的指定索引中 我看到有 Array prototype splice 方法 但是 如果我在空数组上使用 splice 它只会添加项目来结束数组 如下所示 var a a splice 3 0 item 3 cons
  • 如何删除以前的 ViewController

    我是一名学生 对编程还很陌生 我正在尝试在业余时间学习 Objective C Swift 我使用 spriteKit 和 swift 制作了一个游戏 有多个菜单 场景 我正在尝试从一个视图控制器转换到另一个视图控制器 为此 我使用了以下代
  • Array.of 与“[ ]”。何时使用 Array.of 而不是“[ ]”?

    当我发现时我正在读一些书Array of https developer mozilla org en docs Web JavaScript Reference Global Objects Array of 根据 MDN Array o
  • MATLAB 中的逻辑数组与数值数组

    我正在比较两个二进制数组 我有一个数组 其中值可以是一或零 如果值相同则为 1 如果不同则为零 请注意 我正在做检查之外的其他事情 因此我们不需要进入矢量化或代码的性质 在 MATLAB 中使用数值数组和逻辑数组哪个更有效 Logical
  • 带有预填充 .sqlite 的核心数据 (Swift3)

    目前 我正在对现有 iOS9 应用程序进行 Swift3 iOS10 更新 该应用程序存储了欧洲各地约 10 000 个电动汽车充电点 到目前为止 我总是为应用程序提供预填充的数据库 xcappdata 包中的 sqlite sqlite
  • 如何在 ios 应用程序中将 .svg url 显示为图像

    我从服务器获取 svg 网址 如何在我的应用程序中将其显示为图像 我尝试在 UIWebView 中显示它 但无法调整内容图像的大小 我正在使用这个代码 let request NSURLRequest NSURLRequest url UR
  • shell中如何从数组中随机选择一个项目

    我正在 Shell 脚本中创建一个机器人 Array with expressions expressions Ploink Poink I Need Oil Some Bytes are Missing Poink Poink Piiii
  • 在 Node.js 中一次迭代 50 个项目的数组

    我是 node js 的新手 目前正在尝试编写数组迭代代码 我有一个包含 1 000 个项目的数组 由于服务器负载问题 我想一次迭代 50 个项目的块 我目前使用 forEach 循环 如下所示 我希望将其转换为上述块迭代 result i
  • 快速不平衡调用开始/结束外观转换

    这已经困扰我一段时间了 我有一个UISplitViewController里面一个UITabBarController 主视图是一个TableView 当我单击一个单元格时 我会弹出一个非常基本的视图控制器 其中只有一个UIButton居中
  • 将时间值转换为数字,同时保留时间特征

    我有一个数据集 其中包含不同事件发生的间隔时间 我想要做的是将数据转换为数字向量 以便更容易操作和运行摘要 制作图表等 同时保持其时间特征 这是我的数据片段 data lt c 03 31 12 17 16 29 09 52 04 01 0
  • 如何取消 Alamofire.upload

    我正在通过以下方式将图像上传到服务器上Alamofire upload作为多部分数据 不像Alamofire request它没有回来Request对象 我通常用它来取消请求 但是能够取消上传这样的消耗性请求是非常合理的 阿拉莫菲尔有哪些选
  • 结构体如何存储在内存中?

    我有一个struct iof header在我的代码中 我确定它的宽度是 24 字节 我执行 sizeof iof header 它返回 32 字节宽 问题1为什么是 32 字节宽而不是 24 字节宽 问题2包括其成员在内 结构体如何存储在
  • 如何比双击更快地识别单击?

    我有一个UITableView与我添加单击的行and双击手势 let doubleTap UITapGestureRecognizer target self action doubleTap doubleTap numberOfTapsR
  • Android 中的垂直(旋转)标签

    我需要两种在 Android 中显示垂直标签的方法 水平标签逆时针旋转 90 度 字母在侧面 带有字母的水平标签 如商店招牌 我是否需要为这两种情况 一种情况 开发自定义小部件 我可以使 TextView 以这种方式呈现吗 如果我需要完全自
  • 无法在 Swift 的 Storyboard 中加载 UIViewController XIB 文件

    我读了使用 XCode 故事板实例化使用 XIB 进行设计的视图控制器 https stackoverflow com questions 9155719 using xcode storyboard to instantiate view

随机推荐