You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS 16 SwiftUI Menu按钮在选择动画期间滚动/拖拽时错位浮离容器问题

iOS 16 SwiftUI Menu按钮在选择动画期间滚动/拖拽时错位浮离容器问题

我最近碰到了一个特别费解的SwiftUI布局问题,在iOS 16上只要满足特定操作就会触发:

在包含Menu组件的可滚动视图中,如果我在点击菜单选项后的动画完成前(大概1秒内)就开始滚动视图,Menu的图标会临时错位——它会相对于所在容器偏移,看起来像是“飘”出了布局边界。等动画结束或者滚动停止后,它又会弹回正确位置,但交互过程中这个按钮明显和容器的对齐方式脱节了,视觉上特别突兀。

这绝对不是正常的预期行为吧?更糟的是,我项目里所有的Menu都存在这个问题,就连Sheet工具栏里的Menu,只要在选择选项后拖拽Sheet,同样的错位问题也会出现。我附了两个不同场景的动图来复现这个问题:

菜单图标错位复现场景1
菜单图标错位复现场景2

下面是可以直接测试的示例代码:

测试用示例代码

import SwiftUI

struct ContentView: View {
    private let items = (1...30).map { "Item \($0)" }

    var body: some View {
        NavigationStack {
            ScrollView {
                LazyVStack(alignment: .leading, spacing: 12, pinnedViews: []) {
                    HStack {
                        Text("Scrollable header")
                            .font(.headline)

                        Spacer()

                        Menu {
                            Button("Option 1") {
                                // handle option 1
                            }
                            Button("Option 2") {
                                // handle option 2
                            }
                        } label: {
                            Image(systemName: "ellipsis.circle")
                                .imageScale(.large)
                                .padding(8)
                        }
                        .menuStyle(.button)
                        .buttonStyle(.plain)
                        .accessibilityLabel("More options")
                    }
                    .padding(.horizontal)
                    .padding(.top, 8)

                    ForEach(items, id: \.self) { item in
                        Text(item)
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .padding(.horizontal)
                            .padding(.vertical, 12)
                            .background(.background)
                            .overlay(alignment: .bottom) {
                                Divider()
                            }
                    }
                }
            }
            .navigationTitle("Items")
            .background(Color(.systemGroupedBackground))
        }
    }
}

#Preview {
    ContentView()
}

备注:内容来源于stack exchange,提问作者Vitor

火山引擎 最新活动