Text 如何在SwiftUI中创建文本笔划?
我试图在SwiftUI中创建文本笔划或在文本上添加边框,而不是在Text 如何在SwiftUI中创建文本笔划?,text,border,swiftui,outline,stroke,Text,Border,Swiftui,Outline,Stroke,我试图在SwiftUI中创建文本笔划或在文本上添加边框,而不是在text()项中的字母中 可能吗 我想对边界产生这样的效果: 我认为没有一种方法可以“开箱即用”地做到这一点。 到目前为止(beta 5),我们只能在形状上应用笔划 例如: struct SomeView: View { var body: some View { Circle().stroke(Color.red) } } 但这同样不适用于文本 UIViewRepresentable 另一种方法是
text()
项中的字母中
可能吗
我想对边界产生这样的效果:
我认为没有一种方法可以“开箱即用”地做到这一点。
到目前为止(beta 5),我们只能在
形状上应用笔划
例如:
struct SomeView: View {
var body: some View {
Circle().stroke(Color.red)
}
}
但这同样不适用于文本
UIViewRepresentable
另一种方法是通过uiviewsrepresentable
将好的ol'UIKit
\NSAttributedString
与SwiftUI一起使用
像这样:
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
结果
当然,您必须调整NSAttributedString
的属性(大小、字体、颜色等)以生成所需的输出。为此,我推荐macOS应用程序。这里有一个100%的SwiftUI解决方案。虽然不完美,但它可以工作,并且可以让您完全快速地控制结果视图
我建议使用粗体字。使用大小合理的字体和笔划宽度,效果更好。对于较大的尺寸,您可能需要添加更多角度的文本偏移以覆盖该区域。
您可以使用
import SwiftUI
import SwiftFX
struct ContentView: View {
var body: some View {
Text("Hello, World!")
.fxEdge()
}
}
这是Swift套餐:
.package(url: "https://github.com/hexagons/SwiftFX.git", from: "0.1.0")
设置说明。我找到了另一个创建笔划的技巧,但只有当您希望的笔划宽度不超过1时才有效
Text(“你好,世界”)
.shadow(颜色:。黑色,半径:1)
我使用了阴影
,但确保半径仅为1,以获得相同的效果在改为使用此方法之前,我使用了“偏移”文本解决方案,并发现其效果更好。它还有一个额外的好处,就是允许大纲文本内部中空,而无需下载软件包即可获得简单的效果
它通过叠加阴影和保持较低的半径在物体周围形成一条实线来工作。如果你想要一个更厚的边框,你需要在扩展中添加更多的.shadow修改器,但是对于我所有的文本需求,这已经做得很好了。另外,它也适用于图片
它并不完美,但我喜欢简单的解决方案,这些解决方案停留在SwifUI领域,并且可以轻松实现
最后,outline Bool参数应用了一个倒置的掩码(SwiftUI还缺少一些东西),我也提供了这个扩展
extension View {
@ViewBuilder
func viewBorder(color: Color = .black, radius: CGFloat = 0.4, outline: Bool = false) -> some View {
if outline {
self
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.invertedMask(
self
)
} else {
self
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
}
}
}
扩展视图{
func invertedMask(ucontent:content)->一些视图{
自己
.面具(
ZStack{
自己
.亮度(1)
内容
.亮度(-1)
}.compositingGroup()
.阿尔法亮度()
)
}
}
同样,这不是一个“完美”的解决方案,但它是一个简单而有效的解决方案。⚠️ 编辑:在清理Xcode缓存后…它不再工作了,非常感谢!事实上,从昨天开始,我在网上搜索,解决办法是使用UIKit,但我的swift水平很差。我希望苹果能用一种简单的方法在swiftUI中制作未来的复杂文本效果。当我将其更改为UITextField并按下键盘上的return键时,这会导致应用程序冻结。我需要改变一些东西才能让它工作吗?你试过用阴影吗?不是你要求的那样,但外观可能类似。嗨,我试过使用4个阴影,x位置为1和-1,y位置相同(半径为0),效果很好。这确实有助于在图像上过度显示时“弹出”一些文本。你还可以在其上叠加更多的.shadow()
s,使效果更强烈。试10个半径为0.4
eachI首先尝试了你的解决方案,因为它与金属一起工作,所以我认为它比使用4个Text
s要好。我有点失望……因为它的工作原理是一样的:/I尝试使用.fxEdge(强度:.constant(1),距离:.constant(100))
(自愿极端)并获得了5个文本标签:/I很抱歉,但由于金属库的设置要求,我不会使用您的解决方案。是的,设置有点烦人。由于Swift Package manager有资源支持,我现在将尝试修复此问题。但老实说,我个人同意用反斜杠f表示视图的方法。我希望有一天SwiftUI会为文本添加对笔划修改器的支持。我昨天花了几个小时研究了一个解决方案,今天早上就完成了。这是6行纯迅捷,工作完美!我可以做任何事情(非常大的笔划,非不透明的颜色…),当我在这里写我的长答案时,我清理了XCode的缓存,它停止了编辑:它与单色IIRC完美配合,并用彩色笔划显示笔划周围的人工制品。我设法让我的解决方案再次工作,并分享了它:。我将很快添加图片。
extension View {
@ViewBuilder
func viewBorder(color: Color = .black, radius: CGFloat = 0.4, outline: Bool = false) -> some View {
if outline {
self
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.invertedMask(
self
)
} else {
self
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
.shadow(color: color, radius: radius)
}
}
extension View {
func invertedMask<Content : View>(_ content: Content) -> some View {
self
.mask(
ZStack {
self
.brightness(1)
content
.brightness(-1)
}.compositingGroup()
.luminanceToAlpha()
)
}