如何在 SwiftUI 的 HStack 中将这些图像以直线居中
How do I center these images in a straight line inside my HStack in SwiftUI
所以我在 ScrollView 内的 VStack 内嵌套了一个 HStack,我试图将中间的照片居中放置在一条直线上。正如您在照片中看到的那样,图片根据文本标签的大小向左偏移。 (单词越长,图像向右偏移越多)。我想让图像在 HStack 的中间居中,使它们彼此完美对齐。
HStack 的格式应该是(标签 - 图像 - 标签),我希望这两个标签位于触摸屏幕两侧的图像的远端 left/right。
我目前正在使用两个 Spacer() 来完成这项工作,但它会产生偏移量。
Here is what it looks like right now (unaligned)
这是我的视图代码,它包含滚动视图和 vstack:
ScrollView(.vertical){
VStack(alignment: .center, spacing: 5){
ForEach(weatherViewModel.dailyDataArray){
DailyCell(dailyData: [=10=])
.background(Color.clear)
.padding(10)
}
}
}
这是我的 CellView 的代码
结构 DailyCell:查看 {
let dailyData: DailyData
var body: some View {
HStack(alignment: .center){
Text(dailyData.time)
.fontWeight(.semibold)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
Spacer()
Image(dailyData.icon)
.resizable()
.scaledToFit()
.frame(width: 25, height: 25, alignment: .center)
.multilineTextAlignment(.leading)
Spacer()
HStack(spacing: 10){
Text(dailyData.lowtemp + "°")
.fontWeight(.regular)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
Text(dailyData.hightemp + "°")
.fontWeight(.regular)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
}
}
}
}
将所有内容包装在 geometryreader 中并为文本视图分配相对宽度应该可以解决问题:
var body: some View {
//decide which image to show
GeometryReader{ readerProxy in <- add this
HStack(alignment: .center){
Text(dailyData.time)
.fontWeight(.semibold)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
.frame(width: readerProxy.size.width / 3, alignment: .left) <- add this
Spacer()
Image(dailyData.icon)
.resizable()
.scaledToFit()
.frame(width: 25, height: 25, alignment: .center)
.multilineTextAlignment(.leading)
Spacer()
HStack(spacing: 10){
Text(dailyData.lowtemp + "°")
.fontWeight(.regular)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
Text(dailyData.hightemp + "°")
.fontWeight(.regular)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
}
.frame(width: readerProxy.size.width / 3, alignment: .right) <- add this
}
}
}
一种可能是使用 LazyVGrid :
struct HStackCenterCell: View {
var weatherViewModel = WeatherViewModel();
let columns: [GridItem] = Array(repeating: .init(.flexible()), count: 3) // 3 columns LazyVGrid
var body: some View {
ScrollView(.vertical){
// Lazy grid to have columns
LazyVGrid(columns: columns) {
ForEach(weatherViewModel.dailyDataArray){
DailyCell(dailyData: [=10=])
.background(Color.clear)
.padding(10)
}
}
}
}
}
struct DailyCell: View {
let dailyData: DailyData
var body: some View {
// need to suppress global HStack and Spacers
HStack { // HStack to align day on left
Text(dailyData.time)
.fontWeight(.semibold)
.font(.system(size: 16)).multilineTextAlignment(.leading)
Spacer()
}
// For my tests i used SF symbols
Image(systemName: dailyData.icon)
.resizable()
.scaledToFit()
.frame(width: 25, height: 25, alignment: .center)
.multilineTextAlignment(.leading)
HStack(spacing: 10)
{
Text(dailyData.lowtemp + "°")
.fontWeight(.regular)
.font(.system(size: 16))
Text(dailyData.hightemp + "°")
.fontWeight(.regular)
.font(.system(size: 16))
}
}
注意:我删除了白色前景,因为我的背景是白色的
所以我在 ScrollView 内的 VStack 内嵌套了一个 HStack,我试图将中间的照片居中放置在一条直线上。正如您在照片中看到的那样,图片根据文本标签的大小向左偏移。 (单词越长,图像向右偏移越多)。我想让图像在 HStack 的中间居中,使它们彼此完美对齐。
HStack 的格式应该是(标签 - 图像 - 标签),我希望这两个标签位于触摸屏幕两侧的图像的远端 left/right。
我目前正在使用两个 Spacer() 来完成这项工作,但它会产生偏移量。
Here is what it looks like right now (unaligned)
这是我的视图代码,它包含滚动视图和 vstack:
ScrollView(.vertical){
VStack(alignment: .center, spacing: 5){
ForEach(weatherViewModel.dailyDataArray){
DailyCell(dailyData: [=10=])
.background(Color.clear)
.padding(10)
}
}
}
这是我的 CellView 的代码 结构 DailyCell:查看 {
let dailyData: DailyData
var body: some View {
HStack(alignment: .center){
Text(dailyData.time)
.fontWeight(.semibold)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
Spacer()
Image(dailyData.icon)
.resizable()
.scaledToFit()
.frame(width: 25, height: 25, alignment: .center)
.multilineTextAlignment(.leading)
Spacer()
HStack(spacing: 10){
Text(dailyData.lowtemp + "°")
.fontWeight(.regular)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
Text(dailyData.hightemp + "°")
.fontWeight(.regular)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
}
}
}
}
将所有内容包装在 geometryreader 中并为文本视图分配相对宽度应该可以解决问题:
var body: some View {
//decide which image to show
GeometryReader{ readerProxy in <- add this
HStack(alignment: .center){
Text(dailyData.time)
.fontWeight(.semibold)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
.frame(width: readerProxy.size.width / 3, alignment: .left) <- add this
Spacer()
Image(dailyData.icon)
.resizable()
.scaledToFit()
.frame(width: 25, height: 25, alignment: .center)
.multilineTextAlignment(.leading)
Spacer()
HStack(spacing: 10){
Text(dailyData.lowtemp + "°")
.fontWeight(.regular)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
Text(dailyData.hightemp + "°")
.fontWeight(.regular)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
}
.frame(width: readerProxy.size.width / 3, alignment: .right) <- add this
}
}
}
一种可能是使用 LazyVGrid :
struct HStackCenterCell: View {
var weatherViewModel = WeatherViewModel();
let columns: [GridItem] = Array(repeating: .init(.flexible()), count: 3) // 3 columns LazyVGrid
var body: some View {
ScrollView(.vertical){
// Lazy grid to have columns
LazyVGrid(columns: columns) {
ForEach(weatherViewModel.dailyDataArray){
DailyCell(dailyData: [=10=])
.background(Color.clear)
.padding(10)
}
}
}
}
}
struct DailyCell: View {
let dailyData: DailyData
var body: some View {
// need to suppress global HStack and Spacers
HStack { // HStack to align day on left
Text(dailyData.time)
.fontWeight(.semibold)
.font(.system(size: 16)).multilineTextAlignment(.leading)
Spacer()
}
// For my tests i used SF symbols
Image(systemName: dailyData.icon)
.resizable()
.scaledToFit()
.frame(width: 25, height: 25, alignment: .center)
.multilineTextAlignment(.leading)
HStack(spacing: 10)
{
Text(dailyData.lowtemp + "°")
.fontWeight(.regular)
.font(.system(size: 16))
Text(dailyData.hightemp + "°")
.fontWeight(.regular)
.font(.system(size: 16))
}
}
注意:我删除了白色前景,因为我的背景是白色的