Skip to content

Instantly share code, notes, and snippets.

@craiggrummitt
Last active April 11, 2020 03:05

Revisions

  1. craiggrummitt revised this gist Oct 10, 2016. 1 changed file with 27 additions and 29 deletions.
    56 changes: 27 additions & 29 deletions SKMultilineLabel.swift
    Original file line number Diff line number Diff line change
    @@ -2,17 +2,14 @@
    // SKMultilineLabel.swift
    //
    // Created by Craig on 10/04/2015.
    // Copyright (c) 2015 Interactive Coconut.
    // Copyright (c) 2015 Interactive Coconut.
    // MIT License, http://www.opensource.org/licenses/mit-license.php
    //
    /* USE:

    (most component parameters have defaults)

    let multiLabel = SKMultilineLabel(text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", labelWidth: 250, pos: CGPoint(x: size.width / 2, y: size.height / 2))
    self.addChild(multiLabel)

    */
    (most component parameters have defaults)
    let multiLabel = SKMultilineLabel(text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", labelWidth: 250, pos: CGPoint(x: size.width / 2, y: size.height / 2))
    self.addChild(multiLabel)
    */

    import SpriteKit

    @@ -33,23 +30,27 @@ class SKMultilineLabel: SKNode {
    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)
    init(text:String, labelWidth:Int, pos:CGPoint, fontName:String="ChalkboardSE-Regular",fontSize:CGFloat=10,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
    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() {
    @@ -60,31 +61,28 @@ class SKMultilineLabel: SKNode {
    }
    labels = []
    }
    let separators = NSCharacterSet.whitespaceAndNewlineCharacterSet()
    let words = text.componentsSeparatedByCharactersInSet(separators)

    let len = countElements(text)

    let separators = NSCharacterSet.whitespacesAndNewlines
    let words = (text as NSString).components(separatedBy: separators)
    var finalLine = false
    var wordCount = -1
    var lineCount = 0
    while (!finalLine) {
    lineCount++
    lineCount+=1
    var lineLength = CGFloat(0)
    var lineString = ""
    var lineStringBeforeAddingWord = ""

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

    while lineLength < CGFloat(labelWidth)
    {
    wordCount++
    wordCount+=1
    if wordCount > words.count-1
    {
    //label.text = "\(lineString) \(words[wordCount])"
    @@ -96,26 +94,25 @@ class SKMultilineLabel: SKNode {
    lineStringBeforeAddingWord = lineString
    lineString = "\(lineString) \(words[wordCount])"
    label.text = lineString
    lineLength = label.width
    lineLength = label.frame.width
    }
    }
    if lineLength > 0 {
    wordCount--
    wordCount-=1
    if (!finalLine) {
    lineString = lineStringBeforeAddingWord
    }
    label.text = lineString
    var linePos = pos
    if (alignment == .Left) {
    if (alignment == .left) {
    linePos.x -= CGFloat(labelWidth / 2)
    } else if (alignment == .Right) {
    } else if (alignment == .right) {
    linePos.x += CGFloat(labelWidth / 2)
    }
    linePos.y += CGFloat(-leading * lineCount)
    label.position = CGPointMake( linePos.x , linePos.y )
    label.position = CGPoint(x:linePos.x , y:linePos.y )
    self.addChild(label)
    labels.append(label)
    //println("was \(lineLength), now \(label.width)")
    }

    }
    @@ -125,15 +122,16 @@ class SKMultilineLabel: SKNode {
    func showBorder() {
    if (!shouldShowBorder) {return}
    if let rect = self.rect {
    self.removeChildrenInArray([rect])
    self.removeChildren(in: [rect])
    }
    self.rect = SKShapeNode(rectOfSize: CGSize(width: labelWidth, height: labelHeight))
    self.rect = SKShapeNode(rectOf: CGSize(width: labelWidth, height: labelHeight))
    if let rect = self.rect {
    rect.strokeColor = UIColor.whiteColor()
    rect.strokeColor = UIColor.white
    rect.lineWidth = 1
    rect.position = CGPoint(x: pos.x, y: pos.y - (CGFloat(labelHeight) / 2.0))
    self.addChild(rect)
    }

    }
    }

  2. craiggrummitt revised this gist Oct 10, 2016. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion SKMultilineLabel.swift
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,8 @@
    // SKMultilineLabel.swift
    //
    // Created by Craig on 10/04/2015.
    // Copyright (c) 2015 Interactive Coconut. All rights reserved.
    // Copyright (c) 2015 Interactive Coconut.
    // MIT License, http://www.opensource.org/licenses/mit-license.php
    //
    /* USE:

  3. craiggrummitt revised this gist Apr 10, 2015. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion SKMultilineLabel.swift
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,5 @@
    //
    // SKMultilineLabel.swift
    // GrabbleWords
    //
    // Created by Craig on 10/04/2015.
    // Copyright (c) 2015 Interactive Coconut. All rights reserved.
  4. craiggrummitt revised this gist Apr 10, 2015. 1 changed file with 0 additions and 3 deletions.
    3 changes: 0 additions & 3 deletions SKMultilineLabel.swift
    Original file line number Diff line number Diff line change
    @@ -136,7 +136,4 @@ class SKMultilineLabel: SKNode {
    }

    }
    required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
    }
    }
  5. craiggrummitt created this gist Apr 10, 2015.
    142 changes: 142 additions & 0 deletions SKMultilineLabel.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,142 @@
    //
    // SKMultilineLabel.swift
    // GrabbleWords
    //
    // Created by Craig on 10/04/2015.
    // Copyright (c) 2015 Interactive Coconut. All rights reserved.
    //
    /* USE:

    (most component parameters have defaults)

    let multiLabel = SKMultilineLabel(text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", labelWidth: 250, pos: CGPoint(x: size.width / 2, y: size.height / 2))
    self.addChild(multiLabel)

    */

    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)
    }

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