Fonts 如何使用Swift生成属性字符串?

Fonts 如何使用Swift生成属性字符串?,fonts,uilabel,swift,nsattributedstring,Fonts,Uilabel,Swift,Nsattributedstring,我想做一个简单的咖啡计算器。我需要以克为单位显示咖啡的量。克的“g”符号需要附在我用来显示数量的UILabel上。UILabel中的数字随着用户的输入而动态变化,但我需要在字符串的末尾添加一个小写的“g”,它的格式与更新的数字不同。需要将“g”附加到数字上,以便随着数字大小和位置的变化,“g”随数字一起移动。我相信这个问题以前已经解决了,所以一个指向正确方向的链接会很有帮助,因为我已经用谷歌搜索了我的心 我在文档中搜索了一个属性字符串,我甚至从应用商店下载了一个“属性字符串创建者”,但生成的代码

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

我在文档中搜索了一个属性字符串,我甚至从应用商店下载了一个“属性字符串创建者”,但生成的代码是Objective-C,我正在使用Swift。在Swift中使用属性字符串创建具有自定义属性的自定义字体的一个清晰示例将非常棒,并且可能对学习该语言的其他开发人员有所帮助。这方面的文档非常混乱,因为没有一条非常清晰的路径来说明如何做到这一点。我的计划是创建属性字符串并将其添加到coffeeAmount字符串的末尾

var coffeeAmount: String = calculatedCoffee + attributedText

其中calculatedCoffee是一个转换为字符串的整数,“attributedText”是小写的“g”,带有我试图创建的自定义字体。也许我走错了方向。感谢您的帮助

Swift使用与Obj-C相同的
NSMutableAttributedString
。通过将计算值作为字符串传递来实例化它:

var attributedString = NSMutableAttributedString(string:"\(calculatedCoffee)")
现在创建属性化的
g
字符串(heh)注意:
UIFont.systemFontOfSize(41;
现在是一个可失败的初始值设定项,因此必须先将其展开,然后才能使用它:

var attrs = [NSFontAttributeName : UIFont.systemFontOfSize(19.0)!]
var gString = NSMutableAttributedString(string:"g", attributes:attrs)
然后附加它:

attributedString.appendAttributedString(gString)
然后可以将UILabel设置为显示NSAttribute字符串,如下所示:

myLabel.attributedText = attributedString
textView.attributedText = myString

Swift使用与Obj-C相同的
nsmutableAttributeString
。通过将计算值作为字符串传递来实例化它:

var attributedString = NSMutableAttributedString(string:"\(calculatedCoffee)")
现在创建属性化的
g
字符串(heh)注意:
UIFont.systemFontOfSize(41;
现在是一个可失败的初始值设定项,因此必须先将其展开,然后才能使用它:

var attrs = [NSFontAttributeName : UIFont.systemFontOfSize(19.0)!]
var gString = NSMutableAttributedString(string:"g", attributes:attrs)
然后附加它:

attributedString.appendAttributedString(gString)
然后可以将UILabel设置为显示NSAttribute字符串,如下所示:

myLabel.attributedText = attributedString
textView.attributedText = myString
在beta 6中运行良好

let attrString = NSAttributedString(
    string: "title-title-title",
    attributes: NSDictionary(
       object: NSFont(name: "Arial", size: 12.0), 
       forKey: NSFontAttributeName))
在beta 6中运行良好

let attrString = NSAttributedString(
    string: "title-title-title",
    attributes: NSDictionary(
       object: NSFont(name: "Arial", size: 12.0), 
       forKey: NSFontAttributeName))

Xcode 6版本

let attriString = NSAttributedString(string:"attriString", attributes:
[NSForegroundColorAttributeName: UIColor.lightGrayColor(), 
            NSFontAttributeName: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedStringKey.foregroundColor: UIColor.lightGray, 
            NSAttributedStringKey.font: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedString.Key.foregroundColor: UIColor.lightGray, 
            NSAttributedString.Key.font: AttriFont])
Xcode 9.3版本

let attriString = NSAttributedString(string:"attriString", attributes:
[NSForegroundColorAttributeName: UIColor.lightGrayColor(), 
            NSFontAttributeName: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedStringKey.foregroundColor: UIColor.lightGray, 
            NSAttributedStringKey.font: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedString.Key.foregroundColor: UIColor.lightGray, 
            NSAttributedString.Key.font: AttriFont])
Xcode 10、iOS 12、Swift 4

let attriString = NSAttributedString(string:"attriString", attributes:
[NSForegroundColorAttributeName: UIColor.lightGrayColor(), 
            NSFontAttributeName: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedStringKey.foregroundColor: UIColor.lightGray, 
            NSAttributedStringKey.font: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedString.Key.foregroundColor: UIColor.lightGray, 
            NSAttributedString.Key.font: AttriFont])

Xcode 6版本

let attriString = NSAttributedString(string:"attriString", attributes:
[NSForegroundColorAttributeName: UIColor.lightGrayColor(), 
            NSFontAttributeName: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedStringKey.foregroundColor: UIColor.lightGray, 
            NSAttributedStringKey.font: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedString.Key.foregroundColor: UIColor.lightGray, 
            NSAttributedString.Key.font: AttriFont])
Xcode 9.3版本

let attriString = NSAttributedString(string:"attriString", attributes:
[NSForegroundColorAttributeName: UIColor.lightGrayColor(), 
            NSFontAttributeName: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedStringKey.foregroundColor: UIColor.lightGray, 
            NSAttributedStringKey.font: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedString.Key.foregroundColor: UIColor.lightGray, 
            NSAttributedString.Key.font: AttriFont])
Xcode 10、iOS 12、Swift 4

let attriString = NSAttributedString(string:"attriString", attributes:
[NSForegroundColorAttributeName: UIColor.lightGrayColor(), 
            NSFontAttributeName: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedStringKey.foregroundColor: UIColor.lightGray, 
            NSAttributedStringKey.font: AttriFont])
let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedString.Key.foregroundColor: UIColor.lightGray, 
            NSAttributedString.Key.font: AttriFont])
Swift:xcode 6.1

    let font:UIFont? = UIFont(name: "Arial", size: 12.0)

    let attrString = NSAttributedString(
        string: titleData,
        attributes: NSDictionary(
            object: font!,
            forKey: NSFontAttributeName))
Swift:xcode 6.1

    let font:UIFont? = UIFont(name: "Arial", size: 12.0)

    let attrString = NSAttributedString(
        string: titleData,
        attributes: NSDictionary(
            object: font!,
            forKey: NSFontAttributeName))

对我来说,上述解决方案在设置特定颜色或属性时不起作用

这确实奏效了:

let attributes = [
    NSFontAttributeName : UIFont(name: "Helvetica Neue", size: 12.0)!,
    NSUnderlineStyleAttributeName : 1,
    NSForegroundColorAttributeName : UIColor.darkGrayColor(),
    NSTextEffectAttributeName : NSTextEffectLetterpressStyle,
    NSStrokeWidthAttributeName : 3.0]

var atriString = NSAttributedString(string: "My Attributed String", attributes: attributes)

对我来说,上述解决方案在设置特定颜色或属性时不起作用

这确实奏效了:

let attributes = [
    NSFontAttributeName : UIFont(name: "Helvetica Neue", size: 12.0)!,
    NSUnderlineStyleAttributeName : 1,
    NSForegroundColorAttributeName : UIColor.darkGrayColor(),
    NSTextEffectAttributeName : NSTextEffectLetterpressStyle,
    NSStrokeWidthAttributeName : 3.0]

var atriString = NSAttributedString(string: "My Attributed String", attributes: attributes)

此答案已更新为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

这篇文章的其余部分为那些感兴趣的人提供了更多的细节


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

  • 关键字名称:
    nsattributestring.key.font
    ,值:a
    UIFont
  • 密钥名称:
    nsattributestring.key.foregroundColor
    ,值:a
    UIColor
  • 密钥名称:
    NSAttributedString.key.link
    ,值:an
    NSURL
    NSString
还有很多其他的。更多信息,请参阅。您甚至可以创建自己的自定义属性,如:

  • 关键字名称:
    nsattributestring.key.myName
    ,值:某些类型。
    如果您做出以下选择:

在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

因为属性只是字典,所以您也可以创建它们,方法是创建一个空字典,然后向其中添加键值对。如果该值将包含多个类型,则必须将其用作类型。下面是上面的
多重属性
示例,以这种方式重新创建:

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)
更改属性字符串 例如,让我们在本文顶部创建属性字符串

首先使用新的字体属性创建一个
nsmutableAttributeString

let myAttribute = [ NSAttributedString.Key.font: UIFont(name: "Chalkduster", size: 18.0)! ]
let myString = NSMutableAttributedString(string: "Swift", attributes: myAttribute )
如果正在使用,请将属性化字符串设置为
UITextView
(或
UILabel
)如下所示:

myLabel.attributedText = attributedString
textView.attributedText = myString
您不使用
textView.text

结果如下:

然后附加另一个未设置任何属性的属性字符串。(请注意,尽管我在上面使用了
let
来声明
myString
,但我仍然可以修改它,因为它是一个
nsmutableAttributeString
。这对我来说似乎很难理解,如果这种情况发生变化,我也不会感到惊讶。)
let attr = [NSForegroundColorAttributeName:self.configuration.settingsColor, NSFontAttributeName: self.configuration.settingsFont]

let title = NSAttributedString(string: self.configuration.settingsTitle,
                               attributes: attr)
let attributes = [NSAttributedStringKey.font : UIFont.init(name: "Avenir-Medium", size: 13.0)]
import Prestyler
...
Prestyle.defineRule("$", UIColor.red)
label.attributedText = "\(calculatedCoffee) $g$".prestyled()
   let attributedString = NSAttributedString(string:"targetString",
                                   attributes:[NSAttributedString.Key.foregroundColor: UIColor.lightGray,
                                               NSAttributedString.Key.font: UIFont(name: "Arial", size: 18.0) as Any])
``` Swift
let defaultGenreText = NSAttributedString(string: "Select Genre - Required")
let redGenreText = defaultGenreText.applying(attributes: [NSAttributedString.Key.foregroundColor : UIColor.red], toRangesMatching: "Required")
``
let attributes = [NSAttributedStringKey.font : UIFont(name: CustomFont.NAME_REGULAR.rawValue, size: CustomFontSize.SURVEY_FORM_LABEL_SIZE.rawValue)!]

let attributedString : NSAttributedString = NSAttributedString(string: messageString, attributes: attributes)
protocol AttributedStringComponent {
    var text: String { get }
    func getAttributes() -> [NSAttributedString.Key: Any]?
}

// MARK: String extensions

extension String: AttributedStringComponent {
    var text: String { self }
    func getAttributes() -> [NSAttributedString.Key: Any]? { return nil }
}

extension String {
    func toAttributed(with attributes: [NSAttributedString.Key: Any]?) -> NSAttributedString {
        .init(string: self, attributes: attributes)
    }
}

// MARK: NSAttributedString extensions

extension NSAttributedString: AttributedStringComponent {
    var text: String { string }

    func getAttributes() -> [Key: Any]? {
        if string.isEmpty { return nil }
        var range = NSRange(location: 0, length: string.count)
        return attributes(at: 0, effectiveRange: &range)
    }
}

extension NSAttributedString {

    convenience init?(from attributedStringComponents: [AttributedStringComponent],
                      defaultAttributes: [NSAttributedString.Key: Any],
                      joinedSeparator: String = " ") {
        switch attributedStringComponents.count {
        case 0: return nil
        default:
            var joinedString = ""
            typealias SttributedStringComponentDescriptor = ([NSAttributedString.Key: Any], NSRange)
            let sttributedStringComponents = attributedStringComponents.enumerated().flatMap { (index, component) -> [SttributedStringComponentDescriptor] in
                var components = [SttributedStringComponentDescriptor]()
                if index != 0 {
                    components.append((defaultAttributes,
                                       NSRange(location: joinedString.count, length: joinedSeparator.count)))
                    joinedString += joinedSeparator
                }
                components.append((component.getAttributes() ?? defaultAttributes,
                                   NSRange(location: joinedString.count, length: component.text.count)))
                joinedString += component.text
                return components
            }

            let attributedString = NSMutableAttributedString(string: joinedString)
            sttributedStringComponents.forEach { attributedString.addAttributes($0, range: $1) }
            self.init(attributedString: attributedString)
        }
    }
}
let defaultAttributes = [
    .font: UIFont.systemFont(ofSize: 16, weight: .regular),
    .foregroundColor: UIColor.blue
] as [NSAttributedString.Key : Any]

let marketingAttributes = [
    .font: UIFont.systemFont(ofSize: 20.0, weight: .bold),
    .foregroundColor: UIColor.black
] as [NSAttributedString.Key : Any]

let attributedStringComponents = [
    "pay for",
    NSAttributedString(string: "one",
                       attributes: marketingAttributes),
    "and get",
    "three!\n".toAttributed(with: marketingAttributes),
    "Only today!".toAttributed(with: [
        .font: UIFont.systemFont(ofSize: 16.0, weight: .bold),
        .foregroundColor: UIColor.red
    ])
] as [AttributedStringComponent]
let attributedText = NSAttributedString(from: attributedStringComponents, defaultAttributes: defaultAttributes)
import UIKit

class ViewController: UIViewController {

    private weak var label: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        let label = UILabel(frame: .init(x: 40, y: 40, width: 300, height: 80))
        label.numberOfLines = 2
        view.addSubview(label)
        self.label = label

        let defaultAttributes = [
            .font: UIFont.systemFont(ofSize: 16, weight: .regular),
            .foregroundColor: UIColor.blue
        ] as [NSAttributedString.Key : Any]

        let marketingAttributes = [
            .font: UIFont.systemFont(ofSize: 20.0, weight: .bold),
            .foregroundColor: UIColor.black
        ] as [NSAttributedString.Key : Any]

        let attributedStringComponents = [
            "pay for",
            NSAttributedString(string: "one",
                               attributes: marketingAttributes),
            "and get",
            "three!\n".toAttributed(with: marketingAttributes),
            "Only today!".toAttributed(with: [
                .font: UIFont.systemFont(ofSize: 16.0, weight: .bold),
                .foregroundColor: UIColor.red
            ])
        ] as [AttributedStringComponent]
        label.attributedText = NSAttributedString(from: attributedStringComponents, defaultAttributes: defaultAttributes)
        label.textAlignment = .center
    }
}
    let attrStri = NSMutableAttributedString.init(string:"This is red")
    let nsRange = NSString(string: "This is red").range(of: "red", options: String.CompareOptions.caseInsensitive)
    attrStri.addAttributes([NSAttributedString.Key.foregroundColor : UIColor.red, NSAttributedString.Key.font: UIFont.init(name: "PTSans-Regular", size: 15.0) as Any], range: nsRange)
    self.label.attributedText = attrStri
func createAttributedString(stringArray: [String], attributedPart: Int, attributes: [NSAttributedString.Key: Any]) -> NSMutableAttributedString? {
    let finalString = NSMutableAttributedString()
    for i in 0 ..< stringArray.count {
        var attributedString = NSMutableAttributedString(string: stringArray[i], attributes: nil)
        if i == attributedPart {
            attributedString = NSMutableAttributedString(string: attributedString.string, attributes: attributes)
            finalString.append(attributedString)
        } else {
            finalString.append(attributedString)
        }
    }
    return finalString
}
if let attributedString = createAttributedString(stringArray: ["Hello ", "how ", " are you?"], attributedPart: 2, attributes: [NSAttributedString.Key.foregroundColor: UIColor.systemYellow]) {
      myLabel.attributedText = attributedString
}