Можно ли использовать символы SF вне UIImage?

Я не понимаю, как использовать символы SF в тексте в проекте iOS. У меня есть UIButton, который отлично использует символ, используяUIImage systemImageNamed:. Я хотел бы отобразить сообщение об этой кнопке с некоторым текстом в другом представлении. Я думал, что смогу использовать ссылку Unicode для этого символа, но он не отображается. Насколько я понимаю, эти символы находятся в области частного использования, но я не могу заставить их отобразить, используя такой код, как@"Press the \U0010057C button."

Я попытался импортировать файл шрифта SFSymbolsFallback.ttf в свой проект.

Я ожидал увидеть визуализированный символ, но получаю? вместо.

4 ответа

Это работает для меня:

let imageAttachment = NSTextAttachment()
imageAttachment.image = UIImage(systemName: "checkmark.circle")

let fullString = NSMutableAttributedString(string: "Press the ")
fullString.append(NSAttributedString(attachment: imageAttachment))
fullString.append(NSAttributedString(string: " button"))
label.attributedText = fullString

Результат:

Я боролся с той же проблемой, как использовать глифы SF Symbol с помощью API рендеринга CoreText. В MacOS шрифт "SF Pro Text" содержит более 7500 глифов, включая глифы символов SF. В iOS системный шрифт имеет только ~2800 глифов и, похоже, не включает новые глифы SF Symbol. Помимо включения шрифта в сам проект (что, я считаю, противоречит лицензированию Apple), я не нашел способа визуализировать эти глифы с использованием их значений символов Unicode.

В macOS 13 Ventura вы можете просто скопировать и вставить символы из приложения SF Symbols в NSString в Xcode, и это прекрасно работает!

Я также тестировал это под macOS 11 Big Sur. Сначала это не сработало, но потом, когда я установил приложение SF Symbols, оно заработало.

Так может быть, это работает, только если установлено приложение SF Symbols? Я не уверен.

Для iOS этот фрагмент может сэкономить вам немного времени:

      extension NSAttributedString {

    static func create(
        blocks: [Block],
        font: UIFont? = nil,
        textColor: UIColor? = nil,
        symbolColor: UIColor? = nil
    ) -> NSAttributedString {

        let font = font ?? .preferredFont(forTextStyle: .body)
        let textColor = textColor ?? .label
        let symbolColor = symbolColor ?? textColor

        let attributedBlocks: [NSAttributedString] = blocks.map { block in
            switch block {
            case .text(let text):
                return NSAttributedString(
                    string: text,
                    attributes: [
                        .font: font,
                        .foregroundColor: textColor
                    ]
                )
            case .symbol(let imageName):
                let attachment = NSTextAttachment()
                let imageConfiguration = UIImage.SymbolConfiguration(font: font)
                attachment.image = UIImage(
                    systemName: imageName,
                    withConfiguration: imageConfiguration
                )?.withTintColor(symbolColor)
                return NSAttributedString(attachment: attachment)
            }
        }
        let string = NSMutableAttributedString(string: "")
        attributedBlocks.forEach {
            string.append($0)
        }
        return string
    }
    
    enum Block {
        case text(String)
        case symbol(String)
    }
}

Возможно, вы захотите украсить свои строки \t,\n или разделителями по вашему выбору.

Другие вопросы по тегам