在Swift中加入UILabel的一部分

Nic*_*k89 33 string uilabel ios nsrange swift

我有一个UILabel以编程方式制作的:

var label = UILabel()
Run Code Online (Sandbox Code Playgroud)

然后,我为标签声明了一些样式,包括字体,例如:

label.frame = CGRect(x: 20, y: myHeaderView.frame.height / 2, width: 300, height: 30)
label.font = UIFont(name: "Typo GeoSlab Regular Demo", size: 15)
label.textColor = UIColor(hue: 0/360, saturation: 0/100, brightness: 91/100, alpha: 1)
Run Code Online (Sandbox Code Playgroud)

标签的第一部分将始终显示:"Filter:"然后是字符串的另一部分,例如"最受欢迎"

我希望单词过滤器以粗体显示,所以整个过程看起来像:

过滤:最受欢迎

我想以最简单的方式创建这种效果.我一直在互联网上搜索如何实现这一点,有很多方法,有些看起来像代码页.其中大部分似乎都是在Objective-C中.我想在Swift请:)

我不知道我是否在正确的路线上,但这NSRange有助于实现吗?提前致谢

更新

我使用一系列if语句来改变我的label变量.如:

if indexArray == 1 {

    label.text = "Filter: Film name"

} else if indexArray == 2 {

    label.text = "Filter: Most popular"

} else if indexArray == 3 {

    label.text = "Filter: Star rating"

}
Run Code Online (Sandbox Code Playgroud)

Joe*_*ton 52

您将需要使用attributedString哪个允许您设置字符串等部分的样式.这可以通过两个样式,一个普通,一个粗体,然后将它们连接在一起来完成:

let boldText = "Filter:"
let attrs = [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 15)]
let attributedString = NSMutableAttributedString(string:boldText, attributes:attrs)

let normalText = "Hi am normal"
let normalString = NSMutableAttributedString(string:normalText)

attributedString.append(normalString)
Run Code Online (Sandbox Code Playgroud)

如果要将其分配给标签:

label.attributedText = attributedString
Run Code Online (Sandbox Code Playgroud)

  • `类型'String'的值没有成员'appendAttributedString'` (2认同)

abd*_*lek 45

您可以使用NSMutableAttributedString和NSAttributedString来创建自定义字符串.下面的函数在给定的字符串中给出boldString粗体.

斯威夫特3

func attributedText(withString string: String, boldString: String, font: UIFont) -> NSAttributedString {
    let attributedString = NSMutableAttributedString(string: string,
                                                     attributes: [NSFontAttributeName: font])
    let boldFontAttribute: [String: Any] = [NSFontAttributeName: UIFont.boldSystemFont(ofSize: font.pointSize)]
    let range = (string as NSString).range(of: boldString)
    attributedString.addAttributes(boldFontAttribute, range: range)
    return attributedString
}
Run Code Online (Sandbox Code Playgroud)

用法示例

authorLabel.attributedText = attributedText(withString: String(format: "Author : %@", user.name), boldString: "Author", font: authorLabel.font)
Run Code Online (Sandbox Code Playgroud)

斯威夫特4

func attributedText(withString string: String, boldString: String, font: UIFont) -> NSAttributedString {
    let attributedString = NSMutableAttributedString(string: string,
                                                     attributes: [NSAttributedStringKey.font: font])
    let boldFontAttribute: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: font.pointSize)]
    let range = (string as NSString).range(of: boldString)
    attributedString.addAttributes(boldFontAttribute, range: range)
    return attributedString
}
Run Code Online (Sandbox Code Playgroud)

Swift 4.2

func attributedText(withString string: String, boldString: String, font: UIFont) -> NSAttributedString {
    let attributedString = NSMutableAttributedString(string: string,
                                                 attributes: [NSAttributedString.Key.font: font])
    let boldFontAttribute: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: font.pointSize)]
    let range = (string as NSString).range(of: boldString)
    attributedString.addAttributes(boldFontAttribute, range: range)
    return attributedString
}
Run Code Online (Sandbox Code Playgroud)

  • 效果很好,这应该是公认的答案。 (2认同)

Llo*_*zer 14

结果:

在此输入图像描述

Swift 4.2:

首先,我们创建一个既可以采用UILabelUITextField可以采用的协议.

public protocol ChangableFont: AnyObject {
    var text: String? { get set }
    var attributedText: NSAttributedString? { get set }
    var rangedAttributes: [RangedAttributes] { get }
    func getFont() -> UIFont?
    func changeFont(ofText text: String, with font: UIFont)
    func changeFont(inRange range: NSRange, with font: UIFont)
    func changeTextColor(ofText text: String, with color: UIColor)
    func changeTextColor(inRange range: NSRange, with color: UIColor)
    func resetFontChanges()
}
Run Code Online (Sandbox Code Playgroud)

我们希望能够为文本添加多个更改,因此我们创建了该rangedAttributes属性.它是一个自定义结构,包含属性及其应用范围.

public struct RangedAttributes {

    let attributes: [NSAttributedString.Key: Any]
    let range: NSRange

    public init(_ attributes: [NSAttributedString.Key: Any], inRange range: NSRange) {
        self.attributes = attributes
        self.range = range
    }
}
Run Code Online (Sandbox Code Playgroud)

另一个问题是UILabel它的font属性很强,UITextFieldfont属性很弱/可选.为了使它们都与我们的ChangableFont协议一起工作,我们包括getFont() -> UIFont?方法.

extension UILabel: ChangableFont {

    public func getFont() -> UIFont? {
        return font
    }
}

extension UITextField: ChangableFont {

    public func getFont() -> UIFont? {
        return font
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以继续为两者创建默认实现UILabelUITextField扩展我们的协议.

public extension ChangableFont {

    public var rangedAttributes: [RangedAttributes] {
        guard let attributedText = attributedText else {
            return []
        }
        var rangedAttributes: [RangedAttributes] = []
        let fullRange = NSRange(
            location: 0,
            length: attributedText.string.count
        )
        attributedText.enumerateAttributes(
            in: fullRange,
            options: []
        ) { (attributes, range, stop) in
            guard range != fullRange, !attributes.isEmpty else { return }
            rangedAttributes.append(RangedAttributes(attributes, inRange: range))
        }
        return rangedAttributes
    }

    public func changeFont(ofText text: String, with font: UIFont) {
        guard let range = (self.attributedText?.string ?? self.text)?.range(ofText: text) else { return }
        changeFont(inRange: range, with: font)
    }

    public func changeFont(inRange range: NSRange, with font: UIFont) {
        add(attributes: [.font: font], inRange: range)
    }

    public func changeTextColor(ofText text: String, with color: UIColor) {
        guard let range = (self.attributedText?.string ?? self.text)?.range(ofText: text) else { return }
        changeTextColor(inRange: range, with: color)
    }

    public func changeTextColor(inRange range: NSRange, with color: UIColor) {
        add(attributes: [.foregroundColor: color], inRange: range)
    }

    private func add(attributes: [NSAttributedString.Key: Any], inRange range: NSRange) {
        guard !attributes.isEmpty else { return }

        var rangedAttributes: [RangedAttributes] = self.rangedAttributes

        var attributedString: NSMutableAttributedString

        if let attributedText = attributedText {
            attributedString = NSMutableAttributedString(attributedString: attributedText)
        } else if let text = text {
            attributedString = NSMutableAttributedString(string: text)
        } else {
            return
        }

        rangedAttributes.append(RangedAttributes(attributes, inRange: range))

        rangedAttributes.forEach { (rangedAttributes) in
            attributedString.addAttributes(
                rangedAttributes.attributes,
                range: rangedAttributes.range
            )
        }

        attributedText = attributedString
    }

    public func resetFontChanges() {
        guard let text = text else { return }
        attributedText = NSMutableAttributedString(string: text)
    }
}
Run Code Online (Sandbox Code Playgroud)

在默认实现中,我使用一个小帮助方法来获取NSRangea substring.

public extension String {

    public func range(ofText text: String) -> NSRange {
        let fullText = self
        let range = (fullText as NSString).range(of: text)
        return range
    }
}
Run Code Online (Sandbox Code Playgroud)

我们完成了!您现在可以更改文本的部分字体和文本颜色.

titleLabel.text = "Welcome"
titleLabel.font = UIFont.systemFont(ofSize: 70, weight: .bold)
titleLabel.textColor = UIColor.black
titleLabel.changeFont(ofText: "lc", with: UIFont.systemFont(ofSize: 60, weight: .light))
titleLabel.changeTextColor(ofText: "el", with: UIColor.blue)
titleLabel.changeTextColor(ofText: "co", with: UIColor.red)
titleLabel.changeTextColor(ofText: "m", with: UIColor.green)
Run Code Online (Sandbox Code Playgroud)

  • 感谢这个解决方案!您可以将其发布为 CocoaPods 库。 (2认同)

Mak*_*zev 7

Swift 4 替代方案

let attrs = [NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 14)]
let attributedString = NSMutableAttributedString(string: "BOLD TEXT", attributes:attrs)
let normalString = NSMutableAttributedString(string: "normal text")
attributedString.append(normalString)
myLabel.attributedText = attributedString
Run Code Online (Sandbox Code Playgroud)


小智 7

如果您愿意,可以直接在 String 上执行以下操作:

extension String {
func withBoldText(text: String, font: UIFont? = nil) -> NSAttributedString {
  let _font = font ?? UIFont.systemFont(ofSize: 14, weight: .regular)
  let fullString = NSMutableAttributedString(string: self, attributes: [NSAttributedString.Key.font: _font])
  let boldFontAttribute: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: _font.pointSize)]
  let range = (self as NSString).range(of: text)
  fullString.addAttributes(boldFontAttribute, range: range)
  return fullString
}}
Run Code Online (Sandbox Code Playgroud)

用法:

label.attributeString = "my full string".withBoldText(text: "full")
Run Code Online (Sandbox Code Playgroud)