如何使 SwiftUI 中的 SF 符号具有相同的宽度

Posted

技术标签:

【中文标题】如何使 SwiftUI 中的 SF 符号具有相同的宽度【英文标题】:How to make SF Symbols in SwiftUI have the same width 【发布时间】:2020-10-21 02:15:22 【问题描述】:

有没有办法让相同大小的所有符号都具有相同的宽度?

从下面的屏幕截图中可以看出,person.2.fill 的宽度最长,square.and.arrow.up 的宽度最近。在这种情况下,将字体设置为等距字体似乎没有任何改变。

Image(systemName: "square.and.arrow.up")
    .font(Font.system(size: 18, weight: .medium, design: .monospaced))

解决方法不是“强制”它们具有相同的宽度,而是在相同宽度的容器内水平居中。

【问题讨论】:

签出this 但它们是符号,确实有不同的宽度......这与要求 IW 的尺寸相同。 @Asperi,有道理。感谢您的评论 【参考方案1】:

我使用PreferenceKey 修复了这个问题,也适用于动态字体大小。

在 Xcode13.2 Swift5.5 中测试

struct ContentView: View 

    @State private var iconWidth: Double = 0

    private var icons: [String] = ["person.crop.circle", "tag", "text.book.closed", "icloud.and.arrow.up"]

    var body: some View 
        List(icons, id: \.self)  iconName in
            HStack 
                Image(systemName: iconName)
                    .sync(with: $iconWidth)
                    .frame(width: iconWidth)

                Text(iconName)
            
            .onPreferenceChange(SymbolWidthPreferenceKey.self)  iconWidth = $0 
        
    


struct SymbolWidthPreferenceKey: PreferenceKey 

    static var defaultValue: Double = 0

    static func reduce(value: inout Double, nextValue: () -> Double) 
        value = max(value, nextValue())
    


struct SymbolWidthModifier: ViewModifier 

    @Binding var width: Double

    func body(content: Content) -> some View 
        content
            .background(GeometryReader  geo in
                Color
                    .clear
                    .preference(key: SymbolWidthPreferenceKey.self, value: geo.size.width)
            )
    


extension Image 

    func sync(with width: Binding<Double>) -> some View 
         modifier(SymbolWidthModifier(width: width))
    

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。【参考方案2】:

该问题的解决方法。但是,问题在于它不适用于动态字体大小。

HStack 
    Image(systemName: "square.and.arrow.up")
        .font(Font.system(size: 18, weight: .medium, design: .monospaced))
        .foregroundColor(Color("secondary"))

.frame(minWidth: 30)

【讨论】:

以上是关于如何使 SwiftUI 中的 SF 符号具有相同的宽度的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 如何在文本视图中更改自定义 SF 符号的颜色?

使 SwiftUI 矩形与另一个矩形具有相同的高度或宽度

如何正确创建 SF 符号?

自定义 SF 符号不呈现分层着色

swiftui 在您的项目中使用非 SF Symbols SVG

有没有办法在 macOS SwiftUI 开发中使用 SF Symbols?