SwiftUI:Sheet关闭后导航栏按钮帧错位且点击异常
SwiftUI:关闭Sheet后导航栏按钮点击区域错位问题
问题描述
关闭Sheet后,导航栏按钮的点击区域与可视区域错位,无法正常点击按钮。
复现步骤
- 弹出Sheet弹窗
- 将App切换至后台并停留约2秒
- 恢复App后向下滑动关闭Sheet
该问题在iOS 16模拟器上极易复现,真实iOS设备上偶发。
复现代码
struct ContentView: View { @State private var showSheetView = false var body: some View { NavigationView { VStack { navigationBarView Color.blue } .sheet(isPresented: $showSheetView) { FilterView() } .navigationBarHidden(true) } .navigationViewStyle(.stack) } private var navigationBarView: some View { HStack(spacing: 0) { Spacer() Button { showSheetView = true } label: { Text("Filter") .padding() .background(Color.red) } } } } struct FilterView: View { var body: some View { Color.green } }
解决方案
方案1:使用iOS 16+推荐的NavigationStack替代NavigationView
NavigationView在iOS 16存在部分布局兼容问题,换成官方推荐的NavigationStack可直接规避该bug:
struct ContentView: View { @State private var showSheetView = false var body: some View { // 替换为NavigationStack NavigationStack { VStack { navigationBarView Color.blue } .sheet(isPresented: $showSheetView) { FilterView() } .navigationBarHidden(true) } } private var navigationBarView: some View { HStack(spacing: 0) { Spacer() Button { showSheetView = true } label: { Text("Filter") .padding() .background(Color.red) } } } }
方案2:强制刷新自定义导航栏视图
通过给自定义导航栏添加id绑定Sheet的展示状态,当Sheet关闭时强制视图刷新,重新计算点击区域:
private var navigationBarView: some View { HStack(spacing: 0) { Spacer() Button { showSheetView = true } label: { Text("Filter") .padding() .background(Color.red) } } // Sheet状态变化时强制刷新视图 .id(showSheetView) }
方案3:使用官方导航栏组件替代自定义导航栏
如果允许使用系统默认导航栏样式,直接通过navigationBarItems添加按钮,避免自定义导航栏的布局计算问题:
struct ContentView: View { @State private var showSheetView = false var body: some View { NavigationView { Color.blue .sheet(isPresented: $showSheetView) { FilterView() } .navigationBarTitleDisplayMode(.inline) .navigationBarItems(trailing: Button { showSheetView = true } label: { Text("Filter") .padding() .background(Color.red) }) } .navigationViewStyle(.stack) } }
内容的提问来源于stack exchange,提问作者Mohammed Shakeer
相关产品推荐
相关产品推荐

