带有 SF 符号的 HStack 图像未居中对齐

HStack with SF Symbols Image not aligned centered

我有这个简单的 SwiftUI 代码。我希望所有符号都居中对齐,就像云符号一样。

struct ContentView : View {
var body: some View {
    HStack(alignment: .center, spacing: 10.0) {
        Image(systemName: "cloud.sun")
        Image(systemName: "cloud")
        Image(systemName: "cloud.bolt")
        Text("Text")
        }.font(.title)
    }
}

但是如下图所示,第一个和最后一个符号没有居中。我是不是遗漏了什么,或者这是一个错误?

干杯!

事情就是这样。

Image 视图未调整大小。

他们似乎没有意识到其固有内容的大小,或者可能报告了错误的值。

修复:

struct ContentView : View {
    var body: some View {
        HStack(alignment: .center, spacing: 10.0) {
            Image(systemName: "cloud.sun")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .background(Color.red)
            Image(systemName: "cloud")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .background(Color.yellow)
            Image(systemName: "cloud.bolt")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .background(Color.pink)
            Text("Text").background(Color.green)
        }
        .frame(width: 250, height: 50)
        .background(Color.gray)
        .font(.title)

    }
}

...使 Images 可调整大小,并确保纵横比设置为 .fit,否则它们会拉伸。

同时在 HStack 上设置框架,否则它会扩展以填满整个屏幕。

@MartinR 提出了一个更好的解决方案 - 通过 UIImage 创建图像 - 请参阅下面的评论。

struct ContentView : View {

    var body: some View {
        HStack {
            Image(uiImage: UIImage(systemName: "cloud.sun")!)
                .background(Color.red)
            Image(uiImage: UIImage(systemName: "cloud")!)
                .background(Color.yellow)
            Image(uiImage: UIImage(systemName: "cloud.bolt")!)
                .background(Color.pink)
            Text("Text").background(Color.green)
        }
        .background(Color.gray)
        .font(.title)

    }

}

输出:

我遇到了和你一样的问题:SF Symbols 在 iOS 13 上没有报告正确的内容大小。(不过,它在 iOS 14 及更高版本上是固定的。)

使用 Matteo Pacinis 解决方案中提出的 UIImage 的问题是与 SwiftUI 动态的兼容性差:前景色和字体大小(以及动态类型!)不是简单地从当前的 SwiftUI 上下文中获取的,而是必须复制到 UIImage 配置中(使用 UIImage(systemName:, withConfiguration:)),这通常是不切实际的。 (请参阅 hackingwithswift.com 了解如何使用它)。

针对以上问题,我提出以下解决方案:

HStack(alignment: .center, spacing: 10.0) {
    Image(systemName: "cloud.sun")
        .hidden()
        .overlay(
            Image(systemName: "cloud.sun")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .background(Color.red)
        )
    Image(systemName: "cloud")
        .hidden()
        .overlay(
            Image(systemName: "cloud")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .background(Color.yellow)
        )
    Image(systemName: "cloud.bolt")
        .hidden()
        .overlay(
            Image(systemName: "cloud.bolt")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .background(Color.pink)
        )
    Text("Text")
        .background(Color.green)
}
.background(Color.gray)
.font(.title)

它看起来像很多代码重复,但它有一个优点,即符号根据您的 font 缩放,遵守 foregroundColor 修饰符并根据您想要的 [=16= 对齐]

输出:

但是这种方法仍然存在一些问题:图像仍然没有正确的固有尺寸,符号只是“很好地居中”绘制的。这意味着 HStack 的高度仍然取决于 Text 元素的高度。 如果您只想绘制 .largeTitle 字体的符号和 .body 字体的文本,结果如​​下所示,可能导致与相邻视图重叠:

我仍将进一步调查以找到确保正确视图大小的解决方案,因为这真的让我很烦。