如何使用 Swift 创建属性字符串?

2024-01-04

我正在尝试制作一个简单的咖啡计算器。我需要以克为单位显示咖啡的量。克的“g”符号需要附加到我用来显示数量的 UILabel 上。 UILabel 中的数字会随着用户输入而动态变化,但我需要在字符串末尾添加一个小写“g”,其格式与更新数字不同。 “g”需要附加到数字上,以便随着数字大小和位置的变化,“g”随数字“移动”。我确信这个问题之前已经解决了,所以正确方向的链接会很有帮助,因为我已经用谷歌搜索了我的小心脏。

我已经在文档中搜索了属性字符串,甚至从应用商店下载了“属性字符串创建器”,但生成的代码是 Objective-C 格式的,而我使用的是 Swift。一个在 Swift 中使用属性字符串创建具有自定义属性的自定义字体的清晰示例将是很棒的,并且可能对学习这种语言的其他开发人员有所帮助。有关此操作的文档非常混乱,因为没有非常明确的说明如何执行此操作的路径。我的计划是创建属性字符串并将其添加到我的 CoffeeAmount 字符串的末尾。

var coffeeAmount: String = calculatedCoffee + attributedText

其中calculatedCoffee是转换为字符串的Int,“attributedText”是小写“g”,带有我试图创建的自定义字体。也许我的处理方式是错误的。任何帮助表示赞赏!


此答案已针对 Swift 4.2 进行更新。

快速参考

制作和设置属性字符串的一般形式如下。您可以在下面找到其他常见选项。

// create attributed string
let myString = "Swift Attributed String"
let myAttribute = [ NSAttributedString.Key.foregroundColor: UIColor.blue ]
let myAttrString = NSAttributedString(string: myString, attributes: myAttribute) 

// set attributed text on a UILabel
myLabel.attributedText = myAttrString
let myAttribute = [ NSAttributedString.Key.foregroundColor: UIColor.blue ]
let myAttribute = [ NSAttributedString.Key.backgroundColor: UIColor.yellow ]
let myAttribute = [ NSAttributedString.Key.font: UIFont(name: "Chalkduster", size: 18.0)! ]
let myAttribute = [ NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue ]
let myShadow = NSShadow()
myShadow.shadowBlurRadius = 3
myShadow.shadowOffset = CGSize(width: 3, height: 3)
myShadow.shadowColor = UIColor.gray

let myAttribute = [ NSAttributedString.Key.shadow: myShadow ]

本文的其余部分为感兴趣的人提供了更多详细信息。


属性

字符串属性只是一个字典形式[NSAttributedString.Key: Any], where NSAttributedString.Key是属性的键名,Any是某种类型的值。该值可以是字体、颜色、整数或其他内容。 Swift 中有许多已经预定义的标准属性。例如:

  • 按键名称:NSAttributedString.Key.font,值:aUIFont
  • 按键名称:NSAttributedString.Key.foregroundColor,值:aUIColor
  • 按键名称:NSAttributedString.Key.link,值:一个NSURL or NSString

还有很多其他的。看这个链接 https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/AttributedStrings/Articles/standardAttributes.html了解更多。您甚至可以创建自己的自定义属性,例如:

  • 按键名称:NSAttributedString.Key.myName,值:某种类型。
    如果你做了一个扩大 https://stackoverflow.com/q/33942483/3681880:

    extension NSAttributedString.Key {
        static let myName = NSAttributedString.Key(rawValue: "myCustomAttributeKey")
    }
    

在 Swift 中创建属性

您可以像声明任何其他字典一样声明属性。

// single attributes declared one at a time
let singleAttribute1 = [ NSAttributedString.Key.foregroundColor: UIColor.green ]
let singleAttribute2 = [ NSAttributedString.Key.backgroundColor: UIColor.yellow ]
let singleAttribute3 = [ NSAttributedString.Key.underlineStyle: NSUnderlineStyle.double.rawValue ]

// multiple attributes declared at once
let multipleAttributes: [NSAttributedString.Key : Any] = [
    NSAttributedString.Key.foregroundColor: UIColor.green,
    NSAttributedString.Key.backgroundColor: UIColor.yellow,
    NSAttributedString.Key.underlineStyle: NSUnderlineStyle.double.rawValue ]

// custom attribute
let customAttribute = [ NSAttributedString.Key.myName: "Some value" ]

请注意rawValue这是下划线样式值所需要的。

因为属性只是字典,所以您还可以通过创建一个空字典,然后向其中添加键值对来创建它们。如果该值包含多种类型,那么您必须使用Any https://craiggrummitt.wordpress.com/2016/09/16/any-vs-anyobject-vs-nsobject-in-swift-3/作为类型。这里是multipleAttributes上面的示例,以这种方式重新创建:

var multipleAttributes = [NSAttributedString.Key : Any]()
multipleAttributes[NSAttributedString.Key.foregroundColor] = UIColor.green
multipleAttributes[NSAttributedString.Key.backgroundColor] = UIColor.yellow
multipleAttributes[NSAttributedString.Key.underlineStyle] = NSUnderlineStyle.double.rawValue

属性字符串

现在您已经了解了属性,您可以创建属性字符串。

初始化

有几种方法可以创建属性字符串。如果您只需要一个只读字符串,您可以使用NSAttributedString。以下是一些初始化方法:

// Initialize with a string only
let attrString1 = NSAttributedString(string: "Hello.")

// Initialize with a string and inline attribute(s)
let attrString2 = NSAttributedString(string: "Hello.", attributes: [NSAttributedString.Key.myName: "A value"])

// Initialize with a string and separately declared attribute(s)
let myAttributes1 = [ NSAttributedString.Key.foregroundColor: UIColor.green ]
let attrString3 = NSAttributedString(string: "Hello.", attributes: myAttributes1)

如果稍后需要更改属性或字符串内容,则应该使用NSMutableAttributedString。这些声明非常相似:

// Create a blank attributed string
let mutableAttrString1 = NSMutableAttributedString()

// Initialize with a string only
let mutableAttrString2 = NSMutableAttributedString(string: "Hello.")

// Initialize with a string and inline attribute(s)
let mutableAttrString3 = NSMutableAttributedString(string: "Hello.", attributes: [NSAttributedString.Key.myName: "A value"])

// Initialize with a string and separately declared attribute(s)
let myAttributes2 = [ NSAttributedString.Key.foregroundColor: UIColor.green ]
let mutableAttrString4 = NSMutableAttributedString(string: "Hello.", attributes: myAttributes2)

更改属性字符串

作为示例,让我们在本文顶部创建属性字符串。

首先创建一个NSMutableAttributedString具有新的字体属性。

let myAttribute = [ NSAttributedString.Key.font: UIFont(name: "Chalkduster", size: 18.0)! ]
let myString = NSMutableAttributedString(string: "Swift", attributes: myAttribute )

如果您正在合作,请将属性字符串设置为UITextView (or UILabel) 像这样:

textView.attributedText = myString

You don't use textView.text.

结果如下:

然后附加另一个未设置任何属性的属性字符串。 (请注意,即使我使用let声明myString上面,我仍然可以修改它,因为它是NSMutableAttributedString。这对我来说似乎不太像,如果将来这种情况发生变化,我不会感到惊讶。发生这种情况时请给我留言。)

let attrString = NSAttributedString(string: " Attributed Strings")
myString.append(attrString)

接下来我们只选择“Strings”单词,它从索引开始17并且长度为7。请注意,这是一个NSRange而不是斯威夫特Range. (See 这个答案 https://stackoverflow.com/a/35193481/3681880有关范围的更多信息。)addAttribute方法让我们将属性键名称放在第一个位置,将属性值放在第二个位置,将范围放在第三个位置。

var myRange = NSRange(location: 17, length: 7) // range starting at location 17 with a lenth of 7: "Strings"
myString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red, range: myRange)

最后,让我们添加背景颜色。为了多样化,我们使用addAttributes方法(注意s)。我可以使用此方法一次添加多个属性,但我只会再次添加一个。

myRange = NSRange(location: 3, length: 17)
let anotherAttribute = [ NSAttributedString.Key.backgroundColor: UIColor.yellow ]
myString.addAttributes(anotherAttribute, range: myRange)

请注意,属性在某些地方是重叠的。添加属性不会覆盖已有的属性。

Related

  • 如何更改文本NSMutableAttributedString但保留属性 https://stackoverflow.com/a/34628596/3681880

进一步阅读

  • 如何从点击位置检索属性 https://stackoverflow.com/a/32262426/3681880
  • 属性字符串编程指南 https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/AttributedStrings/AttributedStrings.html(信息非常丰富,但不幸的是仅在 Objective-C 中)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Swift 创建属性字符串? 的相关文章

随机推荐

  • 如何将 Visual Studio 附加到尚未启动的进程?

    我的 NET 程序由于某些原因无法从 Visual Studio 运行 从 Excel 2010 模板项目创建的 Excel 文件 我需要调试启动事件 如果我想调试程序初始化后发生的事件 那么没有问题 我从资源管理器运行该程序 将进程附加到
  • 如何在Android-ndk中将变量内容输出到“LogCat”窗口

    我在 Eclipse ADT 环境中使用 Android sdk ndk 在Android sdk Java开发中 我可以使用 Log i Log w 语句将消息和变量内容输出到 LogCat 窗口 然而 在Android ndk C C
  • 创建按字母顺序索引的列表 (ColdFusion + Microsoft SQL Server)

    我目前正在努力寻找知道如何做到这一点的人 我尝试了几种不同的方法 最终得到了一半的结果 但并不完全是我想要的 基本上我正在尝试创建一个显示所有乐队 A Z 的列表 但乐队名称是从数据库中调用的 所以我必须在嵌套列表中使用 band name
  • 如何验证“Cache-Control”、“无缓存、无存储、必须重新验证”

    我正在学习缓存以及如何管理它 当我打开网站页面时 我可以看到图像 css 文件 js 文件等静态内容存储在临时文件夹中 但现在 当我在响应标头中添加这些属性时 我看不到缓存行为的任何变化 所有内容都像以前一样被存储 即使我在 js 文件中进
  • Thymeleaf:我可以在表达式中使用消息吗

    我在 Spring Boot 应用程序中使用 Thymeleaf 3 目前 我想在 EL 表达式 Spring EL 中使用消息表达式 第一个用例 修剪消息 data title message key trim 第二个用例 有条件地创建一
  • 如何停止工作表中的程序执行?

    如何在 Scala 工作表中停止程序执行 如果代码正在执行并且不返回 无限循环 那么似乎不可能在不重新启动 Eclipse 的情况下停止程序执行 From https github com scala ide scala worksheet
  • 如何在 Linux 中终止单个 TCP 连接?

    我有一个进程在不同的端口上打开到多个浏览器的多个 tcp 连接 使用 netsat 的输出是这样的 tcp 0 0 server1 something myprog client1 something 49987 ESTABLISHED t
  • jQuery DataTables - 启动缓慢,“正常”html 表显示在开头

    我正在使用 jQuery DataTable 插件 但我担心脚本加载似乎需要一些时间 所以我的网页总是首先显示普通的 html 表格 在所有脚本完成后 该表格将变成 DataTable 我觉得这种样子不太能接受 所以希望能在这里得到一些建议
  • 在 IOS 上启用语音时,移动菜单无法打开

    我正在使用 Safari 浏览器在 ios 中打开我的网站 移动菜单工作正常 当我点击菜单图标 三行图标 时它会打开 但是 当我启用语音然后进入浏览器并点击该菜单图标时 移动菜单未打开 这是CSS问题还是我必须添加一些aria属性 有人能帮
  • 将全局变量传递给类和函数的替代方法

    我是 python 新手 我一直在使用global将变量传递给其他函数被认为是新手 也是一种不好的做法 我想不再使用全局变量 但我不知道该怎么做 现在 我有一个在 wxPython 中创建的 UI 作为其自己的单独类 并且我有另一个从 in
  • 当我序列化对象时出现 StackOverflowError

    我想用这个方法序列化一个对象 public void serializ CRDT m throws IOException ByteArrayOutputStream byteOutput new ByteArrayOutputStream
  • std::vector 在不知道元素类型的情况下插入

    假设我有一个接受各种向量的模板化函数 但由于各种原因我不能在模板参数中提及这一点 这就是我想要做的 在特定位置插入一个新的默认构造元素 而不知道其类型 template
  • 使用 sm.OLS 时需要添加常量吗?

    我正在对两组数据 Y 和 X 执行 OLS 我使用 statsmodel api OLS 然而 无论我之前是否向 X 添加常量 我发现一些非常不同的结果 这是代码 import statsmodels api as sm import nu
  • RestructedText 文件中可能存在文本的私有部分吗?

    我正在将公司的一些文档从 md 转换为 rst 以便在 ReadTheDocs com 中显示 其中一些文档中的内部部分不适合我们的客户使用 有没有办法标记这些部分 以便 Sphinx 不会将其呈现为 HTML Use the ifconf
  • 单击按钮时发出警报并将用户移动到打开的新选项卡

    我创建了一个带有链接的按钮 该链接在新选项卡中打开 我还使用了 javascript 来发出警报 目前这段代码运行完美 但是在 警报 中单击 确定 后 用户仍停留在同一页面上 但我想将用户移至新打开的选项卡 是否可以 我的代码是
  • strtok调用时出现问题

    我有一个像这样使用 strtok 的函数 void f1 char name char tmp tmp strtok names while tmp tmp strtok NULL 我有一个电话 f1 abc def 问题是在第一次调用中
  • 无法实例化名为 ADBannerView 的类

    我试图在我的应用程序底部插入 iad 横幅 但在遵循教程后不断出现错误 代码如下 interface DMKHomeViewController UIViewcontroller
  • 手动创建 pyspark 数据框

    我正在尝试根据某些数据手动创建 pyspark 数据框 row in 1566429545575348 40 353977 111 701859 rdd sc parallelize row in schema StructType Str
  • 模板引擎实现

    我目前正在构建这个小型模板引擎 它需要一个参数中包含模板的字符串 以及一个 标签 值 的字典来填充模板 在引擎中 我不知道模板中将包含哪些标签 哪些不会 我目前正在字典上迭代 foreach 解析我放入字符串生成器中的字符串 并将模板中的标
  • 如何使用 Swift 创建属性字符串?

    我正在尝试制作一个简单的咖啡计算器 我需要以克为单位显示咖啡的量 克的 g 符号需要附加到我用来显示数量的 UILabel 上 UILabel 中的数字会随着用户输入而动态变化 但我需要在字符串末尾添加一个小写 g 其格式与更新数字不同 g