LazyVGrid与Text()在内容为空时会影响间距。

huangapple go评论63阅读模式
英文:

LazyVGrid with Text() affects spacing when content is empty

问题

我是一个完全的新手,对Swift和SwiftUI都不太了解,但我找不到一个直接的答案,所以在这里提问。

我有一个包含ForEachLazyVGrid,它渲染了包含TextRoundedRectangle。网格正确地包装了矩形并在行之间添加了间距。但是,当点击一个矩形时,我会删除其中的Text,当我对一行中的所有项目都这样做时,项目会瞬间移动。

我明白这可能是由于Text内部的某些内部填充/边距等引起的,但在内容视图预览中看不到这些。当然,我可以通过使用一个空的Text来轻松修复它,但这感觉不太对。

有人能解释为什么会发生这种情况以及如何正确修复它的任何想法吗? -- 谢谢

相关代码:

LazyVGrid(columns: [GridItem(.adaptive(minimum: 65))]) {
    ForEach(emojis[0..<emojiCount], id: \.self) { emoji in
        CardView(content: emoji).aspectRatio(3/4, contentMode: .fit)
    }
}

//----

struct CardView: View {
    var content: String
    @State var isFaceUp = true
    var body: some View {
        ZStack {
            let shape = RoundedRectangle(cornerRadius: 20)
            
            if isFaceUp {
                shape.fill().foregroundColor(.white)
                shape.strokeBorder(lineWidth: 3)
                Text(content).font(.largeTitle)
            } else {
                shape.fill()
            }
        }.onTapGesture {
            isFaceUp = !isFaceUp
        }
    }
}
英文:

Total newbie, in Swift and SwiftUI but I couldn't find a straightforward answer hence, asking here.

I have a LazyVGrid that contains a ForEach that renders RoundedRectangle that contains Text. The grid wraps the rectangles correctly and adds the spacing between the rows. However, when tapping on a rectangle, I remove the contained Text and when I do this for all items in a row, the items shift momentarily.

I get that there is some inner padding/margin/etc. going coming from within Text but this is not visible in the content view preview. I can of course, easily fix it by having an empty Text, but this doesn't feel right.

Can someone explain why this is happening and any ideas on how to properly fix it? -- Thanks

related code:

LazyVGrid(columns: [GridItem(.adaptive(minimum: 65))]) {
    ForEach(emojis[0..&lt;emojiCount], id: \.self) { emoji in
        CardView(content: emoji).aspectRatio(3/4, contentMode: .fit)
    }
}

//----

struct CardView: View {
    var content: String
    @State var isFaceUp = true
    var body: some View {
        ZStack {
            let shape = RoundedRectangle(cornerRadius: 20)
            
            if isFaceUp {
                shape.fill().foregroundColor(.white)
                shape.strokeBorder(lineWidth: 3)
                Text(content).font(.largeTitle)
            } else {
                shape.fill()
            }
        }.onTapGesture {
            isFaceUp = !isFaceUp
        }
    }
}

答案1

得分: 1

我不完全确定这里发生了什么,但将 maxHeight 设置为无穷大可以解决问题:

Text(content).font(.largeTitle).frame(maxHeight: .infinity)

ZStack 通常会尝试适应其内容,而 Text 似乎有一些神秘的底部填充,需要 ZStack 扩展。我怀疑这是通过告诉 Text 适应 ZStack 来实现的,而不是反过来。

这个解决方案看起来与这个问题非常相似,其中 Text 由于其框架被挤压以适应内容而导致不必要的填充,而不是容器。

另一个解决方案是使用 overlay

shape.strokeBorder(lineWidth: 3).overlay {
    Text(content).font(.largeTitle)
}

这个方法有效,因为父视图的框架不受其叠加视图的影响,因此叠加视图的存在/不存在不会改变父视图的框架。

英文:

I'm not entirely sure what is happening here either, but setting maxHeight to infinity works:

Text(content).font(.largeTitle).frame(maxHeight: .infinity)

ZStack would normally try to fit its contents, and the Text has some mysterious bottom padding, requiring the ZStack to expand. I suspect that this works by telling the Text to fit the ZStack, rather than the other way round.

The solution looks very similar to this question, where a Text has undesired padding because its frame is squeezed to fit the content, rather than the container.

Another solution is to use an overlay:

shape.strokeBorder(lineWidth: 3).overlay {
    Text(content).font(.largeTitle)
}

This works because the parent view's frame is not affected by its overlays, and so the existence/absence of an overlay does not change the parent view's frame.

huangapple
  • 本文由 发表于 2023年7月3日 13:27:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76602035.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定