我想在 UILabel 中显示倒数计时器,但是当我更新计时器时,下一个句子/单词的位置会发生变化。计时器向左、向右移动后完成句子。 我想修复定时器(4:47)的宽度,这样只有定时器值应该更新而不改变任何其他单词的位置。任何想法都将有助于解决这个问题。我不能使用三个标签,因为文本是多行的。
这是我使用的代码:
override func viewDidLoad() {
super.viewDidLoad()
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {[weak self] timer in
self?.updateText()
if let time = self?.reservedTimeInSeconds, time < 0 {
timer.invalidate()
self?.reservedTimeInSeconds = 300
}
}
}
func updateText() {
let minutes: Int = self.reservedTimeInSeconds / 60
let seconds: Int = self.reservedTimeInSeconds % 60
let timer = String(format: "%d:%02d", minutes, seconds)
self.textLabel.text = "Price valid for: \(timer). All prices inclusive of 3% gst."
self.reservedTimeInSeconds -= 1
}
我尝试使用属性字符串但没有运气,这段代码有点工作但是当我尝试设置自定义字体和字体大小时它中断了。
func updateText() {
let minutes: Int = self.reservedTimeInSeconds / 60
let seconds: Int = self.reservedTimeInSeconds % 60
let timer = String(format: "%d:%02d", minutes, seconds)
let html = "<div>%@ <div style=\"color: %@;text-align: center;display: inline-block; overflow: hidden;\">%@</div>. %@</div>"
let htmlFilledString = String(format: html, "Price valid for: ", "green", timer, "All price inclusive of 3% gst. All price inclusive of 3% gst")
self.textLabel.attributedText = htmlFilledString.html2AttributedString
self.reservedTimeInSeconds -= 1
}
extension Data {
var html2AttributedString: NSAttributedString? {
do {
return try NSAttributedString(data: self, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
} catch {
print("error:", error)
return nil
}
}
var html2String: String {
return html2AttributedString?.string ?? ""
}
}
extension String {
var html2AttributedString: NSAttributedString? {
return Data(utf8).html2AttributedString
}
var html2String: String {
return html2AttributedString?.string ?? ""
}
}
最佳答案
如果你不能使用三个标签,我认为你可以使用两个标签来解决这个问题;)。
在倒计时之前计算文本的宽度和高度。在这种情况下,它是“Price valid for”。您可以使用下面的扩展来做到这一点。
extension String { func widthOfString(usingFont font: UIFont) -> CGFloat { let fontAttributes = [NSAttributedStringKey.font: font]; let size = self.size(withAttributes: fontAttributes); return size.width } func heightWithConstrainedWidth(width: CGFloat, font: UIFont) -> CGFloat { let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude) let boundingBox = self.boundingRect(with: constraintRect, options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: [NSAttributedStringKey.font: font], context: nil) return boundingBox.height } }
- 再创建一个与
mainLabel
字体相同的UILabel
(countDownLabel
),给它绿色textColor
。 - 使
coundDownLabel
与mainLabel
重叠。 代替设置
mainLabel.text = "Price valid for 4:36. All prices are inclusive of 9234% GST.";
使用
mainLabel.text = "Price valid for . All prices are inclusive of 9234% GST.";
最后,给
countDown
一个右前导和顶约束。let displayedText = "Price valid valid valid valid for _counDownTimer_. All prices are inclusive of 9234% GST."; let labelWidth : CGFloat = 200; // Add main label let textLabel = UILabel.init(); textLabel.translatesAutoresizingMaskIntoConstraints = false; textLabel.textColor = UIColor.darkGray; textLabel.numberOfLines = 0; textLabel.text = displayedText.replacingOccurrences(of: "_counDownTimer_", with: " "); self.view.addSubview(textLabel); // Update constraints for |textLabel| textLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50).isActive = true; textLabel.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 10).isActive = true; textLabel.widthAnchor.constraint(equalToConstant: 200).isActive = true; // Add timer label let countDownLabel = UILabel.init(); countDownLabel.textColor = UIColor.green; countDownLabel.translatesAutoresizingMaskIntoConstraints = false; self.view.addSubview(countDownLabel); // Calculate position and update constraints of |countDownLabel| let timerTextRange = displayedText.range(of: "_counDownTimer_"); let textBeforeTimer = displayedText.substring(to: (timerTextRange?.lowerBound)!); let textWidth = textBeforeTimer.widthOfString(usingFont: textLabel.font); let textHeight = textBeforeTimer.heightWithConstrainedWidth(width: labelWidth, font: textLabel.font); var leadingConstant = textWidth; let topConstant = textHeight - textLabel.font.lineHeight; let indexOfCountDownLine = NSInteger(textHeight / textLabel.font.lineHeight) - 1; if indexOfCountDownLine > 0 { leadingConstant = leadingConstant - CGFloat(indexOfCountDownLine) * labelWidth; } countDownLabel.topAnchor.constraint(equalTo: textLabel.topAnchor, constant: topConstant).isActive = true; countDownLabel.leadingAnchor.constraint(equalTo: textLabel.leadingAnchor, constant: leadingConstant).isActive = true;
结果
有关更多详细信息,您可以查看我的演示库 here .
关于ios - 一个字的固定宽度(倒数计时器 3 :45) in UIlabel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49583232/