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

切换应用后SwiftUI NavigationLink失效,需二次切换才恢复

iOS应用后台切换后NavigationLink失效问题

我正在开发一款iOS平台的充电站应用,为用户提供地图及充电站标记点功能。使用NavigationLink跳转到筛选地图结果的视图,按钮采用自定义样式。但遇到一个异常:切换应用到后台再返回后,该NavigationLink完全无法触发跳转,必须再次切换后台并返回才能恢复正常,且该现象会重复出现。

相关代码(MainView)

import SwiftUI
import MapKit
import CoreLocationUI
import Foundation
import AlertToast

struct MainView: View {    
    @StateObject var locationController = LocationController()
    @StateObject var networkController = NetworkController()
    
    @State public var showingSheet = false
    @State public var dismissSheet = false
    
    @State private var showToast = false
    
    @State public var applyFilters = false
    
    @State public var type1 = false
    @State public var type2 = false
    @State public var csstype1 = false
    @State public var csstype2 = false
    @State public var chademo = false
    @State public var schuko = false
    @State public var tesla = false
    
    @State public var dc = false
    @State public var ac1 = false
    @State public var ac2 = false
    @State public var ac2s = false
    @State public var ac3 = false
    
    @State public var format: Int = 3
    @State public var status: Int = 7
    
    var map: MapView {
        MapView(
            locationController: locationController,
            networkController: networkController,
            showingSheet: $showingSheet,
            dismissSheet: $dismissSheet,
            didSelect: {_ in}
        )
        
    }
    
    var body: some View {
        NavigationView {
            ZStack(alignment: .bottom) {
                map.edgesIgnoringSafeArea(.bottom)
                
                LocationButton(.currentLocation) {
                    print("tapped")
                    locationController.requestAllowOnceLocationPermission()
                }
                .foregroundColor(.white)
                .cornerRadius(8)
                .labelStyle(.iconOnly)
                .tint(Color("LightBlue"))
                .padding(.bottom, 100 )
                .padding(.leading, 330 )
                
                NavigationLink(
                    destination: FiltersView(
                        applyFilters: $applyFilters,  
                        type1: $type1, 
                        type2: $type2,  
                        csstype1: $csstype1, 
                        csstype2: $csstype2, 
                        chademo: $chademo, 
                        schuko: $schuko, 
                        tesla: $tesla, 
                        dc: $dc, 
                        ac1: $ac1, 
                        ac2: $ac2, 
                        ac2s: $ac2s, 
                        ac3: $ac3, 
                        format: $format, 
                        status: $status),
                    label: {
                        ZStack {
                            RoundedRectangle(cornerRadius: 8, style: .circular)
                                .fill(Color("LightBlue"))
                            HStack {
                                SwiftUI.Image("Filters")
                                    .resizable()
                                    .scaledToFit()
                                .padding(10)
                                Text("Φίλτρα")
                                    .foregroundColor(.white)
                                    .font(.system(size: 15, weight: .regular))
                                    .padding(.trailing, 5)
                            }
                        }.frame(minWidth: 100, maxWidth: 110, minHeight: 40, maxHeight: 40)
                    })
                    .padding(.bottom, 660 )
                    .padding(.leading, 250 )
            }
            .background(Color("DeepBlue"))
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    SwiftUI.Image("Logo")
                        .resizable()
                        .scaledToFit()
                        .frame(width: 100, height: 100)
                    
                }
                
            }
            .sheet(item: $networkController.activeLocation, onDismiss: onSheetDismiss) { item in
                BottomSheetView(data: item)
                    .onDisappear() {
                        print("dissapear")
                    }
            }
            .onAppear {
                print("Active View: Main")
                if applyFilters {
                    networkController.applyFilters = .constant(true)
                    NetworkVariables.FilterOptions.type1 = type1
                    NetworkVariables.FilterOptions.type2 = type2
                    NetworkVariables.FilterOptions.csstype1 = csstype1
                    NetworkVariables.FilterOptions.csstype2 = csstype2
                    NetworkVariables.FilterOptions.chademo = chademo
                    NetworkVariables.FilterOptions.schuko = schuko
                    NetworkVariables.FilterOptions.tesla = tesla
                    NetworkVariables.FilterOptions.dc = dc
                    NetworkVariables.FilterOptions.ac1 = ac1
                    NetworkVariables.FilterOptions.ac2 = ac2
                    NetworkVariables.FilterOptions.ac2s = ac2s
                    NetworkVariables.FilterOptions.ac3 = ac3
                    NetworkVariables.FilterOptions.format = format
                    NetworkVariables.FilterOptions.status = status
                    Task {
                        await networkController.getToken()
                        showToast.toggle()
                    }
                    applyFilters = false
                }
            }
        }
        .toast(isPresenting: $showToast){
            AlertToast(type: .regular, title: "Βρέθηκαν \(networkController.mapLocations.count) σημεία")
        }
        
    }
    
    func onSheetDismiss() {
        print("sheet dismissed")
        map.dismissSheet = true
    }
}

解决方案

1. 使用isActive绑定控制导航状态

替换原有的隐式NavigationLink为绑定激活模式,通过状态变量明确控制导航,避免后台切换时的状态丢失:

// 添加状态变量
@State private var isFiltersViewActive = false

// 替换原NavigationLink
NavigationLink(
    destination: FiltersView(
        applyFilters: $applyFilters,  
        type1: $type1, 
        type2: $type2,  
        csstype1: $csstype1, 
        csstype2: $csstype2, 
        chademo: $chademo, 
        schuko: $schuko, 
        tesla: $tesla, 
        dc: $dc, 
        ac1: $ac1, 
        ac2: $ac2, 
        ac2s: $ac2s, 
        ac3: $ac3, 
        format: $format, 
        status: $status
    ),
    isActive: $isFiltersViewActive,
    label: {
        ZStack {
            RoundedRectangle(cornerRadius: 8, style: .circular)
                .fill(Color("LightBlue"))
            HStack {
                SwiftUI.Image("Filters")
                    .resizable()
                    .scaledToFit()
                .padding(10)
                Text("Φίλτρα")
                    .foregroundColor(.white)
                    .font(.system(size: 15, weight: .regular))
                    .padding(.trailing, 5)
            }
        }.frame(minWidth: 100, maxWidth: 110, minHeight: 40, maxHeight: 40)
    }
)
.padding(.bottom, 660 )
.padding(.leading, 250 )

2. 修复点击区域与层级问题

  • 给自定义按钮添加contentShape确保完整点击区域:
ZStack { /* 原按钮内容 */ }
.frame(minWidth: 100, maxWidth: 110, minHeight: 40, maxHeight: 40)
.contentShape(Rectangle()) // 确保按钮整体可点击
  • 给NavigationLink添加zIndex,确保它在地图视图上层:
NavigationLink(...)
.padding(...)
.zIndex(1)

3. 修正onAppear中的状态修改方式

原代码中直接替换Binding的操作会破坏SwiftUI的响应链,改为使用@Published变量:

// 在NetworkController中修改
class NetworkController: ObservableObject {
    @Published var applyFilters = false
    // ...其他原有代码
}

// 在MainView的onAppear中修改
.onAppear {
    print("Active View: Main")
    if applyFilters {
        networkController.applyFilters = true // 不再使用.constant(true)
        // ...其他筛选参数赋值代码
        Task {
            await networkController.getToken()
            showToast.toggle()
        }
        applyFilters = false
    }
}

4. 检查地图视图的交互状态

确保地图视图在后台恢复后不会拦截点击事件,可显式设置:

map.edgesIgnoringSafeArea(.bottom)
.allowsHitTesting(true)

内容的提问来源于stack exchange,提问作者George Karageorgiou

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:45:31