我试图将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?"]
但标签看起来像这样:
passed to the PromptChoice constructor
我希望得到["Hey there how\'s it ", "going today?"]
。发生了什么事?
答案 0 :(得分:4)
所以它似乎与UILabel有关,并且与您正在使用的功能没有任何问题。我怀疑CATextLayer会渲染它们从该方法返回的方式,我遗憾地发现:(我是对的。
红色是您用来创建UILabel的确切代码。
绿色是CATextLayer,具有上述UILabel的所有相同特征,包括字体,字体大小和帧大小。
黄色是一个子类UIView,它正在替换它自己的层并返回一个CATextLayer。我在下面附上它。您可以继续构建它以满足您的需求,但我认为这是真正的解决方案,也是唯一一个让get行与用户看到的可见行匹配的解决方案。如果您想出更好的解决方案,请告诉我。
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上查看Core-Text-Label。它完全像CATextLayers那样呈现,并且与get行的返回相匹配。它不适用于我的特殊需求,因为我需要我的可调整大小并且它崩溃但是如果不需要调整大小那么我会检查它。
最后我又回来了,看起来这可能是在iOS 11中启动的自动换行问题,他们不会在行上留下孤儿字。