这是我的解决方案,但这很大程度上是一个hack,我不知道苹果是否会批准。所以我想这个答案只适用于“教育目的”。
概念
主要思路是修改SF Symbols应用程序导出的SVG文件,使其仅包含所选符号的一个实例,而不是完整模板,并使用SVGKit框架通过NSViewRepresentable
对象显示它。
导出
在您的Mac上使用SF Symbols应用程序并选择要使用的符号,然后执行“导出自定义符号模板”。
修改
在文本编辑器(如Sublime Text或CotEditor)中打开导出的SVG文件。
删除文件中除标题和“Symbols”字段之外的所有内容,该字段应仅包含您想要使用的符号变体。然后更改呈现画布的大小并正确对齐符号。
例如,如果您想使用“plus”符号的“Regular-L”版本,则最终的“plus.svg”文件应该像这样:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128">
<g id="Symbols">
<g id="Regular-L" transform="matrix(1 0 0 1 0 100)">
<path d="M 67.4316 17.3828 C 70.0684 17.3828 72.2168 15.2832 72.2168 12.7441 L 72.2168 -30.3711 L 114.062 -30.3711 C 116.65 -30.3711 118.848 -32.5684 118.848 -35.1562 C 118.848 -37.793 116.65 -39.9414 114.062 -39.9414 L 72.2168 -39.9414 L 72.2168 -83.1055 C 72.2168 -85.6445 70.0684 -87.7441 67.4316 -87.7441 C 64.8438 -87.7441 62.6953 -85.6445 62.6953 -83.1055 L 62.6953 -39.9414 L 20.8496 -39.9414 C 18.2617 -39.9414 16.0645 -37.793 16.0645 -35.1562 C 16.0645 -32.5684 18.2617 -30.3711 20.8496 -30.3711 L 62.6953 -30.3711 L 62.6953 12.7441 C 62.6953 15.2832 64.8438 17.3828 67.4316 17.3828 Z"/>
</g>
</g>
</svg>
总之:
- 保留标题
- 保留`id="Symbols"`字段
- 在符号字段中,仅保留一个类别,在我的示例中为`id="Regular-L"`
- 更改标题中的大小,在我的示例中为`width="128" height="128"`
- 通过更改变换字段的最后两个参数来对齐符号,在我的示例中为`transform="matrix(1 0 0 1 0 100)"`(x 0和y 100)
安装SVGKit:
- 关闭Xcode
- 使用Cocoapods版本安装SVGKit(
https://github.com/SVGKit/SVGKit)
- 打开Cocoapods创建的.xcworkspace文件
制作视图:
将修改后的`plus.svg`文件添加到项目中(不在资源目录中,而是在项目本身中)
像这样添加一个`NSViewRepresentable`结构:
import SVGKit
struct IconView: NSViewRepresentable {
let name: String
func makeNSView(context: Context) -> SVGKFastImageView {
let img = SVGKImage(named: name)!
return SVGKFastImageView(svgkImage: img)!
}
func updateNSView(_ nsView: SVGKFastImageView, context: Context) {
}
}
使用视图
然后在您的ContentView中使用它(给它一个框架,以便它不会填满整个窗口),例如:
struct ContentView: View {
var body: some View {
VStack {
IconView(name: "plus")
.frame(width: 200, height: 200, alignment: .center)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}