首页 文章

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

提问于
浏览
252

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

我在文档中搜索了一个属性字符串,我甚至从应用程序商店下载了一个“Attributed String Creator”,但结果代码是在Objective-C中,我使用的是Swift . 什么是令人敬畏的,并且可能对其他开发人员学习这种语言有帮助,这是使用Swift中的属性字符串创建具有自定义属性的自定义字体的明显示例 . 这方面的文档非常令人困惑,因为没有非常明确的方法来解决这个问题 . 我的计划是创建属性字符串并将其添加到coffeeAmount字符串的末尾 .

var coffeeAmount: String = calculatedCoffee + attributedText

其中calculateCoffee是一个转换为字符串的Int,“attributedText”是我想要创建的自定义字体的小写“g” . 也许我会以错误的方式解决这个问题 . 任何帮助表示赞赏!

20 回答

  • 16

    属性可以直接在swift 3中设置......

    let attributes = NSAttributedString(string: "String", attributes: [NSFontAttributeName : UIFont(name: "AvenirNext-Medium", size: 30)!,
             NSForegroundColorAttributeName : UIColor .white,
             NSTextEffectAttributeName : NSTextEffectLetterpressStyle])
    

    然后在任何具有属性的类中使用该变量

  • 9

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

    var attributedString = NSMutableAttributedString(string:"\(calculatedCoffee)")
    

    现在创建属性 g 字符串(heh) . Note: UIFont.systemFontOfSize(_) 现在是一个可用的初始化程序,因此必须先将其解包,然后才能使用它:

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

    然后追加它:

    attributedString.appendAttributedString(gString)
    

    然后,您可以设置UILabel以显示NSAttributedString,如下所示:

    myLabel.attributedText = attributedString
    
  • 2

    我强烈建议使用库来归因字符串 . 例如,当您需要一个包含四种不同颜色和四种不同字体的字符串时,它会变得更加容易 . Here is my favorite.它被称为SwiftyAttributes

    如果你想使用SwiftyAttributes制作一个包含四种不同颜色和不同字体的字符串:

    let magenta = "Hello ".withAttributes([
        .textColor(.magenta),
        .font(.systemFont(ofSize: 15.0))
        ])
    let cyan = "Sir ".withAttributes([
        .textColor(.cyan),
        .font(.boldSystemFont(ofSize: 15.0))
        ])
    let green = "Lancelot".withAttributes([
        .textColor(.green),
        .font(.italicSystemFont(ofSize: 15.0))
    
        ])
    let blue = "!".withAttributes([
        .textColor(.blue),
        .font(.preferredFont(forTextStyle: UIFontTextStyle.headline))
    
        ])
    let finalString = magenta + cyan + green + blue
    

    finalString 将显示为

    Shows as image

  • 2

    在iOS上使用Attributed Strings的最佳方法是在界面构建器中使用内置的Attributed Text编辑器,并避免在源文件中使用不必要的硬编码NSAtrributedStringKeys .

    您可以稍后使用此扩展在运行时动态替换placehoderls:

    extension NSAttributedString {
        func replacing(placeholder:String, with valueString:String) -> NSAttributedString {
    
            if let range = self.string.range(of:placeholder) {
                let nsRange = NSRange(range,in:valueString)
                let mutableText = NSMutableAttributedString(attributedString: self)
                mutableText.replaceCharacters(in: nsRange, with: valueString)
                return mutableText as NSAttributedString
            }
            return self
        }
    }
    

    添加一个故事板标签,其属性文本如下所示 .

    enter image description here

    然后,您只需在每次需要时更新该值:

    label.attributedText = initalAttributedString.replacing(placeholder: "<price>", with: newValue)
    

    确保将原始值保存到initalAttributedString中 .

    您可以通过阅读本文来更好地理解这种方法:https://medium.com/mobile-appetite/text-attributes-on-ios-the-effortless-approach-ff086588173e

  • 4

    Swift 4.2

    extension UILabel {
    
        func boldSubstring(_ substr: String) {
            guard substr.isEmpty == false,
                let text = attributedText,
                let range = text.string.range(of: substr, options: .caseInsensitive) else {
                    return
            }
            let attr = NSMutableAttributedString(attributedString: text)
            let start = text.string.distance(from: text.string.startIndex, to: range.lowerBound)
            let length = text.string.distance(from: range.lowerBound, to: range.upperBound)
            attr.addAttributes([NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: self.font.pointSize)],
                               range: NSMakeRange(start, length))
            attributedText = attr
        }
    }
    
  • 3
    func decorateText(sub:String, des:String)->NSAttributedString{
        let textAttributesOne = [NSAttributedStringKey.foregroundColor: UIColor.darkText, NSAttributedStringKey.font: UIFont(name: "PTSans-Bold", size: 17.0)!]
        let textAttributesTwo = [NSAttributedStringKey.foregroundColor: UIColor.black, NSAttributedStringKey.font: UIFont(name: "PTSans-Regular", size: 14.0)!]
    
        let textPartOne = NSMutableAttributedString(string: sub, attributes: textAttributesOne)
        let textPartTwo = NSMutableAttributedString(string: des, attributes: textAttributesTwo)
    
        let textCombination = NSMutableAttributedString()
        textCombination.append(textPartOne)
        textCombination.append(textPartTwo)
        return textCombination
    }
    

    //实现

    cell.lblFrom.attributedText = decorateText(sub: sender!, des: " - \(convertDateFormatShort3(myDateString: datetime!))")
    
  • 16

    enter image description here

    此答案已针对Swift 4.0进行了更新 .

    快速参考

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

    // create attributed string
    let myString = "Swift Attributed String"
    let myAttribute = [ NSAttributedStringKey.foregroundColor: UIColor.blue ]
    let myAttrString = NSAttributedString(string: myString, attributes: myAttribute) 
    
    // set attributed text on a UILabel
    myLabel.attributedText = myAttrString
    

    Text Color

    let myAttribute = [ NSAttributedStringKey.foregroundColor: UIColor.blue ]
    

    Background Color

    let myAttribute = [ NSAttributedStringKey.backgroundColor: UIColor.yellow ]
    

    Font

    let myAttribute = [ NSAttributedStringKey.font: UIFont(name: "Chalkduster", size: 18.0)! ]
    

    enter image description here

    let myAttribute = [ NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue ]
    

    enter image description here

    let myShadow = NSShadow()
    myShadow.shadowBlurRadius = 3
    myShadow.shadowOffset = CGSize(width: 3, height: 3)
    myShadow.shadowColor = UIColor.gray
    
    let myAttribute = [ NSAttributedStringKey.shadow: myShadow ]
    

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


    属性

    字符串属性只是 [NSAttributedStringKey: Any] 形式的字典,其中 NSAttributedStringKey 是属性的键名, Any 是某些Type的值 . 值可以是字体,颜色,整数或其他内容 . Swift中有许多已经预定义的标准属性 . 例如:

    • 键名: NSAttributedStringKey.font ,值:a UIFont

    • 键名: NSAttributedStringKey.foregroundColor ,值:a UIColor

    • 键名: NSAttributedStringKey.link ,值: NSURLString

    还有很多其他的 . 有关详细信息,请参阅this link . 您甚至可以制作自己的自定义属性,例如:

    • 键名: NSAttributedStringKey.myName ,值:某些类型 .
      如果你做extension
    extension NSAttributedStringKey {
        static let myName = NSAttributedStringKey(rawValue: "myCustomAttributeKey")
    }
    

    Creating attributes in Swift

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

    // single attributes declared one at a time
    let singleAttribute1 = [ NSAttributedStringKey.foregroundColor: UIColor.green ]
    let singleAttribute2 = [ NSAttributedStringKey.backgroundColor: UIColor.yellow ]
    let singleAttribute3 = [ NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleDouble.rawValue ]
    
    // multiple attributes declared at once
    let multipleAttributes: [NSAttributedStringKey : Any] = [
        NSAttributedStringKey.foregroundColor: UIColor.green,
        NSAttributedStringKey.backgroundColor: UIColor.yellow,
        NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleDouble.rawValue ]
    
    // custom attribute
    let customAttribute = [ NSAttributedStringKey.myName: "Some value" ]
    

    请注意下划线样式值所需的 rawValue .

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

    var multipleAttributes = [NSAttributedStringKey : Any]()
    multipleAttributes[NSAttributedStringKey.foregroundColor] = UIColor.green
    multipleAttributes[NSAttributedStringKey.backgroundColor] = UIColor.yellow
    multipleAttributes[NSAttributedStringKey.underlineStyle] = NSUnderlineStyle.styleDouble.rawValue
    

    归因于字符串

    既然您了解了属性,那么您可以创建属性字符串 .

    Initialization

    有几种方法可以创建属性字符串 . 如果您只需要一个只读字符串,则可以使用 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: [NSAttributedStringKey.myName: "A value"])
    
    // Initialize with a string and separately declared attribute(s)
    let myAttributes1 = [ NSAttributedStringKey.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: [NSAttributedStringKey.myName: "A value"])
    
    // Initialize with a string and separately declared attribute(s)
    let myAttributes2 = [ NSAttributedStringKey.foregroundColor: UIColor.green ]
    let mutableAttrString4 = NSMutableAttributedString(string: "Hello.", attributes: myAttributes2)
    

    更改归因字符串

    举个例子,让我们在这篇文章的顶部创建一个属性字符串 .

    首先使用新的字体属性创建 NSMutableAttributedString .

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

    如果您正在使用,请将属性字符串设置为 UITextView (或 UILabel ),如下所示:

    textView.attributedText = myString
    

    你不使用 textView.text .

    结果如下:

    enter image description here

    然后追加另一个没有设置任何属性的属性字符串 . (请注意,即使我使用 let 来声明上面的 myString ,我仍然可以修改它,因为它是 NSMutableAttributedString . 这对我来说似乎很不顺便,如果将来发生变化我也不会感到惊讶 . 请给我留言发生 . )

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

    enter image description here

    接下来我们将只选择"Strings"字,它从索引 17 开始,长度为 7 . 请注意,这是 NSRange 而不是Swift Range . (有关范围的更多信息,请参阅this answer . ) addAttribute 方法允许我们将属性键名称放在第一个点,第二个点中的属性值和第三个点中的范围 .

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

    enter image description here

    最后,让's add a background color. For variety, let'使用 addAttributes 方法(注意 s ) . 我可以使用此方法一次添加多个属性,但我只会再添加一个 .

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

    enter image description here

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

    相关

    进一步阅读

  • 18

    Swift:xcode 6.1

    let font:UIFont? = UIFont(name: "Arial", size: 12.0)
    
        let attrString = NSAttributedString(
            string: titleData,
            attributes: NSDictionary(
                object: font!,
                forKey: NSFontAttributeName))
    
  • 1

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

    这确实有效:

    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)
    
  • 817

    我创建了一个解决您问题的在线工具!您可以编写字符串并以图形方式应用样式,该工具为您提供objective-c和swift代码以生成该字符串 .

    也是开源的,所以随意扩展它并发送PR .

    Transformer Tool

    Github

    enter image description here

  • 14

    Swift 4

    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)
    

    您需要删除swift 4中的原始值

  • 4

    Swift 2.0

    Here is a sample:

    let newsString: NSMutableAttributedString = NSMutableAttributedString(string: "Tap here to read the latest Football News.")
    newsString.addAttributes([NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleDouble.rawValue], range: NSMakeRange(4, 4))
    sampleLabel.attributedText = newsString.copy() as? NSAttributedString
    

    要么

    let stringAttributes = [
        NSFontAttributeName : UIFont(name: "Helvetica Neue", size: 17.0)!,
        NSUnderlineStyleAttributeName : 1,
        NSForegroundColorAttributeName : UIColor.orangeColor(),
        NSTextEffectAttributeName : NSTextEffectLetterpressStyle,
        NSStrokeWidthAttributeName : 2.0]
    let atrributedString = NSAttributedString(string: "Sample String: Attributed", attributes: stringAttributes)
    sampleLabel.attributedText = atrributedString
    
  • 4

    在测试版6中运行良好

    let attrString = NSAttributedString(
        string: "title-title-title",
        attributes: NSDictionary(
           object: NSFont(name: "Arial", size: 12.0), 
           forKey: NSFontAttributeName))
    
  • 7
    extension UILabel{
        func setSubTextColor(pSubString : String, pColor : UIColor){    
            let attributedString: NSMutableAttributedString = self.attributedText != nil ? NSMutableAttributedString(attributedString: self.attributedText!) : NSMutableAttributedString(string: self.text!);
    
            let range = attributedString.mutableString.range(of: pSubString, options:NSString.CompareOptions.caseInsensitive)
            if range.location != NSNotFound {
                attributedString.addAttribute(NSForegroundColorAttributeName, value: pColor, range: range);
            }
            self.attributedText = attributedString
        }
    }
    
  • 6

    Xcode 6 version

    let attriString = NSAttributedString(string:"attriString", attributes:
    [NSForegroundColorAttributeName: UIColor.lightGrayColor(), 
                NSFontAttributeName: AttriFont])
    

    Xcode 9.3 version

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

    Xcode 10, iOS 12, Swift 4

    let attriString = NSAttributedString(string:"attriString", attributes:
    [NSAttributedString.Key.foregroundColor: UIColor.lightGray, 
                NSAttributedString.Key.font: AttriFont])
    
  • 1

    用我创建的库来解决你的问题真的很容易 . 它被称为Atributika .

    let calculatedCoffee: Int = 768
    let g = Style("g").font(.boldSystemFont(ofSize: 12)).foregroundColor(.red)
    let all = Style.font(.systemFont(ofSize: 12))
    
    let str = "\(calculatedCoffee)<g>g</g>".style(tags: g)
        .styleAll(all)
        .attributedString
    
    label.attributedText = str
    

    768g

    你可以在这里找到https://github.com/psharanda/Atributika

  • 98

    Swift 2.1 - Xcode 7

    let labelFont = UIFont(name: "HelveticaNeue-Bold", size: 18)
    let attributes :[String:AnyObject] = [NSFontAttributeName : labelFont!]
    let attrString = NSAttributedString(string:"foo", attributes: attributes)
    myLabel.attributedText = attrString
    
  • 2
    let attrString = NSAttributedString (
                string: "title-title-title",
                attributes: [NSAttributedStringKey.foregroundColor: UIColor.black])
    
  • -3
    extension String {
    //MARK: Getting customized string
    struct StringAttribute {
        var fontName = "HelveticaNeue-Bold"
        var fontSize: CGFloat?
        var initialIndexOftheText = 0
        var lastIndexOftheText: Int?
        var textColor: UIColor = .black
        var backGroundColor: UIColor = .clear
        var underLineStyle: NSUnderlineStyle = .styleNone
        var textShadow: TextShadow = TextShadow()
    
        var fontOfText: UIFont {
            if let font = UIFont(name: fontName, size: fontSize!) {
                return font
            } else {
                return UIFont(name: "HelveticaNeue-Bold", size: fontSize!)!
            }
        }
    
        struct TextShadow {
            var shadowBlurRadius = 0
            var shadowOffsetSize = CGSize(width: 0, height: 0)
            var shadowColor: UIColor = .clear
        }
    }
    func getFontifiedText(partOfTheStringNeedToConvert partTexts: [StringAttribute]) -> NSAttributedString {
        let fontChangedtext = NSMutableAttributedString(string: self, attributes: [NSFontAttributeName: UIFont(name: "HelveticaNeue-Bold", size: (partTexts.first?.fontSize)!)!])
        for eachPartText in partTexts {
            let lastIndex = eachPartText.lastIndexOftheText ?? self.count
            let attrs = [NSFontAttributeName : eachPartText.fontOfText, NSForegroundColorAttributeName: eachPartText.textColor, NSBackgroundColorAttributeName: eachPartText.backGroundColor, NSUnderlineStyleAttributeName: eachPartText.underLineStyle, NSShadowAttributeName: eachPartText.textShadow ] as [String : Any]
            let range = NSRange(location: eachPartText.initialIndexOftheText, length: lastIndex - eachPartText.initialIndexOftheText)
            fontChangedtext.addAttributes(attrs, range: range)
        }
        return fontChangedtext
    }
    

    }

    //如下所示使用它

    let someAttributedText = "Some   Text".getFontifiedText(partOfTheStringNeedToConvert: <#T##[String.StringAttribute]#>)
    
  • 6

    Swift 4:

    let attributes = [NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Bold", size: 17)!, 
                      NSAttributedStringKey.foregroundColor: UIColor.white]
    

相关问题