textborderswiftuioutlinestroke

How to make text stroke in SwiftUI?


I'm trying to make text-stroke in SwiftUI or add a border on my text, in the letters not the Text() item.

Is it possible?

I want to make this effect with the border: effect
(source: noelshack.com)


Solution

  • I don't think there's a way for doing that "out of the box".
    So far (beta 5) we can apply strokes to Shapes only.

    For example:

    struct SomeView: View {
        var body: some View {
            Circle().stroke(Color.red)
        }
    }
    

    But again that isn’t available for Text.

    UIViewRepresentable

    Another approach would be to use the good ol' UIKit \ NSAttributedString with SwiftUI via UIViewRepresentable.

    Like so:

    import SwiftUI
    import UIKit
    
    struct SomeView: View {
        var body: some View {
            StrokeTextLabel()
        }
    }
    
    struct StrokeTextLabel: UIViewRepresentable {
        func makeUIView(context: Context) -> UILabel {
            let attributedStringParagraphStyle = NSMutableParagraphStyle()
            attributedStringParagraphStyle.alignment = NSTextAlignment.center
            let attributedString = NSAttributedString(
                string: "Classic",
                attributes:[
                    NSAttributedString.Key.paragraphStyle: attributedStringParagraphStyle,
                    NSAttributedString.Key.strokeWidth: 3.0,
                    NSAttributedString.Key.foregroundColor: UIColor.black,
                    NSAttributedString.Key.strokeColor: UIColor.black,
                    NSAttributedString.Key.font: UIFont(name:"Helvetica", size:30.0)!
                ]
            )
    
            let strokeLabel = UILabel(frame: CGRect.zero)
            strokeLabel.attributedText = attributedString
            strokeLabel.backgroundColor = UIColor.clear
            strokeLabel.sizeToFit()
            strokeLabel.center = CGPoint.init(x: 0.0, y: 0.0)
            return strokeLabel
        }
    
        func updateUIView(_ uiView: UILabel, context: Context) {}
    }
    
    #if DEBUG
    struct SomeView_Previews: PreviewProvider {
        static var previews: some View {
            SomeView()
        }
    }
    #endif
    

    Result

    result

    Of course you have to tweak the attributes (size, font, color, etc) of the NSAttributedString to generate the desired output. For that I would recommend the Visual Attributed String macOS app.