xcode 自动多行标签swift
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33430680/
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
automatic multiline label swift
提问by Alex
I have a label and I insert text in it. The label has a size but my problem is this:
我有一个标签,并在其中插入文本。标签有尺寸,但我的问题是:
when I insert text in label if the text is longer than label'size appears "...." in the label; for example:
当我在标签中插入文本时,如果文本长于标签的大小,标签中会出现“....”;例如:
if complete string that I want insert in the label is this : "hello world how are you?"
如果我想在标签中插入的完整字符串是这样的: "hello world how are you?"
in the label I see this "hello world..."
在标签中我看到了这个 "hello world..."
I would like that label wraps automatically.
我希望该标签自动换行。
For this reason I did this but it doesn't work:
出于这个原因,我这样做了,但它不起作用:
label!.textAlignment = NSTextAlignment.Center;
label!.numberOfLines = 0;
label!.font = UIFont.systemFontOfSize(16.0);
label!.text = "hello world how are you?"
Where do I wrong?
我哪里错了?
回答by good4pc
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 0;
or adjust the font size as below to fit the whole string
或如下调整字体大小以适合整个字符串
label.adjustsFontSizeToFitWidth = true
回答by Niall Kehoe
What I did was use a UILabel
class.
我所做的是使用一个UILabel
类。
Create your label:
创建您的标签:
let multiLabel = LabelClass(text: "hello world how are u?", labelWidth: 250, pos: CGPoint(x: size.width / 2, y: size.height / 2))
addChild(multiLabel)
You've now referenced your LabelClass file. Here's the code for that:
您现在已经引用了 LabelClass 文件。这是代码:
import SpriteKit
class GameSceneLabel : SKNode {
//props
var labelWidth:Int {didSet {update()}}
var labelHeight:Int = 0
var text:String {didSet {update()}}
var fontName:String {didSet {update()}}
var fontSize:CGFloat {didSet {update()}}
var pos:CGPoint {didSet {update()}}
var fontColor:UIColor {didSet {update()}}
var leading:Int {didSet {update()}}
var alignment:SKLabelHorizontalAlignmentMode {didSet {update()}}
var dontUpdate = false
var shouldShowBorder:Bool = false {didSet {update()}}
//display objects
var rect:SKShapeNode?
var labels:[SKLabelNode] = []
init(text:String, labelWidth:Int, pos:CGPoint, fontName:String="ChalkboardSE-Regular",fontSize:CGFloat=20,fontColor:UIColor=UIColor.white,leading:Int? = nil, alignment:SKLabelHorizontalAlignmentMode = .center, shouldShowBorder:Bool = false)
{
self.text = text
self.labelWidth = labelWidth
self.pos = pos
self.fontName = fontName
self.fontSize = fontSize
self.fontColor = fontColor
self.leading = leading ?? Int(fontSize)
self.shouldShowBorder = shouldShowBorder
self.alignment = alignment
super.init()
self.update()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//if you want to change properties without updating the text field,
// set dontUpdate to false and call the update method manually.
func update() {
if (dontUpdate) {return}
if (labels.count>0) {
for label in labels {
label.removeFromParent()
}
labels = []
}
let separators = NSCharacterSet.whitespacesAndNewlines
let words = (text as NSString).components(separatedBy: separators)
var finalLine = false
var wordCount = -1
var lineCount = 0
while (!finalLine) {
lineCount+=1
var lineLength = CGFloat(0)
var lineString = ""
var lineStringBeforeAddingWord = ""
// creation of the SKLabelNode itself
let label = SKLabelNode(fontNamed: fontName)
// name each label node so you can animate it if u wish
label.name = "line\(lineCount)"
label.horizontalAlignmentMode = alignment
label.fontSize = fontSize
label.fontColor = fontColor
while lineLength < CGFloat(labelWidth)
{
wordCount+=1
if wordCount > words.count-1
{
//label.text = "\(lineString) \(words[wordCount])"
finalLine = true
break
}
else
{
lineStringBeforeAddingWord = lineString
lineString = "\(lineString) \(words[wordCount])"
label.text = lineString
lineLength = label.frame.width
}
}
if lineLength > 0 {
wordCount-=1
if (!finalLine) {
lineString = lineStringBeforeAddingWord
}
label.text = lineString
var linePos = pos
if (alignment == .left) {
linePos.x -= CGFloat(labelWidth / 2)
} else if (alignment == .right) {
linePos.x += CGFloat(labelWidth / 2)
}
linePos.y += CGFloat(-leading * lineCount)
label.position = CGPoint(x:linePos.x , y:linePos.y )
self.addChild(label)
labels.append(label)
}
}
labelHeight = lineCount * leading
showBorder()
}
func showBorder() {
if (!shouldShowBorder) {return}
if let rect = self.rect {
self.removeChildren(in: [rect])
}
self.rect = SKShapeNode(rectOf: CGSize(width: labelWidth, height: labelHeight))
if let rect = self.rect {
rect.strokeColor = UIColor.white
rect.lineWidth = 1
rect.position = CGPoint(x: pos.x, y: pos.y - (CGFloat(labelHeight) / 2.0))
self.addChild(rect)
}
}
}
Here you can set your position, font, font size, colour and everything you need.
在这里你可以设置你的位置、字体、字体大小、颜色和你需要的一切。
Let me know if that helps
让我知道这是否有帮助
回答by Charlie
You do not mention whether or not you are using a Stack View. The normal way of doing it (as provided by good4pc) does not work properly if you put a UILabel in a Stack View.
您没有提及您是否使用堆栈视图。如果您将 UILabel 放在 Stack View 中,那么正常的做法(由 good4pc 提供)将无法正常工作。
If you are using a stack view:
如果您使用堆栈视图:
Make a custom label class that will work right. I have pasted one below - simply make a new swift file and place this code in it. Call the swift file "MultilineLabelThatWorks". Then, define the label as a "MultilineLabelThatWorks" instead of "UILabel"
制作一个可以正常工作的自定义标签类。我在下面粘贴了一个 - 只需创建一个新的 swift 文件并将此代码放入其中。调用 swift 文件“MultilineLabelThatWorks”。然后,将标签定义为“MultilineLabelThatWorks”而不是“UILabel”
import UIKit
class MultilineLabelThatWorks : UILabel {
override func layoutSubviews() {
super.layoutSubviews()
preferredMaxLayoutWidth = bounds.width
super.layoutSubviews()
}
}
Now you can set it to wrap text as discussed by good4pc and it will wrap properly.
现在您可以将其设置为按照 good4pc 所讨论的换行文本,它将正确换行。