iOS13兼容SwiftUI自定义返回按钮:支持返回多页面实现
SwiftUI 自定义返回按钮(兼容iOS13+,支持返回指定页面数)
核心解决思路
由于iOS13不支持@Environment(\.dismiss),我们直接借助UIKit的UINavigationController管理页面栈,实现自定义返回逻辑——包括返回上一页、返回指定层级页面等需求。
步骤1:创建导航栈管理工具类
这个类负责获取顶层导航控制器,并封装各类返回操作:
import UIKit class NavigationManager { // 返回上一页 static func popToPreviousPage() { guard let navController = UIApplication.shared.topNavigationController else { return } navController.popViewController(animated: true) } // 返回指定索引的页面(索引从0开始,0为根页面) static func popToPage(at index: Int) { guard let navController = UIApplication.shared.topNavigationController, navController.viewControllers.count > index else { return } let targetVC = navController.viewControllers[index] navController.popToViewController(targetVC, animated: true) } // 返回指定层级数(比如传2就是回退2页) static func popBack(_ count: Int) { guard let navController = UIApplication.shared.topNavigationController else { return } let targetIndex = max(0, navController.viewControllers.count - 1 - count) popToPage(at: targetIndex) } // 可选:直接返回根页面 static func popToRoot() { guard let navController = UIApplication.shared.topNavigationController else { return } navController.popToRootViewController(animated: true) } } // 扩展UIApplication,方便获取顶层导航控制器 extension UIApplication { var topNavigationController: UINavigationController? { let keyWindow = connectedScenes .filter({$0.activationState == .foregroundActive}) .map({$0 as? UIWindowScene}) .compactMap({$0}) .first?.windows .filter({$0.isKeyWindow}).first return keyWindow?.rootViewController as? UINavigationController ?? keyWindow?.rootViewController?.presentedViewController as? UINavigationController } }
步骤2:修改现有页面的返回逻辑
在KnowMoreView中,给自定义返回按钮绑定对应的返回方法即可:
struct KnowMoreView: View { // MARK: - PROPERTY // MARK: - BODY var body: some View { ZStack { Color.white .edgesIgnoringSafeArea(.top) Color(UIColor.ray239) .edgesIgnoringSafeArea(.bottom) VStack { // 示例1:默认返回上一页 LabeledHeaderView(label: "know_more_about_us".localized, showBackButton: true) { NavigationManager.popToPreviousPage() } // 示例2:回退2个页面 // LabeledHeaderView(label: "know_more_about_us".localized, showBackButton: true) { // NavigationManager.popBack(2) // } // 示例3:直接返回根页面 // LabeledHeaderView(label: "know_more_about_us".localized, showBackButton: true) { // NavigationManager.popToRoot() // } Divider() .frame(height: 2) .overlay(Color("gray151")) .padding(.top, -10) Image("knowMore") .resizable() .scaledToFit() .padding(.horizontal, 16) .padding(.top, 12) .cornerRadius(24) Text("explore_my_fund".localized.uppercased()) .foregroundColor(Color("gray143")) .font(.custom(Fonts.GothamMedium.rawValue, size: 24)) .padding(.top, 12) HStack { Spacer() SquareButton(label: "who_we_are".localized, image: "whoWeAre", action: {}) Spacer() SquareButton(label: "faqs".localized, image: "faqs", action: {}) Spacer() SquareButton(label: "our_products".localized, image: "ourProducts", action: {}) Spacer() } .padding(.top, 12) Spacer() } } .navigationBarBackButtonHidden(true) // 移除无用的BackButtonHandler,改用自定义逻辑 } }
兼容性说明
该方案基于UIKit的UINavigationController实现,iOS13及以上版本均可正常运行,同时完全适配自定义导航栏的需求。
内容的提问来源于stack exchange,提问作者M.Argumedo
相关产品推荐
相关产品推荐

