2016-02-01 3 views
8

Мне нужно сделать многострочный ярлык в swift 2 sprite-kit для игры. Текст нужно обернуть, а не выйти из экрана. Беллоу, что у меня есть, но я не знаю, что делатьМногострочная этикетка в быстром 2 комплекте спрайтов?

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

Я бы просто пользователь UIlabel и добавить как subview, над SKView. – jarryd

+0

Это решение третья сторона. SKLabels обычно не поддерживают несколько строк. 'https: // craiggrummitt.wordpress.com/2015/04/10/multi-line-sklabels-in-swift /' – Akaino

ответ

3

Существует решение Github над here в SKLabelNodes не поддерживают несколько строк.

Код цитировал:

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: Вы можете также проверить this version тоже, как он обновляется для Swift2

+0

Одна из проблем заключается в том, что SKLabelNode не отображается в пакетах, таких как SKSpriteNode. Итак, если у вас есть 20-строчная метка, для нее потребуется 20 обратных проходов, и это может повлиять на производительность. Вы можете попробовать добавить экземпляр с несколькими метками в SKEffectNode, а затем растрировать его. Это уменьшит количество проходов, необходимых для рендеринга многострочных меток, на 1. – Whirlwind

+0

Я пока не замечал экстремальных проблем с производительностью. Я не злоупотребляю многострочными надписями, хотя, возможно, вы правы. – Akaino

+1

Я ценю ваши усилия, не поймите меня неправильно, но вы не справляетесь с определенными ситуациями. Передача строки длиннее, чем 'labelWidth', заканчивается бесконечным циклом (в момент разговора). – Whirlwind

4

Начиная IOS 11, это, наконец, становится возможным с SKLabelNode:

let lb = SKLabelNode(fontNamed: "Copperplate") 
    lb.text = "Put your long text here..." 
    lb.numberOfLines = 0 
    lb.preferredMaxLayoutWidth = 1000 
Смежные вопросы