ios 在 Swift 中将 UILabel 的一部分设为粗体
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36486761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Make part of a UILabel bold in Swift
提问by Nick89
I have a UILabel
I've made programmatically as:
我有一个UILabel
我以编程方式制作的:
var label = UILabel()
I've then declared some styling for the label, including a font, such as:
然后,我为标签声明了一些样式,包括字体,例如:
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)
The first part of the label will always read : "Filter:"
then followed by another part of the string, for example, "Most popular"
标签的第一部分将始终为:"Filter:"
然后是字符串的另一部分,例如,“最流行”
I would like the word filter to be in bold, so the whole thing would look like:
我希望过滤器这个词是粗体的,所以整个事情看起来像:
Filter:Most popular
过滤器:最受欢迎
I want to simplest way of creating this effect. I've been searching the internet for how to achieve this and there are so many ways, some which just look like pages of code. And most of it seems to be in Objective-C. I would like it in Swift please :)
我想用最简单的方法来创造这种效果。我一直在互联网上搜索如何实现这一点,有很多方法,有些看起来就像代码页。而且大部分似乎都在Objective-C中。我想在 Swift 中使用它 :)
I don't know if i'm on the right lines, but is this what NSRange
can help achieve? Thanks in advance
我不知道我是否在正确的路线上,但这是NSRange
可以帮助实现的吗?提前致谢
Update
更新
I use a series of if
statements to change my label
variable. Such as:
我使用一系列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"
}
回答by Joe Benton
You will want to use attributedString
which allows you to style parts of a string etc. This can be done like this by having two styles, one normal, one bold, and then attaching them together:
您将需要使用attributedString
which 允许您为字符串的某些部分设置样式等。 这可以通过使用两种样式来完成,一种是普通样式,一种是粗体,然后将它们连接在一起:
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)
When you want to assign it to a label:
当您想将其分配给标签时:
label.attributedText = attributedString
回答by abdullahselek
You can use NSMutableAttributedString and NSAttributedString to create customized string. The function below makes given boldString bold in given string.
您可以使用 NSMutableAttributedString 和 NSAttributedString 来创建自定义字符串。下面的函数使给定的 boldString 在给定的字符串中加粗。
Swift 3
斯威夫特 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
}
Example usage
示例用法
authorLabel.attributedText = attributedText(withString: String(format: "Author : %@", user.name), boldString: "Author", font: authorLabel.font)
Swift 4
斯威夫特 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
}
Swift 4.2 and 5
斯威夫特 4.2 和 5
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
}
回答by Lloyd Keijzer
Result:
结果:
Swift 4.2 & 5.0:
斯威夫特 4.2 和 5.0:
First off we create a protocol that both UILabel
and UITextField
can adopt.
首先,我们创建了一个既可以采用UILabel
又UITextField
可以采用的协议。
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()
}
We want to be able to add multiple changes to our text, therefore we create the rangedAttributes
property. It's a custom struct that holds attributes and the range in which they are applied.
我们希望能够为我们的文本添加多个更改,因此我们创建了该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
}
}
Another problem is that UILabel
its font
property is strong and UITextField
its font
property is weak/optional. To make them both work with our ChangableFont
protocol we include the getFont() -> UIFont?
method.
另一个问题是UILabel
它的font
属性是强的,而UITextField
它的font
属性是弱/可选的。为了使它们都适用于我们的ChangableFont
协议,我们包含了该getFont() -> UIFont?
方法。
extension UILabel: ChangableFont {
public func getFont() -> UIFont? {
return font
}
}
extension UITextField: ChangableFont {
public func getFont() -> UIFont? {
return font
}
}
Now we can go ahead and create the default implementation for both UILabel
and UITextField
by extending our protocol.
现在我们可以继续为两者创建默认实现,UILabel
并UITextField
通过扩展我们的协议。
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)
}
}
With in the default implementation I use a little helper method for getting the NSRange
of a substring
.
在默认实现我用得到一个小帮手方法NSRange
的substring
。
public extension String {
public func range(ofText text: String) -> NSRange {
let fullText = self
let range = (fullText as NSString).range(of: text)
return range
}
}
We're done!You can now change parts of the text its font and text color.
我们完成了!您现在可以更改部分文本的字体和文本颜色。
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)
回答by Maksim Kniazev
Swift 4 alternative:
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
回答by Glenn
Just sharing my own quite-flexible implementation in Swift 4.0. Cause there are some requirements, like mine currently, that you need to set not only bold but italic the part of a label's text.
只是在 Swift 4.0 中分享我自己的非常灵活的实现。因为有一些要求,例如我目前的要求,您不仅需要将标签文本的部分设置为粗体,还需要设置为斜体。
import UIKit
extension UILabel {
/** Sets up the label with two different kinds of attributes in its attributed text.
* @params:
* - primaryString: the normal attributed string.
* - secondaryString: the bold or highlighted string.
*/
func setAttributedText(primaryString: String, textColor: UIColor, font: UIFont, secondaryString: String, secondaryTextColor: UIColor, secondaryFont: UIFont) {
let completeString = "\(primaryString) \(secondaryString)"
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let completeAttributedString = NSMutableAttributedString(
string: completeString, attributes: [
.font: font,
.foregroundColor: textColor,
.paragraphStyle: paragraphStyle
]
)
let secondStringAttribute: [NSAttributedStringKey: Any] = [
.font: secondaryFont,
.foregroundColor: secondaryTextColor,
.paragraphStyle: paragraphStyle
]
let range = (completeString as NSString).range(of: secondaryString)
completeAttributedString.addAttributes(secondStringAttribute, range: range)
self.attributedText = completeAttributedString
}
}
回答by Stefano Pedroli
You can directly do on String if you prefer:
如果你愿意,你可以直接在 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
}}
Usage:
用法:
label.attributeString = "my full string".withBoldText(text: "full")
回答by Oz Shabat
for the ones who prefer extensions
对于喜欢扩展的人
Swift 5.0
斯威夫特 5.0
/// will set a regual and a bold text in the same label
public func setRegualAndBoldText(regualText: String,
boldiText: String) {
let attrs = [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: font.pointSize)]
let regularString = NSMutableAttributedString(string: regualText)
let boldiString = NSMutableAttributedString(string: boldiText, attributes:attrs)
regularString.append(boldiString)
attributedText = regularString
}
and use:
并使用:
label.setRegualAndBoldText(regualText: "height: ", boldiText: "1.65 :(")
回答by apinho
Swift 4.0 solution
Swift 4.0 解决方案
let font = UIFont.systemFont(ofSize: 14)
func boldSearchResult(searchString: String, resultString: String) -> NSMutableAttributedString {
let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: resultString)
guard let regex = try? NSRegularExpression(pattern: searchString.lowercased(), options: []) else {
return attributedString
}
let range: NSRange = NSMakeRange(0, resultString.count)
regex.enumerateMatches(in: resultString.lowercased(), options: [], range: range) { (textCheckingResult, matchingFlags, stop) in
guard let subRange = textCheckingResult?.range else {
return
}
attributedString.addAttributes([NSAttributedString.Key.font : font], range: subRange)
}
return attributedString
}