每行独立截断的多行 UIButton
Multiline UIButton with each line truncated independently
我正在尝试通过子类化 UIButton 来制作多行按钮。为了避免绘制两个自定义 UILabel
(我对 Swift/Xcode 还是很陌生),我对现有的 UILabel
使用属性字符串,并使用新行字符拆分行,就像这样:
func prepareAttributedTitle(_ primaryTitle: String = "", _ secondaryTitle: String = "") {
let title = NSMutableAttributedString()
let first = NSAttributedString(string: primaryTitle, attributes: [
NSForegroundColorAttributeName: tintColor,
NSFontAttributeName: UIFont.systemFont(ofSize: UIFont.systemFontSize, weight: UIFontWeightSemibold)
])
let newLine = NSAttributedString(string: "\n")
let second = NSAttributedString(string: secondaryTitle, attributes: [
NSForegroundColorAttributeName: tintColor.withAlphaComponent(0.75),
NSFontAttributeName: UIFont.systemFont(ofSize: UIFont.smallSystemFontSize)
])
title.append(first)
title.append(newLine)
title.append(second)
setAttributedTitle(title, for: .normal)
}
结果是(抱歉,我没有足够的代表 post 图片):
| This is the long first |
| line |
| Secondary line |
但是,我想单独截断行,如下所示:
| This is the long fi... |
| Secondary line |
有没有不使用两个自定义 UILabel 就可以做到这一点的方法?
谢谢
单个UILabel
不支持您所需要的。您将不得不使用两个单行标签,每个标签都设置尾部截断。
我正在用对我有用的方法来回答我自己的问题。这是我的 UIButton 子类,但请记住我不是经验丰富的开发人员。还有一些样式和对色调的支持:
import UIKit
@IBDesignable
class FilterButton: UIButton {
let primaryLabel = UILabel()
let secondaryLabel = UILabel()
@IBInspectable var primaryTitle = "" {
didSet {
primaryLabel.text = primaryTitle
}
}
@IBInspectable var secondaryTitle = "" {
didSet {
secondaryLabel.text = secondaryTitle
}
}
// MARK: Initialization
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
override func prepareForInterfaceBuilder() {
primaryTitle = "Primary title"
secondaryTitle = "Secondary title"
commonInit()
}
func commonInit() {
// Force left alignment (FIXME: Use user language direction)
contentHorizontalAlignment = .left
// Set some padding and styling
contentEdgeInsets = UIEdgeInsets(top: 5, left: 10, bottom: 5, right: 10)
layer.cornerRadius = 5
layer.borderWidth = 1
// Hide button original label
titleLabel?.isHidden = true
// Prepare the primary label
primaryLabel.frame = CGRect(x: contentEdgeInsets.left,
y: contentEdgeInsets.top,
width: frame.width - contentEdgeInsets.left - contentEdgeInsets.right,
height: (frame.height - contentEdgeInsets.top - contentEdgeInsets.bottom) / 2)
primaryLabel.font = UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)
primaryLabel.textColor = tintColor
// primaryLabel.backgroundColor = UIColor.green // For debugging
primaryLabel.lineBreakMode = .byTruncatingMiddle // Truncate first line
primaryLabel.autoresizingMask = .flexibleWidth
addSubview(primaryLabel)
// Prepare the secondary label
secondaryLabel.frame = CGRect(x: contentEdgeInsets.left,
y: contentEdgeInsets.top + primaryLabel.frame.height,
width: frame.width - contentEdgeInsets.left - contentEdgeInsets.right,
height: (frame.height - contentEdgeInsets.top - contentEdgeInsets.bottom) / 2)
secondaryLabel.font = UIFont.systemFont(ofSize: UIFont.smallSystemFontSize)
secondaryLabel.textColor = tintColor.withAlphaComponent(0.75)
// secondaryLabel.backgroundColor = UIColor.yellow // For debugging
secondaryLabel.lineBreakMode = .byTruncatingMiddle // Truncate second line
secondaryLabel.autoresizingMask = .flexibleWidth
addSubview(secondaryLabel)
primaryLabel.text = primaryTitle
secondaryLabel.text = secondaryTitle
}
// Support tint color
override func tintColorDidChange() {
super.tintColorDidChange()
layer.borderColor = tintColor.cgColor
layer.backgroundColor = tintColor.withAlphaComponent(0.05).cgColor
primaryLabel.textColor = tintColor
secondaryLabel.textColor = tintColor.withAlphaComponent(0.75)
}
}
我正在尝试通过子类化 UIButton 来制作多行按钮。为了避免绘制两个自定义 UILabel
(我对 Swift/Xcode 还是很陌生),我对现有的 UILabel
使用属性字符串,并使用新行字符拆分行,就像这样:
func prepareAttributedTitle(_ primaryTitle: String = "", _ secondaryTitle: String = "") {
let title = NSMutableAttributedString()
let first = NSAttributedString(string: primaryTitle, attributes: [
NSForegroundColorAttributeName: tintColor,
NSFontAttributeName: UIFont.systemFont(ofSize: UIFont.systemFontSize, weight: UIFontWeightSemibold)
])
let newLine = NSAttributedString(string: "\n")
let second = NSAttributedString(string: secondaryTitle, attributes: [
NSForegroundColorAttributeName: tintColor.withAlphaComponent(0.75),
NSFontAttributeName: UIFont.systemFont(ofSize: UIFont.smallSystemFontSize)
])
title.append(first)
title.append(newLine)
title.append(second)
setAttributedTitle(title, for: .normal)
}
结果是(抱歉,我没有足够的代表 post 图片):
| This is the long first |
| line |
| Secondary line |
但是,我想单独截断行,如下所示:
| This is the long fi... |
| Secondary line |
有没有不使用两个自定义 UILabel 就可以做到这一点的方法?
谢谢
单个UILabel
不支持您所需要的。您将不得不使用两个单行标签,每个标签都设置尾部截断。
我正在用对我有用的方法来回答我自己的问题。这是我的 UIButton 子类,但请记住我不是经验丰富的开发人员。还有一些样式和对色调的支持:
import UIKit
@IBDesignable
class FilterButton: UIButton {
let primaryLabel = UILabel()
let secondaryLabel = UILabel()
@IBInspectable var primaryTitle = "" {
didSet {
primaryLabel.text = primaryTitle
}
}
@IBInspectable var secondaryTitle = "" {
didSet {
secondaryLabel.text = secondaryTitle
}
}
// MARK: Initialization
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
override func prepareForInterfaceBuilder() {
primaryTitle = "Primary title"
secondaryTitle = "Secondary title"
commonInit()
}
func commonInit() {
// Force left alignment (FIXME: Use user language direction)
contentHorizontalAlignment = .left
// Set some padding and styling
contentEdgeInsets = UIEdgeInsets(top: 5, left: 10, bottom: 5, right: 10)
layer.cornerRadius = 5
layer.borderWidth = 1
// Hide button original label
titleLabel?.isHidden = true
// Prepare the primary label
primaryLabel.frame = CGRect(x: contentEdgeInsets.left,
y: contentEdgeInsets.top,
width: frame.width - contentEdgeInsets.left - contentEdgeInsets.right,
height: (frame.height - contentEdgeInsets.top - contentEdgeInsets.bottom) / 2)
primaryLabel.font = UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)
primaryLabel.textColor = tintColor
// primaryLabel.backgroundColor = UIColor.green // For debugging
primaryLabel.lineBreakMode = .byTruncatingMiddle // Truncate first line
primaryLabel.autoresizingMask = .flexibleWidth
addSubview(primaryLabel)
// Prepare the secondary label
secondaryLabel.frame = CGRect(x: contentEdgeInsets.left,
y: contentEdgeInsets.top + primaryLabel.frame.height,
width: frame.width - contentEdgeInsets.left - contentEdgeInsets.right,
height: (frame.height - contentEdgeInsets.top - contentEdgeInsets.bottom) / 2)
secondaryLabel.font = UIFont.systemFont(ofSize: UIFont.smallSystemFontSize)
secondaryLabel.textColor = tintColor.withAlphaComponent(0.75)
// secondaryLabel.backgroundColor = UIColor.yellow // For debugging
secondaryLabel.lineBreakMode = .byTruncatingMiddle // Truncate second line
secondaryLabel.autoresizingMask = .flexibleWidth
addSubview(secondaryLabel)
primaryLabel.text = primaryTitle
secondaryLabel.text = secondaryTitle
}
// Support tint color
override func tintColorDidChange() {
super.tintColorDidChange()
layer.borderColor = tintColor.cgColor
layer.backgroundColor = tintColor.withAlphaComponent(0.05).cgColor
primaryLabel.textColor = tintColor
secondaryLabel.textColor = tintColor.withAlphaComponent(0.75)
}
}