2016-02-01 8 views
8

Devo essere in grado di creare un'etichetta su più righe in quick 2 sprite-kit per un gioco. Il testo deve avvolgersi piuttosto che uscire dallo schermo. Bellow è quello che ho, ma non so cosa fareEtichetta multilinea in kit 2 sprite rapido?

import Foundation 
import UIKit 
import SpriteKit 

class JDQuotes: SKLabelNode { 

    var number = 0 

    init(num: Int) { 
     super.init() 

     if num == 1 { 

      text = "\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. laborum.\"" 

     } 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 
+0

Vorrei solo un UIlabel e aggiungere come sottoview, sopra SKView. – jarryd

+0

Ecco una soluzione di terze parti. SKLabels generalmente non supporta più righe. 'https: // craiggrummitt.wordpress.com/2015/04/10/multi-line-sklabels-in-swift /' – Akaino

risposta

3

C'è una soluzione Github sopra here come SKLabelNodes non supportano più linee.

Codice citato:

import SpriteKit 

class SKMultilineLabel: 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=10,fontColor:UIColor=UIColor.blackColor(),leading:Int=10, 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 
    self.shouldShowBorder = shouldShowBorder 
    self.alignment = alignment 

    super.init() 

    self.update() 
} 

//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.whitespaceAndNewlineCharacterSet() 
    let words = text.componentsSeparatedByCharactersInSet(separators) 

    let len = countElements(text) 

    var finalLine = false 
    var wordCount = -1 
    var lineCount = 0 
    while (!finalLine) { 
     lineCount++ 
     var lineLength = CGFloat(0) 
     var lineString = "" 
     var lineStringBeforeAddingWord = "" 

     // creation of the SKLabelNode itself 
     var 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 = UIColor.whiteColor() 

     while lineLength < CGFloat(labelWidth) 
     { 
      wordCount++ 
      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.width 
      } 
     } 
     if lineLength > 0 { 
      wordCount-- 
      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 = CGPointMake(linePos.x , linePos.y) 
      self.addChild(label) 
      labels.append(label) 
      //println("was \(lineLength), now \(label.width)") 
     } 

    } 
    labelHeight = lineCount * leading 
    showBorder() 
} 
func showBorder() { 
    if (!shouldShowBorder) {return} 
    if let rect = self.rect { 
     self.removeChildrenInArray([rect]) 
    } 
    self.rect = SKShapeNode(rectOfSize: CGSize(width: labelWidth, height: labelHeight)) 
    if let rect = self.rect { 
     rect.strokeColor = UIColor.whiteColor() 
     rect.lineWidth = 1 
     rect.position = CGPoint(x: pos.x, y: pos.y - (CGFloat(labelHeight)/2.0)) 
     self.addChild(rect) 
    } 

} 
} 

EDIT: Si potrebbe anche verificare this version troppo come è aggiornata per Swift2

+0

Un problema con questo è che SKLabelNode non è reso in batch come SKSpriteNode. Quindi, se hai un'etichetta di 20 righe, richiederà 20 passaggi di disegno e questo potrebbe influire sulle prestazioni. Si potrebbe provare ad aggiungere un'istanza multi etichetta a un SKEffectNode e quindi rasterizzarla. Ciò ridurrà i passaggi di disegno richiesti per il rendering di etichette multistrato a 1. – Whirlwind

+0

Non ho notato problemi di prestazioni estremi con esso finora. Non sto esagerando con le etichette multiline, quindi potresti avere ragione. – Akaino

+1

Apprezzo il tuo sforzo, non fraintendermi, ma non gestisci certe situazioni. Passare una stringa più lunga di 'labelWidth' finirà in loop infinito (al momento di parlare). – Whirlwind

4

partire iOS 11, questo diventa finalmente possibile con SKLabelNode:

let lb = SKLabelNode(fontNamed: "Copperplate") 
    lb.text = "Put your long text here..." 
    lb.numberOfLines = 0 
    lb.preferredMaxLayoutWidth = 1000 
Problemi correlati