带有 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
字体的文本,结果如下所示,可能导致与相邻视图重叠:
我仍将进一步调查以找到确保正确视图大小的解决方案,因为这真的让我很烦。
我有这个简单的 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
字体的文本,结果如下所示,可能导致与相邻视图重叠:
我仍将进一步调查以找到确保正确视图大小的解决方案,因为这真的让我很烦。