如何在 SwiftUI 中制作文本笔划?

Nic*_*s M 13 text border outline stroke swiftui

我正在尝试在 SwiftUI 中进行文本笔画或在我的文本上添加边框,而不是在Text()项目中的字母中。

是否可以?

我想用边框制作这种效果: 影响

Wen*_*iga 23

我找到了另一个创建笔划的技巧,但只有当您所需的笔划宽度不超过 1 时它才有效

Text("Hello World")
   .shadow(color: .black, radius: 1)
Run Code Online (Sandbox Code Playgroud)

我使用了shadow,但要确保半径仅为 1,以获得相同的效果

  • 你还可以在上面叠加更多的 .shadow() 来使效果更强。尝试其中 10 个,每个半径为“0.4” (3认同)

Jos*_*tos 20

这是一个 100% SwiftUI 解决方案。并不完美,但它可以工作,并且可以让您对结果视图进行完全的 SwiftUI 控制。

在此处输入图片说明

import SwiftUI

struct SomeView: View {
    var body: some View {
        StrokeText(text: "Sample Text", width: 0.5, color: .red)
            .foregroundColor(.black)
            .font(.system(size: 12, weight: .bold))

    }
}

struct StrokeText: View {
    let text: String
    let width: CGFloat
    let color: Color

    var body: some View {
        ZStack{
            ZStack{
                Text(text).offset(x:  width, y:  width)
                Text(text).offset(x: -width, y: -width)
                Text(text).offset(x: -width, y:  width)
                Text(text).offset(x:  width, y: -width)
            }
            .foregroundColor(color)
            Text(text)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我建议使用粗体。它适用于合理大小的字体和笔画宽度。对于较大的尺寸,您可能需要在更多角度添加文本偏移以覆盖该区域。


pae*_*ebu 17

这是另一种方法,无需覆盖 Text 对象的副本。适用于任何形状或视图:

extension View {
    func stroke(color: Color, width: CGFloat = 1) -> some View {
        modifier(StrokeModifier(strokeSize: width, strokeColor: color))
    }
}

struct StrokeModifier: ViewModifier {
    private let id = UUID()
    var strokeSize: CGFloat = 1
    var strokeColor: Color = .blue

    func body(content: Content) -> some View {
        if strokeSize > 0 {
            appliedStrokeBackground(content: content)
        } else {
            content
        }
    }

    private func appliedStrokeBackground(content: Content) -> some View {
        content
            .padding(strokeSize*2)
            .background(
                Rectangle()
                    .foregroundColor(strokeColor)
                    .mask(alignment: .center) {
                        mask(content: content)
                    }
            )
    }

    func mask(content: Content) -> some View {
        Canvas { context, size in
            context.addFilter(.alphaThreshold(min: 0.01))
            if let resolvedView = context.resolveSymbol(id: id) {
                context.draw(resolvedView, at: .init(x: size.width/2, y: size.height/2))
            }
        } symbols: {
            content
                .tag(id)
                .blur(radius: strokeSize)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


bac*_*h-f 10

我认为没有办法做到“开箱即用”。
到目前为止(beta 5)我们只能应用笔画Shapes

例如:

struct SomeView: View {
    var body: some View {
        Circle().stroke(Color.red)
    }
}
Run Code Online (Sandbox Code Playgroud)

但同样不适用于Text.

UIViewRepresentable

另一种方法是使用好醇” UIKit\NSAttributedString通过与SwiftUI UIViewRepresentable

像这样:

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
Run Code Online (Sandbox Code Playgroud)

结果

结果

当然,您必须调整 的属性(大小、字体、颜色等)NSAttributedString以生成所需的输出。为此,我会推荐Visual Attributed String macOS 应用程序。


Hex*_*ons 6

您可以使用SwiftFX做到这一点

import SwiftUI
import SwiftFX

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .fxEdge()
    }
}
Run Code Online (Sandbox Code Playgroud)

这是斯威夫特包:

.package(url: "https://github.com/hexagons/SwiftFX.git", from: "0.1.0")
Run Code Online (Sandbox Code Playgroud)

设置说明请参见此处