SwiftUI ZStack 对齐错误

Posted

技术标签:

【中文标题】SwiftUI ZStack 对齐错误【英文标题】:SwiftUI ZStack alignment bug 【发布时间】:2020-06-01 06:12:09 【问题描述】:

这是一个简单的代码,它会在 ZStack 中生成奇怪的顶部对齐和缩小的第二个元素的文本。

但是,如果您稍微更改第二个文本(将 text2 替换为 text2Alt1text2Alt2)使其更长或更短,一切都会变得正确。

这种行为的原因是什么?

struct VCardView: View 
    let text: String
    let color: UIColor
    
    var body: some View 
        VStack 
            Rectangle()
                .fill(Color(self.color))
                .frame(idealWidth: 800, idealHeight: 500)
                .aspectRatio(contentMode: .fit)

            Text(self.text)
        
    


struct ContentView: View 
    var body: some View 
        ZStack(alignment: .topLeading) 
            VCardView(text: text1, color: .blue)
                .frame(width: 180, height: nil)
                .alignmentGuide(.leading)  _ in 180 
                .alignmentGuide(.top)  _ in 0 
            
            //Replace text2 by text2Alt1 or text2Alt2 here:
            VCardView(text: text2, color: .green)
                .frame(width: 180, height: nil)
                .alignmentGuide(.leading)  _ in 0 
                .alignmentGuide(.top)  _ in 0 
        
    
    
    let text1 = "1Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidu!"
    
    let text2 = "2Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis nat!"
    
    
    let text2Alt1 = "2Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. C"
    
    let text2Alt2 = "2Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis nat! Cum sociis nat!"


此外,您可以将Rectangle() 替换为具有适当比例的Image(),因为它是初始状态。理想尺寸的Rectangle 仅用于演示。

这里我使用带有显式对齐指南(不是 HStack)的 ZStack,因为它是另一个库的一部分。这是必不可少的。

XCode 11.5 ios 13.5 iPhone SE 2020

Bug 看起来像这样:

预期布局:

【问题讨论】:

【参考方案1】:

我经常在 SwiftUI 中看到这样的Text 截断问题。大多数时候有帮助的解决方法:确保允许Text 使用minimumScaleFactor 修饰符自动调整其字体大小。

通过修改VCardView

Text(self.text)
    .minimumScaleFactor(0.5)

所有可能的文本值(text1text2text2Alt1text2Alt2)的错位问题都消失了。

生成的文本看起来根本没有缩放。一切都很好。 我没有很好的解释,但我认为如果你告诉 SwiftUI 你的 Text 不是 100% 刚性/僵硬,它在计算元素范围时表现更好。

也许这是一个 SwiftUI 错误,但我对这个 minimumScaleFactor 解决方法总是没问题,因为它没有对我的结果产生负面影响。

【讨论】:

【参考方案2】:

这看起来不像是ZStack 问题。尝试从Rectangle() 中的VCardView 中删除.aspectRatio(contentMode: .fit)

对于矩形比例检查类似this。

【讨论】:

这个想法是根据Rectange() 视图的固有大小保存比例并适合父视图(受.frame(width: 180, height: nil) 限制)。例如,将Rectangle() 替换为Image() 并删除frame(idealWidth: idealHeight:)。结果是一样的,GeometryReader 无法帮助您读取图像的固有尺寸。

以上是关于SwiftUI ZStack 对齐错误的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 设置状态栏背景颜色以与导航栏对齐

在 ForEach/ZStack (SwiftUI) 中将表达式分解为不同的子表达式

SwiftUI:更改 ZStack .zIndex 顺序

SwiftUI,ScrollView 在 ZStack 中向上推送 VStack 图像

放入ZStack时swiftui列表不起作用

SwiftUI动画视图出现在ZStack中时出现奇怪的过渡