2016-02-01 11 views
8

मुझे एक गेम के लिए स्विफ्ट 2 स्प्राइट-किट में एक बहु-पंक्ति लेबल बनाने में सक्षम होना चाहिए। पाठ को स्क्रीन से बाहर जाने के बजाए चारों ओर लपेटने की जरूरत है। Bellow मैं क्या है, लेकिन मैंस्विफ्ट 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 होगा और SKView के ऊपर एक सबव्यूव के रूप में जोड़ूंगा। – jarryd

+0

यहां एक तृतीय पक्ष समाधान है। एसकेएलबेल आमतौर पर कई लाइनों का समर्थन नहीं करते हैं। 'https: // craiggrummitt.wordpress.com/2015/04/10/बहु-रेखा-स्केबेल-इन-स्विफ्ट /' – Akaino

उत्तर

3

क्या करना है वहाँ here पर एक Github समाधान 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) 
    } 

} 
} 

संपादित करें: साथ ही आप भी this version जाँच कर सकते हैं के रूप में यह Swift2

+0

इसके साथ एक समस्या यह है कि एसकेएलबेल नोड एसकेएसप्रिट नोड जैसे बैचों में प्रस्तुत नहीं किया जाता है। इसलिए, यदि आपके पास 20 लाइन लेबल हैं, तो उसे 20 ड्रा पास की आवश्यकता होगी और यह प्रदर्शन पर असर डाल सकता है। आप एक बहु-लेबल उदाहरण को SKEffectNode में जोड़ने का प्रयास कर सकते हैं और फिर इसे रास्टराइज़ कर सकते हैं। यह बहु-लाइन वाले लेबल प्रतिपादन के लिए आवश्यक ड्रा पास को कम करेगा। – Whirlwind

+0

मैंने अब तक अत्यधिक प्रदर्शन समस्याओं को नहीं देखा है। मैं बहुभाषी लेबल का उपयोग नहीं कर रहा हूं, हालांकि आप सही हो सकते हैं। – Akaino

+1

मैं आपके प्रयास की सराहना करता हूं, मुझे गलत मत समझो, लेकिन आप कुछ स्थितियों को संभाल नहीं पाते हैं। 'लेबलविड्थ' से अधिक लंबी स्ट्रिंग पास करना अनंत लूप (बोलने के समय) में समाप्त हो जाएगा। – Whirlwind

4

आईओएस शुरूआती 11 के लिए अपडेट किया जाता है यह अंत में संभव SKLabelNode साथ हो जाता है:

let lb = SKLabelNode(fontNamed: "Copperplate") 
    lb.text = "Put your long text here..." 
    lb.numberOfLines = 0 
    lb.preferredMaxLayoutWidth = 1000 
संबंधित मुद्दे