SwiftUI菜单破坏布局

3
这个 SwiftUI 应用程序(Xcode 12.5.1)由一个 Menu 和一个按钮组成。点击按钮可以在“短文本”和“更长的文本”之间切换菜单标题。
不幸的是,布局不能正确地显示。正如你所看到的,“更长的文本”被不必要地截断了。但一旦菜单标题被点击并且菜单短暂出现,标题就会增长到其正确的(未截断)大小,问题就消失了:

enter image description here

这是代码:
struct ContentView: View {
    @State private var textIsLong = false

    var body: some View {
        VStack {
            Menu {
                Text("Menu Item")
            } label: {
                Text(textIsLong ? "Much Longer Text" : "Short Text")
            }
            .font(.system(size: 30))
            .foregroundColor(Color(UIColor.label))
            .lineLimit(1)

            Button("Toggle Title", action: { textIsLong.toggle()})
        }
    }
}

相比之下,用 Text(textIsLong ? "Much Longer Text" : "Short Text") 替换菜单可以消除问题;文本永远不会被截断。
这只是 SwiftUI 布局的一个 bug 吗?无论如何,你能想到解决方法吗?
1个回答

6
你可以通过将 Menu 标签中的 Text.frame() 设置为以下内容来解决截断和布局问题。
Menu {
    Text("Menu Item")
} label: {
    Text(textIsLong ? "Much Longer Text" : "Short Text")
        .frame(maxWidth: .infinity)  // making maxWidth infinity 
}

1
你也可以很可能去掉minWidth: 0 - .frame(maxWidth: .infinity)通常已经足够了。 - aheze
哦,是的,让我很快地纠正一下。习惯使然。 - Visal Rajapakse
谢谢!你有没有想法为什么根据布局规则需要进行修复?在我看来,这似乎不应该是必要的,并且无论菜单是否被调用过,当菜单本身不可见时,菜单标题的大小都应该是无关紧要的。 - Anton
我假设你没有明确给出一个框架,并且由于SwiftUI是声明式的,它试图更新框架导致布局中断。当你将框架设置为.infinity时,它被强制跨越屏幕的最大宽度。因此,不留任何空间进行框架更新。 - Visal Rajapakse
这真的是一个错误。在这里,布局或渲染模型中没有任何部分是有意义的。 - mattsven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接