You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS 15更新后SwiftUI自定义App Bar内所有元素无法点击如何解决

问题原因

iOS 15 对 SwiftUI 视图的交互区域判定逻辑做了调整,默认只有视图的内容绘制区域会响应点击事件。你的自定义 App Bar 顶部延伸到了状态栏安全区域之外,这部分区域默认不会被判定为可交互范围,同时你将空的 NavigationLink 和按钮放在同一 HStack 层级,也可能存在交互遮挡的问题。

解决方案

按以下步骤修改代码即可修复点击失效问题:

  1. 给承载整个 App Bar 的 VStack 添加 .contentShape(Rectangle()) 修饰符,明确指定整个 VStack 的矩形区域都可响应交互
  2. 调整 NavigationLink 的位置,不要和按钮放在同一布局层级,避免遮挡按钮交互
  3. 替换 iOS 15 已废弃的 Window 获取 API,避免后续版本出现异常
修改后的完整代码
struct appBar: View {
    
    @Binding var index: Int
    @State var showGoalTipsScreen = false
    
    var body: some View {
        // 把NavigationLink移到最外层,避免遮挡按钮
        ZStack {
            NavigationLink("", destination: GoalTipsView().navigationBarHidden(true), isActive: $showGoalTipsScreen)
            
            VStack(spacing: 25) {
                
                HStack {
                    
                    Text("My Goals")
                        .fontWeight(.bold)
                        .font(.title)
                        .foregroundColor(.white)
                    
                    Spacer(minLength: 0)
                    
                    Button(action: {
                        showGoalTipsScreen = true
                    }) {
                        
                        Text("Add New Goal")
                            .foregroundColor(.white)
                        
                        Image("addIcon")
                            .resizable()
                            .frame(width: 18, height: 18)
                            .foregroundColor(.white)
                    }
                }
                
                HStack {
                    
                    Button(action: {
                        self.index = 0
                    }, label: {
                        VStack {
                            Text("Active")
                                .foregroundColor(.white)
                                .fontWeight(self.index == 0 ? .bold : .none)
                            
                            Capsule().fill(self.index == 0 ? Color.white : Color.clear)
                                .frame(height: 4)
                            
                        }
                    })
                    
                    Button(action: {
                        self.index = 1
                    }, label: {
                        VStack {
                            Text("Completed")
                                .foregroundColor(.white)
                                .fontWeight(self.index == 1 ? .bold : .none)
                            
                            Capsule().fill(self.index == 1 ? Color.white : Color.clear)
                                .frame(height: 4)
                            
                        }
                    })
                    
                    
                    Button(action: {
                        self.index = 2
                    }, label: {
                        VStack {
                            Text("Shared")
                                .foregroundColor(.white)
                                .fontWeight(self.index == 2  ? .bold : .none)
                            
                            Capsule().fill(self.index == 2 ? Color.white : Color.clear)
                                .frame(height: 4)
                            
                        }
                    })
                    
                }.padding(.bottom, 10)
                
            }
            .padding(.horizontal)
            // 替换适配iOS15+的安全区域获取方式
            .padding(.top, (UIApplication.shared.connectedScenes
                .filter({$0.activationState == .foregroundActive})
                .compactMap({$0 as? UIWindowScene})
                .first?.windows
                .first(where: \.isKeyWindow)?.safeAreaInsets.top ?? 0) + 10)
            .background(RoundedCorners(tl: 0, tr: 0, bl: 13, br: 13).fill(Color.blue))
            // 核心修改:明确指定整个矩形区域都可响应交互
            .contentShape(Rectangle())
        }
    }
}
修改说明
  • .contentShape(Rectangle()) 会强制 SwiftUI 将整个视图的矩形范围都判定为可交互区域,不管内容有没有绘制到对应位置,直接解决安全区域外部分点击无响应的问题
  • 把 NavigationLink 移到 ZStack 最底层,避免空的导航链接视图占用交互区域,挡住后面按钮的点击事件
  • 新的 Window 获取方式适配了 iOS 15+ 的系统 API 规范,避免后续系统版本升级出现崩溃问题

内容的提问来源于stack exchange,提问作者Filia Salta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 21:54:04