我如何在SwiftUI中将这些图像以直线方式居中放置在我的HStack中

ukxgm1gy  于 2023-10-15  发布在  Swift
关注(0)|答案(3)|浏览(88)

我有一个HStack嵌套在一个VStack里面的一个ScrollView,我试图在一条直线中心的中间照片。正如您在照片中看到的,图片根据左侧文本标签的大小进行偏移。(单词越长,图像向右偏移的越多)。我想让图像集中在HStack的中间,在某种程度上,它们都完美地排列在彼此的顶部。
HStack的格式应该是(标签-图像-标签),我希望这两个标签是在最左边/右边的图像接触屏幕的两侧。
我目前使用两个Spacer()来完成这项工作,但它会产生偏移。
以下是它现在的样子(未对齐):

下面是我的视图的代码,它保存了scrollview和vstack:

ScrollView(.vertical){
                VStack(alignment: .center, spacing: 5){
                    ForEach(weatherViewModel.dailyDataArray){
                        DailyCell(dailyData: $0)
                            .background(Color.clear)
                            .padding(10)
                    }
                }
            }

这是我的CellView的代码

struct DailyCell: View {
    
    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))
            }
        }
    }
}
nszi6y05

nszi6y051#

另一个非常简单的解决方案是使用ZStack并将图像集中在自己的HStack中。这将始终将图像定位在视图的中心。

let dailyData: DailyData
    
    var body: some View {
        ZStack {
            HStack(alignment: .center){
                Text(dailyData.time)
                    .fontWeight(.semibold)
                    .foregroundColor(Color(UIColor.white))
                    .font(.system(size: 16))
                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))
                }
            }
            HStack {
                Spacer()
                Image(dailyData.icon)
                    .resizable()
                    .scaledToFit()
                    .frame(width: 25, height: 25, alignment: .center)
                    .multilineTextAlignment(.leading)
                Spacer()
            }
        }
    }

试试看!

kkbh8khc

kkbh8khc2#

将所有内容 Package 在geometryreader中并为textviews分配相对宽度应该可以做到这一点:

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
        }
    }
}
kb5ga3dv

kb5ga3dv3#

一种可能性是使用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: $0)
                        .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))
        }
    }

注意:我删除了白色前景,因为我的背景是白色

相关问题