Як зробити атрибутивний рядок за допомогою Swift?


316

Я намагаюся зробити простий кавовий калькулятор. Мені потрібно вивести кількість кави в грамах. Символ "g" для грамів повинен бути прикріплений до мого UILabel, який я використовую для відображення суми. Цифри в UILabel динамічно змінюються, введення користувача просто чудово, але мені потрібно додати нижній регістр "g" на кінці рядка, який відформатований інакше, ніж оновлення чисел. До цифр потрібно приєднати "g", щоб у міру зміни розміру чи позиції число "g" "рухалося" цифрами. Я впевнений, що ця проблема була вирішена раніше, тому посилання в правильному напрямку було б корисним, оскільки я вирвав своє маленьке серце.

Я шукав документацію щодо атрибутованого рядка, і навіть заблокував "Attributed String Creator" з магазину додатків, але отриманий код знаходиться в Objective-C, і я використовую Swift. Що було б дивним і, мабуть, корисним для інших розробників, які вивчають цю мову, - це наочний приклад створення користувацького шрифту за допомогою спеціальних атрибутів за допомогою атрибутованого рядка в Swift. Документація для цього дуже заплутана, оскільки не існує дуже чіткого шляху, як це зробити. Мій план полягає в тому, щоб створити атрибутивну рядок і додати її до кінця мого рядка coffeeAmount.

var coffeeAmount: String = calculatedCoffee + attributedText

Якщо izračunaCoffee - це Int, перетворений на рядок, а "attributeText" - це мале "g" з налаштованим шрифтом, який я намагаюся створити. Можливо, я йду про це неправильним шляхом. Будь-яка допомога вдячна!

Відповіді:


969

введіть тут опис зображення

Цю відповідь було оновлено для 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], де NSAttributedString.Keyє ключовим назвою атрибута і Anyє значенням якогось типу. Значенням може бути шрифт, колір, ціле число чи щось інше. У Swift є багато стандартних атрибутів, які вже були визначені заздалегідь. Наприклад:

  • ім'я ключа:, NSAttributedString.Key.fontзначення: aUIFont
  • ім'я ключа:, NSAttributedString.Key.foregroundColorзначення: aUIColor
  • ім'я ключа:, NSAttributedString.Key.linkзначення: а NSURLчиNSString

Є багато інших. Дивіться це посилання для отримання додаткової інформації. Ви навіть можете створити власні атрибути на зразок:

  • ім'я ключа:, NSAttributedString.Key.myNameзначення: деякий Тип.
    якщо ви зробите розширення :

    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як тип. Ось 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(або UILabel):

textView.attributedText = myString

Ви не використовуєте textView.text.

Ось результат:

введіть тут опис зображення

Потім додайте інший атрибутивний рядок, який не має жодних атрибутів. (Зауважте, що, хоч я letі декларував myStringвище, я все одно можу його змінити, оскільки він є NSMutableAttributedString. Це здається мені непривітним, і я не здивуюся, якщо це зміниться в майбутньому. Залиште коментар, коли це станеться.)

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

введіть тут опис зображення

Далі ми просто виберемо слово "Строки", яке починається з індексу 17і має довжину 7. Зауважте, що це NSRangeне Швидкий Range. (Дивіться цю відповідь для отримання додаткової інформації про Діапазони.) 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)

введіть тут опис зображення

Зауважте, що атрибути в деяких місцях перекриваються. Додавання атрибуту не замінює атрибут, який вже є.

Пов'язані

Подальше читання


4
Зауважте, що ви можете комбінувати декілька стилів для підкреслення, наприкладNSUnderlineStyleAttributeName: NSUnderlineStyle.StyleSingle.rawValue | NSUnderlineStyle.PatternDot.rawValue
beeb

3
Ви не можете використовувати appendAttributedString в NSAttributedString, це має бути на NSMutableAttributedString, чи можете ви оновити свою відповідь, щоб це відобразило?
Йосип Астрахан

3
1) Супер дякую за вашу відповідь. 2) Я б запропонував розмістити textView.atrributedtText = myStringабо myLabel.attributedText = myStringна початку відповіді. Як новачок я просто робив, myLabel.textі не думав, що мені потрібно пройти всі ваші відповіді. ** 3) ** Чи означає це, що ви можете мати тільки те, attributedTextабо textяк мати їх обох було б безглуздо? 4) Я рекомендую вам також включати в себе lineSpacingприклад , як це в своїй відповіді , оскільки це дуже корисно. 5) ачаар дахін
Мед

1
Різниця між додаванням та додаванням спочатку була заплутаною. appendAttributedStringє як "З'єднання рядків". addAttributeдодає новий атрибут у ваш рядок.
Мед

2
@Daniel, addAttributeє методом NSMutableAttributedString. Ви маєте рацію, що не можете користуватися ним Stringабо NSAttributedString. (Перевірте myStringвизначення в розділі " Зміна атрибутивної рядки " цієї публікації. Я думаю, що я відкинув вас, тому що я також використовував myStringім'я змінної в першій частині публікації, де вона була NSAttributedString.)
Сурагч

114

Свіфт використовує те саме, NSMutableAttributedStringщо робить Obj-C. Ви інстанціюєте його, передаючи обчислене значення у вигляді рядка:

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

Тепер створіть атрибутивний gрядок (хе). Примітка. UIFont.systemFontOfSize(_) Зараз це ініціалізатор, який недоступний, тому його потрібно розкрутити, перш ніж використовувати його:

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

А потім додайте його:

attributedString.appendAttributedString(gString)

Потім ви можете встановити UILabel для відображення NSAttributedString так:

myLabel.attributedText = attributedString

//Part 1 Set Up The Lower Case g var coffeeText = NSMutableAttributedString(string:"\(calculateCoffee())") //Part 2 set the font attributes for the lower case g var coffeeTypeFaceAttributes = [NSFontAttributeName : UIFont.systemFontOfSize(18)] //Part 3 create the "g" character and give it the attributes var coffeeG = NSMutableAttributedString(string:"g", attributes:coffeeTypeFaceAttributes) Коли я встановлюю свій UILabel.text = coffeeText, я отримую помилку "NSMutableAttributedString не конвертується у" String ". Чи є спосіб змусити UILabel прийняти NSMutableAttributedString?
dcbenji

11
Якщо у вас є атрибутивний рядок, вам потрібно встановити властивість attributedText мітки замість її властивості тексту.
NRitH

1
Це працювало належним чином, і моє нижнє регістр "g" тепер додається до кінця тексту моєї кількості кави
dcbenji

2
Чомусь я отримую помилку "додатковий аргумент у виклику" у своєму рядку з NSAttributedString. Це відбувається лише тоді, коли я перемикаю UIFont.systemFontOfSize (18) на UIFont (назва: "Arial", розмір: 20). Будь-які ідеї?
Unome

UIFont (ім'я: size :) є недоступним ініціалізатором і може повернути нуль. Ви можете явно його відкрутити, додавши! наприкінці або прив’яжіть до змінної за допомогою оператора if / let перед тим, як вставити її у словник.
Еш

21

Версія Xcode 6 :

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

Версія Xcode 9.3 :

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])

20

Швидкий 4:

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

не Type 'NSAttributedStringKey' (aka 'NSString') has no member 'font'
збирається

Я щойно спробував це в новітньому XCode (10 бета-6), і він компілює, ви впевнені, що використовуєте Swift 4?
Адам Бардон

Я використовую Swift 3
bibscy

4
Ну, це питання, у моїй відповіді є сміливий заголовок "Swift 4", я настійно пропоную вам оновити Swift 4
Adam Bardon

@bibscy ви можете використовувати NSAttributedString.Key ***.
Hatim

19

Я настійно рекомендую використовувати бібліотеку для атрибутивних рядків. Це набагато простіше, коли ви хочете, наприклад, одну рядок з чотирма різними кольорами та чотирма різними шрифтами. Ось мій улюблений. Він називається 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 показав би як

Показує як зображення


15

Швидкий: xcode 6.1

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

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

10

Найкращий спосіб наблизити до атрибутивних рядків на iOS - це використовувати вбудований редактор атрибутивного тексту у конструкторі інтерфейсів та уникати непотрібного жорсткого кодування 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
    }
}

Додайте етикетку на раскадровці з атрибутивним текстом, який виглядає так.

введіть тут опис зображення

Потім ви просто оновлюєте значення кожного разу, як вам потрібно:

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

Не забудьте зберегти в initalAttributedString початкове значення.

Ви можете краще зрозуміти такий підхід, прочитавши цю статтю: https://medium.com/mobile-appetite/text-attributes-on-ios-the-effortless-approach-ff086588173e


Це було дуже корисно для мого випадку, коли я мав дошку розкадрувань і просто хотів додати жирну частину рядка в мітці. Набагато простіше, ніж налаштування всіх атрибутів вручну.
Марк Аттінасі

Це розширення працювало для мене ідеально, але в Xcode 11 воно розбило мою програму на let nsRange = NSRange(range,in:valueString)лінії.
Лукас П.

9

Швидкий 2.0

Ось зразок:

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

Швидкий 5.x

let newsString: NSMutableAttributedString = NSMutableAttributedString(string: "Tap here to read the latest Football News.")
newsString.addAttributes([NSAttributedString.Key.underlineStyle: NSUnderlineStyle.double.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

8

Добре працює в бета-6

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

7

Я створив онлайн-інструмент, який збирається вирішити вашу проблему! Ви можете написати свій рядок і застосувати стилі графічно, а інструмент дає код-c і swift для створення цього рядка.

Також є відкритим кодом, тому не соромтеся розширювати його та надсилати PR.

Інструмент трансформаторів

Гітуб

введіть тут опис зображення


Не працює для мене. Він просто загортає все в дужки, не застосовуючи жодного стилю.
Даніель Спрінгер

6

Швидкість 5 і вище

   let attributedString = NSAttributedString(string:"targetString",
                                   attributes:[NSAttributedString.Key.foregroundColor: UIColor.lightGray,
                                               NSAttributedString.Key.font: UIFont(name: "Arial", size: 18.0) as Any])

5
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!))")

4

Швидкий 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)

Потрібно видалити необмежене значення у швидкому 4


3

Для мене вище рішення не спрацювали при встановленні певного кольору чи властивості.

Це спрацювало:

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)

3

Швидкий 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

Які зміни були внесені між Swift 2.0 та 2.1?
Сурагч

3

Використовуйте цей зразок коду. Це дуже короткий код для досягнення вашої потреби. Це працює для мене.

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)

2
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
    }
}

cell.IBLabelGuestApcationTime.text = "\ n \ nGuest1 \ n8: 00 am \ n \ nGuest2 \ n9: 00Am \ n \ n" cell.IBLabelGuestAptribuTime.setSubTextColor (pSubString: "Guest1", pColor: UCael. UICo. .setSubTextColor (pSubString: "Guest2", pColor: UIColor.red)
Dipak Panchasara

1
Ласкаво просимо до SO. Будь ласка, відформатуйте свій код та додайте до своєї відповіді пояснення / контекст. Див: stackoverflow.com/help/how-to-answer
Uwe Allner

2

Атрибути можна налаштувати безпосередньо в швидкому 3 ...

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

Потім використовуйте змінну в будь-якому класі з атрибутами


2

Швидкий 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
    }
}

Чому б не просто range.count на довжину?
Лев Дабус

2

Деталі

  • Swift 5.2, Xcode 11.4 (11E146)

Рішення

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
    }
}

Результат

введіть тут опис зображення


1

Вирішити вашу проблему з створеною мною бібліотекою буде дуже просто. Його називають Атрибутика.

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

768г

Ви можете знайти його тут https://github.com/psharanda/Atributika



1

У Swifter Swift є досить солодкий спосіб зробити це без будь-якої роботи. Просто наведіть шаблон, який повинен відповідати, і які атрибути застосувати до нього. Вони чудово підходять для багатьох речей, які їх перевіряють.

``` Swift
let defaultGenreText = NSAttributedString(string: "Select Genre - Required")
let redGenreText = defaultGenreText.applying(attributes: [NSAttributedString.Key.foregroundColor : UIColor.red], toRangesMatching: "Required")
``

Якщо у вас є кілька місць, де це було б застосовано, і ви хочете, щоб це сталося лише для певних випадків, тоді цей метод не працює.

Це можна зробити за один крок, просто простіше читати, коли їх розлучають.


0

Швидкий 4.x

let attr = [NSForegroundColorAttributeName:self.configuration.settingsColor, NSFontAttributeName: self.configuration.settingsFont]

let title = NSAttributedString(string: self.configuration.settingsTitle,
                               attributes: attr)

0

Swift 3.0 // створити атрибутивний рядок

Визначте такі атрибути, як

let attributes = [NSAttributedStringKey.font : UIFont.init(name: "Avenir-Medium", size: 13.0)]


0

Швидкий 5

    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

введіть тут опис зображення


-4
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]#>)

2
ця відповідь говорить вам про все, що вам потрібно знати, крім як швидко зробити атрибутивний рядок.
Ерік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.