我正在尝试将UILabel
中的每一行添加到数组中,但是我使用的代码似乎并不十分准确。
func getLinesArrayOfStringInLabel(label:UILabel) -> [String] {
guard let text: NSString = label.text as? NSString else { return [] }
let font:UIFont = label.font
let rect:CGRect = label.frame
let myFont: CTFont = CTFontCreateWithName(font.fontName as CFString, font.pointSize, nil)
let attStr:NSMutableAttributedString = NSMutableAttributedString(string: text as String)
attStr.addAttribute(NSAttributedStringKey.font, value:myFont, range: NSMakeRange(0, attStr.length))
let frameSetter:CTFramesetter = CTFramesetterCreateWithAttributedString(attStr as CFAttributedString)
let path: CGMutablePath = CGMutablePath()
path.addRect(CGRect(x: 0, y: 0, width: rect.size.width, height: 100000))
let frame:CTFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil)
let lines = CTFrameGetLines(frame) as NSArray
var linesArray = [String]()
for line in lines {
let lineRange = CTLineGetStringRange(line as! CTLine)
let range:NSRange = NSMakeRange(lineRange.location, lineRange.length)
let lineString = text.substring(with: range)
linesArray.append(lineString as String)
}
return linesArray
}
let label = UILabel()
label.numberOfLines = 0
label.frame = CGRect(x: 40, y: 237, width: 265, height: 53)
label.font = UIFont.systemFont(ofSize: 22, weight: UIFont.Weight.regular)
label.text = "Hey there how's it going today?"
label.backgroundColor = .red
bg.addSubview(label)
print(getLinesArrayOfStringInLabel(label: label))
此打印
["Hey there how\'s it going ", "today?"]
但是标签看起来像这样:
我希望得到
["Hey there how\'s it ", "going today?"]
。这是怎么回事? 最佳答案
因此,这似乎与UILabel
无关,而与您使用的函数无关。我怀疑CATextLayer
会渲染这些行如何从该方法返回,我可悲的发现:(我是对的。
这是我的结果的图片:
红色是您用来创建UILabel
的确切代码。
绿色是CATextLayer
,具有上面UILabel
的所有相同特征,包括字体,字体大小和框架大小。
黄色是子类的UIView
,它将替换自己的图层并返回CATextLayer
。我将其附在下面。您可以继续构建它来满足您的需求,但是我认为这是真正的解决方案,并且唯一的解决方案是使获取行与用户看到的可见行相匹配。如果您提出更好的解决方案,请告诉我。
import UIKit
class AGLabel: UIView {
var alignment : String = kCAAlignmentLeft{
didSet{
configureText()
}
}
var font : UIFont = UIFont.systemFont(ofSize: 16){
didSet{
configureText()
}
}
var fontSize : CGFloat = 16.0{
didSet{
configureText()
}
}
var textColor : UIColor = UIColor.black{
didSet{
configureText()
}
}
var text : String = ""{
didSet{
configureText()
}
}
override class var layerClass: AnyClass {
get {
return CATextLayer.self
}
}
func configureText(){
if let textLayer = self.layer as? CATextLayer{
textLayer.foregroundColor = textColor.cgColor
textLayer.font = font
textLayer.fontSize = fontSize
textLayer.string = text
textLayer.contentsScale = UIScreen.main.scale
textLayer.contentsGravity = kCAGravityCenter
textLayer.isWrapped = true
}
}
}
您还应该在GitHub上 checkout Core-Text-Label。它的呈现方式与
CATextLayers
完全相同,并且将与get行的返回值匹配。它不能满足我的特殊需求,因为我需要调整其大小,并且崩溃,但是如果不需要调整大小,那么我会检查一下。最后,我又回来了,看来这可能是自动换行的问题,该问题始于iOS 11,在这种情况下,他们没有在行上留下孤立的单词。