Существуют ли какие-либо аналоги [NSString stringWithFormat:] для NSAttributedString
Обычно я создаю интерфейс приложения в построителе интерфейса. Иногда дизайн требует использования атрибутированных строк (шрифтов, цветов и т.д.). Легко настроить, является ли строка статичной.
Но если строка является динамической (формат с аргументами), тогда нет способов настроить атрибуты в построителе интерфейса. Это требует, чтобы написать много кода.
Я ищу некоторые аналоги [NSString stringWithFormat:]
для NSAttributedString
. Поэтому я смогу установить строковый формат и необходимые атрибуты в построителе интерфейса, а затем предоставить необходимые аргументы в коде.
Например:
Предположим, что мне нужна строка отображения с таким форматом: "% d + % d= % d" (все цифры выделены жирным шрифтом). < ш > Я хочу настроить этот формат в построителе интерфейса. В коде я хочу предоставить аргументы: 1, 1, 2. Приложение должно показать " 1 + 1= 2".
Ответы
Ответ 1
Я искал хорошее существующее решение для этого вопроса, но не добился успеха.
Поэтому я смог реализовать это самостоятельно.
Вот почему я сам отвечаю на вопрос об обмене знаниями с сообществом.
Решение
категория NSAttributedString + VPAttributedFormat предоставляет методы построения атрибутивной строки на основе атрибутного формата и аргументов, которые должны удовлетворять этому формату.
Наиболее подходящим случаем использования этой категории являются текстовые элементы управления с переменным атрибутом текста, сконфигурированным в построителе интерфейса.
Вам необходимо установить правильный формат строки для атрибута текста и настроить необходимые атрибуты.
Затем вам необходимо передать необходимые аргументы в коде, используя методы этой категории.
- Формат синтаксиса такой же, как в методе
[NSString stringWithFormat:]
;
- Может использоваться в коде Objective C и Swift;
- Требуется iOS 6.0 и более поздние версии;
- Интегрировано с CocoaPods;
- В комплекте с модульными тестами.
Использование
1. Импортировать заголовок или модуль структуры
// Objective C
// By header
#import <VPAttributedFormat/VPAttributedFormat.h>
// By module
@import VPAttributedFormat;
// Swift
import VPAttributedFormat
2. Установите правильный формат и атрибуты для управления текстом в построителе интерфейсов
![usage]()
3. Создайте IBOutlet и привяжите его с помощью текстового управления
// Objective C
@property (nonatomic, weak) IBOutlet UILabel *textLabel;
// Swift
@IBOutlet weak var textLabel: UILabel!
4. Задать формат с необходимыми аргументами
// Objective C
NSString *hot = @"Hot";
NSString *cold = @"Cold";
self.textLabel.attributedText = [NSAttributedString vp_attributedStringWithAttributedFormat:self.textLabel.attributedText,
hot,
cold];
// Swift
let hot = "Hot"
let cold = "Cold"
var arguments: [CVarArgType] = [hot, cold]
textLabel.attributedText = withVaList(arguments) { pointer in
NSAttributedString.vp_attributedStringWithAttributedFormat(textLabel.attributedText, arguments: pointer)
}
5. См. Результат
![result]()
Примеры
VPAttributedFormatExample - пример проекта. Он предоставляет примеры форматов Basic и Pro.
![example]()
Ответ 2
Вот категория, которую я написал, чтобы добавить метод в NSAttributedString. Вы должны будете передать NULL в качестве последнего аргумента функции, однако в противном случае он будет сбой к ограничениям va_list для определения размера. [attribitedString stringWithFormat: attrFormat, attrArg1, attrArg2, NULL];
@implementation NSAttributedString(stringWithFormat)
+(NSAttributedString*)stringWithFormat:(NSAttributedString*)format, ...{
va_list args;
va_start(args, format);
NSMutableAttributedString *mutableAttributedString = (NSMutableAttributedString*)[format mutableCopy];
NSString *mutableString = [mutableAttributedString string];
while (true) {
NSAttributedString *arg = va_arg(args, NSAttributedString*);
if (!arg) {
break;
}
NSRange rangeOfStringToBeReplaced = [mutableString rangeOfString:@"%@"];
[mutableAttributedString replaceCharactersInRange:rangeOfStringToBeReplaced withAttributedString:arg];
}
va_end(args);
return mutableAttributedString;
}
@end
Ответ 3
Вот расширение Swift 4, основанное на ответе TheJeff (исправлено для нескольких подстановок). Он ограничен заменой заполнителей на NSAttributedString:
public extension NSAttributedString {
convenience init(format: NSAttributedString, args: NSAttributedString...) {
let mutableNSAttributedString = NSMutableAttributedString(attributedString: format)
var nsRange = NSString(string: mutableNSAttributedString.string).range(of: "%@")
var param = 0
while nsRange.location != NSNotFound {
guard args.count > 0, param < args.count else {
fatalError("Not enough arguments provided for \(format)")
}
mutableNSAttributedString.replaceCharacters(in: nsRange, with: args[param])
param += 1
nsRange = NSString(string: mutableNSAttributedString.string).range(of: "%@")
}
self.init(attributedString: mutableNSAttributedString)
}
}
Ответ 4
Совместим с Swift 4.2
public extension NSAttributedString {
convenience init(format: NSAttributedString, args: NSAttributedString...) {
let mutableNSAttributedString = NSMutableAttributedString(attributedString: format)
args.forEach { (attributedString) in
let range = NSString(string: mutableNSAttributedString.string).range(of: "%@")
mutableNSAttributedString.replaceCharacters(in: range, with: attributedString)
}
self.init(attributedString: mutableNSAttributedString)
}
}
Использование:
let content = NSAttributedString(string: "The quick brown %@ jumps over the lazy %@")
let fox = NSAttributedString(string: "fox", attributes: [.font: Fonts.CalibreReact.boldItalic])
let dog = NSAttributedString(string: "dog", attributes: [.font: Fonts.CalibreReact.lightItalic])
attributedLabel.attributedText = NSAttributedString(format: content, args: fox, dog)
Результат:
![enter image description here]()