Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SKLabelNode Border and Bounds Issue

I am attempting to create text that has an outline. I am currently using SKLabelNode with NSAttributedString, which you can now do in SpriteKit as of iOS 11. The problem is, if the stroke width is too thick, then the outline gets cut off by what appears to be the bounding rectangle of the SKLabelNode. Please see below for the image and code.

Cutoff font

extension SKLabelNode {

    func addStroke(_ strokeColor:UIColor) {

        let font = UIFont(name: self.fontName!, size: self.fontSize)
        let attributes:[NSAttributedStringKey:Any] = [.strokeColor: strokeColor, .strokeWidth: 20.0, .font: font!]
        let attributedString = NSMutableAttributedString(string: " \(self.text!) ", attributes: attributes)
        let label1 = SKLabelNode()
        label1.horizontalAlignmentMode = self.horizontalAlignmentMode
        label1.text = self.text
        label1.zPosition = -1
        label1.attributedText = attributedString
        self.addChild(label1)
    }
}

I looked at expanding the frame of the SKLabelNode serving as the border text, but that is a get-only property. I tried to add leading/trailing spaces, but they appear to be automatically trimmed. Using a negative value for strokeWidth works but creates an inner stroke, I'd prefer to have an outer stroke.

Any ideas? Thanks in advance for the help! Mike

like image 762
MikeL Avatar asked Jul 11 '26 09:07

MikeL


1 Answers

  1. You shouldn't need to create a separate node for the stroke.
  2. Use negative width values to only render the stroke without fill.
  3. Use .foregroundColor to fill.
  4. You should first check to see if an attributed string is already present to ensure you do not clobber it.

Here is the code:

extension SKLabelNode {

   func addStroke(color:UIColor, width: CGFloat) {

        guard let labelText = self.text else { return }

        let font = UIFont(name: self.fontName!, size: self.fontSize)

        let attributedString:NSMutableAttributedString
        if let labelAttributedText = self.attributedText {
            attributedString = NSMutableAttributedString(attributedString: labelAttributedText)
        } else {
            attributedString = NSMutableAttributedString(string: labelText)
        }

        let attributes:[NSAttributedStringKey:Any] = [.strokeColor: color, .strokeWidth: -width, .font: font!, .foregroundColor: self.fontColor!]
        attributedString.addAttributes(attributes, range: NSMakeRange(0, attributedString.length))

        self.attributedText = attributedString
   }
}
like image 50
Nader Eloshaiker Avatar answered Jul 14 '26 22:07

Nader Eloshaiker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!