SwiftUI iOS 26 - 菜单按钮在选择动画期间从容器外部浮出

移动开发 2026-07-12

都不知道该怎么解释这件事……

在iOS 26上,在一个包含Menu的可滚动视图中,如果在菜单选择动画尚未完成时开始滚动视图(大约在点击选项后约1 秒内),菜单图标会暂时错位:它相对于容器发生位置偏移,仿佛从布局边界之外“漂浮”出来。动画完成或滚动停止后,它会回到原位,但在交互过程中,该按钮明显与容器/对齐方式脱离。

这不是预期的行为,对吧?
这在我的项目中的每个菜单上都会发生,甚至在工作表工具栏中的菜单也会这样,当在选中后拖动工作表时,同样的问题也会出现。我附上了一些不同情形的动图。

在 SwiftUI 应用中的复现

在 SwiftUI 应用中的复现
测试用样例:

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()
}

解决方案

如果把 MenuGlassEffectContainer 包裹起来,并将 .glassEffect(.identity) 应用于标签,会有更好的效果:

GlassEffectContainer { // 👈 added
    Menu {
        // ...
    } label: {
        Image(systemName: "ellipsis.circle")
            .imageScale(.large)
            .padding(8)
            .glassEffect(.identity) // 👈 added
    }
    .menuStyle(.button)
    .buttonStyle(.plain)
    .accessibilityLabel("More options")
}

动画

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章