【问题标题】:SwiftUI: how to make a view fit into a certain sizeSwiftUI:如何使视图适合特定大小
【发布时间】:2021-11-09 04:05:45
【问题描述】:

所以基本上我的应用程序中有这个视图。

我希望名为 LaMarcus Aldridge 的框与其他框大小相同 基本上我想通过减少图片和文本行之间的空间量来减小框的大小,以便所有框的大小相同。我最初考虑通过计算所需空间来进行数学运算,但我很确定有更好的方法来做到这一点,而我只是没有想到。谢谢你,我真的很感激。

这是声明这些框的代码。

var body: some View {
        VStack(spacing: 15) { //first
            Image(uiImage: question.players[0].picture)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(height: 140)
//                .padding(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
            
            Text(question.players[0].name)
                .font(.title2)
                .fontWeight(.heavy)
                .foregroundColor(.black)
                .multilineTextAlignment(.center)
                .lineLimit(2)
            
            Text(question.players[0].team)
                .foregroundColor(.black)
                .multilineTextAlignment(.center)
        }
        .padding()
        .frame(maxWidth: .infinity)
        .onTapGesture(perform: {
            selectedAnswer = question.players[0]
        })
        
        .background(
            RoundedRectangle(cornerRadius: 15)
                .stroke(color(option: question.players[0]), lineWidth: 5)
        )
        .cornerRadius(15)
        
        VStack(spacing: 15) { //second
            Image(uiImage: question.players[1].picture)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(height: 140)
            Text(question.players[1].name)
                .font(.title2)
                .fontWeight(.heavy)
                .foregroundColor(.black)
                .multilineTextAlignment(.center)
                .lineLimit(2)
            
            Text(question.players[1].team)
                .foregroundColor(.black)
                .multilineTextAlignment(.center)
        }
        
        .padding()
        .frame(maxWidth: .infinity)
        .onTapGesture(perform: {
            selectedAnswer = question.players[1]
        })
        .background(
            RoundedRectangle(cornerRadius: 15)
                .stroke(color(option: question.players[1]), lineWidth: 5)
        )
        .cornerRadius(15)
        
        VStack(spacing: 15) { //third
            Image(uiImage: question.players[2].picture)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(height: 140)
            Text(question.players[2].name)
                .font(.title2)
                .fontWeight(.heavy)
                .foregroundColor(.black)
                .multilineTextAlignment(.center)
                .lineLimit(2)
            
            Text(question.players[2].team)
                .foregroundColor(.black)
                .multilineTextAlignment(.center)
        }
        
        .padding()
        .frame(maxWidth: .infinity)
        .onTapGesture(perform: {
            selectedAnswer = question.players[2]
        })
        .background(
            RoundedRectangle(cornerRadius: 15)
                .stroke(color(option: question.players[2]), lineWidth: 5)
        )
        .cornerRadius(15)
        
        VStack(spacing: 15) { //fourth
            Image(uiImage: question.players[3].picture)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(height: 140)
            Text(question.players[3].name)
                .font(.title2)
                .fontWeight(.heavy)
                .foregroundColor(.black)
                .multilineTextAlignment(.center)
                .lineLimit(2)
            
            Text(question.players[3].team)
                .foregroundColor(.black)
                .multilineTextAlignment(.center)
        }
        
        .padding()
        .frame(maxWidth: .infinity)
        .onTapGesture(perform: {
            selectedAnswer = question.players[3]
        })
        .background(
            RoundedRectangle(cornerRadius: 15)
                .stroke(color(option: question.players[3]), lineWidth: 5)
        )
        .cornerRadius(15)
    }

【问题讨论】:

  • 如果你使用的是 iOS 14+,也许可以看看 LazyVStack
  • 你的问题是错误的!您应该将图像和文本限制并修复到一定大小,然后所有具有相同功能的视图都将适合
  • 尝试网格系统,var gridLayout = [GridItem(.fixed(180)),GridItem(.fixed(180))] 将 VStacks 包装成类似:LazyVGrid(columns: gridLayout, spacing: 10) {..VStacks..} 并将每个 VStack 的 .frame(maxWidth: .infinity) 替换为 .frame(maxWidth: .infinity, idealHeight: 280)

标签: swift swiftui frontend spacing


【解决方案1】:

尝试在 VStack 中使用条件。 我创建了一个自定义卡片视图,您可以在内容视图中使用它,使用 LazyVGrid + ForEach 或简单地使用 HStack 和 VStack。

struct CardView: View{
var playerName: String
var playerTeam: String
var playerPortrait: UIImage
var body: some 
View{
 
//Control amount of spacing depend on amount of character in player's name
VStack(spacing: playerName.count  > 13 ? -12 : 0) { //first
    Image(uiImage: playerPortrait)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(height:160)
                .padding(10)
            
            Text(playerName)
                .foregroundColor(.black)
                .multilineTextAlignment(.center)
                .lineLimit(2)
                .padding(5)
            
            Text(playerTeam)
                .foregroundColor(.black)
                .multilineTextAlignment(.center)
                .padding(5)
}.background(RoundedRectangle(cornerRadius: 15).stroke()).padding(5)
}
}

【讨论】:

    猜你喜欢
    • 2021-06-22
    • 1970-01-01
    • 2012-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 2013-11-22
    • 2021-11-08
    相关资源
    最近更新 更多