首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用Swift将突出显示/背景添加到仅文本中

使用Swift将突出显示/背景添加到仅文本中
EN

Stack Overflow用户
提问于 2019-09-24 00:55:01
回答 1查看 1.3K关注 0票数 1

我想要高亮显示或添加一个背景,只在标签上的文本上,而不是中心对齐。

我已经尝试过属性化Strings (https://stackoverflow.com/a/38069772/676822)并使用regex,但是没有找到一个好的解决方案。NSAttributedString不能工作,因为我的标签不是居中的,而且它不包含换行符。这只是一个长的文本,需要多行。

这就是我想要达到的目标:

注:这不是“布道\n设计\n思考”,而是“传道设计思想”。

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-24 01:38:40

据我所知,仅仅使用属性化文本是不可能得到您想要的东西的,因为使用:

代码语言:javascript
运行
AI代码解释
复制
let attributedText = NSMutableAttributedString(string: "Evangelizing Desing Thinking",
    attributes: [
        .font: UIFont.systemFont(ofSize: 14),
        .backgroundColor: UIColor.gray
    ]
)

将添加额外的灰色背景在每一行的末尾。我以前的答案也不是很好,因为它只在每个单词上添加了一个灰色背景,而不是在空格上,正如@Alladinian注意到的那样,在某些情况下范围可能是错误的。

所以这里有一个黑客,你可以用它来实现你想要的。它使用多个标签,但可以通过将标签放在自定义视图中轻松地进行改进。因此,在viewDidLoad / CustomView函数中添加:

代码语言:javascript
运行
AI代码解释
复制
    // Maximum desired width for your text
    let maxLabelWidth: CGFloat = 80
    // Font you used
    let font = UIFont.systemFont(ofSize: 14)
    // Your text
    let text = "Eva ngel izing Des ing a Thin king"
    // Width of a space character
    let spaceWidth = NSString(string: " ").size(withAttributes: [NSAttributedString.Key.font: font]).width

    // Width of a row
    var currentRowWidth: CGFloat = 0
    // Content of a row
    var currentRow = ""
    // Previous label added (we keep it to add constraint betweeen labels)
    var prevLabel: UILabel?

    let subStrings = text.split(separator: " ")
    for subString in subStrings {
        let currentWord = String(subString)
        let nsCurrentWord = NSString(string: currentWord)
        // Width of the new word
        let currentWordWidth = nsCurrentWord.size(withAttributes: [NSAttributedString.Key.font: font]).width
        // Width of the row if you add a new word
        let currentWidth = currentRow.count == 0 ? currentWordWidth : currentWordWidth + spaceWidth + currentRowWidth

        if currentWidth <= maxLabelWidth { // The word can be added in the current row
            currentRowWidth = currentWidth
            currentRow += currentRow.count == 0 ? currentWord : " " + currentWord
        } else { // Its not possible to add a new word in the current row, we create a label with the current row content
            prevLabel = generateLabel(with: currentRow,
                                      font: font,
                                      prevLabel: prevLabel)
            currentRowWidth = currentWordWidth
            currentRow = currentWord
        }
    }

    // Dont forget to add the last row
    generateLabel(with: currentRow,
                  font: font,
                  prevLabel: prevLabel)

然后必须创建generateLabel函数:

代码语言:javascript
运行
AI代码解释
复制
@discardableResult func generateLabel(with text: String,
                                      font: UIFont,
                                      prevLabel: UILabel?) -> UILabel {
    let leftPadding: CGFloat = 50 // Left padding of the label
    let topPadding: CGFloat = 100 // Top padding of (first) label

    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(label)
    label.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: leftPadding).isActive = true
    if let prevLabel = prevLabel {
        label.topAnchor.constraint(equalTo: prevLabel.bottomAnchor).isActive = true
    } else {
        label.topAnchor.constraint(equalTo: self.view.topAnchor, constant: topPadding).isActive = true
    }
    label.font = font
    label.text = text
    label.backgroundColor = .gray

    return label
}

先前的回答:

正如Yogesh所建议的,您可以使用属性化字符串:

代码语言:javascript
运行
AI代码解释
复制
    // Init label
    let label = UILabel(frame: CGRect(x: 50, y: 50, width: 90, height: 120))
    self.view.addSubview(label)
    label.lineBreakMode = .byTruncatingTail
    label.numberOfLines = 0
    label.backgroundColor = .white

    // Create attributed text
    let text = "Evangelizing Desing Thinking"
    let attributedText = NSMutableAttributedString(string: text,
        attributes: [
            .font: UIFont.systemFont(ofSize: 14)
        ]
    )

    // Find ranges of each word
    let subStrings = text.split(separator: " ")
    let ranges = subStrings.map { (subString) -> Range<String.Index> in
        guard let range = text.range(of: subString) else {
            fatalError("something wrong with substring") // This case should not happen
        }
        return range
    }

    // Apply background color for each word
    ranges.forEach { (range) in
        let nsRange = NSRange(range, in: text)
        attributedText.addAttribute(.backgroundColor, value: UIColor.gray, range: nsRange)
    }

    // Finally set attributed text
    label.attributedText = attributedText
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58076550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文