iOS笔记App风格菜单实现异常:点击按钮后菜单无法展开
解决方案
问题出在你直接在交互回调中同步修改FocusState,导致视图立即重绘打断了菜单的展开流程。可以通过以下两种方式解决:
方法一:异步延迟状态更新(兼容iOS13+)
将设置isEditing = false的操作放到异步队列中,让菜单先完成展开逻辑,再触发工具栏的更新:
@FocusState private var isEditing: Bool var body: some View { AnnotatedTextEditor(text: $text) .focused($isEditing) .toolbar { ToolbarItemGroup(placement: .navigationBarTrailing) { Menu { Button(role: .destructive, action: delete) { Label("Delete", systemImage: "trash") } } label: { Label("Menu", systemImage: "ellipsis.circle") } .onTapGesture { DispatchQueue.main.async { isEditing = false } } if isEditing { Button("Done", action: done) } } } }
方法二:利用Menu的onPresented回调(iOS16+)
如果你的App适配iOS16及以上版本,使用onPresented修饰符更合适——它会在菜单实际展开时触发回调,此时修改状态不会打断菜单展示:
@FocusState private var isEditing: Bool var body: some View { AnnotatedTextEditor(text: $text) .focused($isEditing) .toolbar { ToolbarItemGroup(placement: .navigationBarTrailing) { Menu { Button(role: .destructive, action: delete) { Label("Delete", systemImage: "trash") } } label: { Label("Menu", systemImage: "ellipsis.circle") } .onPresented { isEditing = false } if isEditing { Button("Done", action: done) } } } }
原理说明
直接同步修改FocusState会立即触发工具栏的重绘,SwiftUI会重新渲染ToolbarItemGroup,导致菜单的展开逻辑被中断。通过异步延迟或使用菜单专属的回调,能确保菜单先完成展开,再执行隐藏Done按钮的状态更新,两者互不干扰。
内容的提问来源于stack exchange,提问作者abegehr
相关产品推荐
相关产品推荐

