ios 如何在SwitUI中填充minHeight或minWidth

rseugnpd  于 2023-07-01  发布在  iOS
关注(0)|答案(3)|浏览(114)

假设我有以下布局:

VStack {
  Text(title)
    .frame(maxWidth: .infinity, alignment: .leading)

  Spacer()

  Divider()
    .frame(height: 1)
}
.frame(minHeight: 80, alignment: .bottom)

我希望文本字段可以自由扩展,分隔符要对齐到底部,整个事情至少有80点高(但如果没有必要,不要更高)。如果我离开它这样的间隔将采取所有的父母的高度(超过80)。如果我没有一个间隔,两个子视图将一起对齐到顶部,底部或中心。
如何实现所需的垫片性能?或者布局应该有不同的结构?

a7qyws3x

a7qyws3x1#

您可以使用PreferenceKey创建任何视图并观察其内容的高度/宽度。根据您的请求,您可能会使用不同的条件,例如在我的代码中- viewHeight:

struct ContentView: View {
    var title = "TitleTitleTitleTitle"
    @State private var textHeight: CGFloat = 0
    var viewHeight: CGFloat {
        if textHeight < 80 {
            return 80
        } else {
            return textHeight
        }
    }
    var body: some View {
        VStack {
            Text(title)
                .fixedSize(horizontal: false, vertical: true)
                .frame(alignment: .leading)
                .background(
                    GeometryReader { geometry in
                        Color.clear
                            .preference(
                                key: TextHeightKey.self,
                                value: geometry.size.height
                            )
                    }
                )
            
            Spacer()
            
            Divider()
                .frame(height: 1)
        }
        .frame(height: viewHeight, alignment: .bottom)
        .onPreferenceChange(TextHeightKey.self) { height in
            textHeight = height
        }
    }
}

struct TextHeightKey: PreferenceKey {
    static var defaultValue: CGFloat = 0
    
    static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
        value = max(value, nextValue())
    }
}
hujrc8aj

hujrc8aj2#

如果我没理解错的话,你需要80或更高的高度,对吗?
既然它取决于文本,为什么不把最小高度赋给Text本身,而去掉Spacer呢?

VStack(alignment: .leading) {
    Text(title) // 👈 This is the content and can be a container of any views
        .frame(minHeight: 80)
        .lineLimit(0)

    Divider()
}
u59ebvdq

u59ebvdq3#

我已经想出了一个更简单的解决方案,如果我使用ZStack而不是像这样的spacer:

ZStack(alignment: .bottom) {
  VStack(alignment: .leading) {
    Text(title)
      .frame(maxWidth: .infinity, alignment: .leading)

    Text(description)
      .frame(maxWidth: .infinity, alignment: .leading)
  }.frame(minHeight: 80)

  Divider()
    .frame(height: 1)
}

然后,如果我想确保ZStack中的第一个视图不与第二个视图重叠,我可以使用Anton Agafonov提出的解决方案,并在VStack中插入一个spacer,其高度基于ZStack的第二个子视图计算。

相关问题