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

Swift 4中如何判断来源视图控制器?复用UserDataViewController问询

这问题我之前做项目时也碰到过,复用UserDataViewController来处理注册和资料更新,核心就是要明确当前的业务场景,给你几个Swift 4里实用的方案,按需选就行:

方案1:用枚举标记场景(最推荐)

这种方式最清晰,完全解耦来源控制器的类型,后期要加新场景(比如修改密码)也非常方便,是我平时用得最多的方式。

首先定义一个枚举来标记业务场景:

enum UserDataScene {
    case register
    case profileUpdate
    // 以后加新场景直接在这里加就行,比如case passwordChange
}

然后在UserDataViewController里添加一个场景属性,跳转时传入对应的值:

class UserDataViewController: UIViewController {
    // 用隐式解包可选类型,确保跳转时一定会赋值
    var currentScene: UserDataScene!
    
    // 比如提交按钮点击时,根据场景执行不同逻辑
    @IBAction func submitButtonTapped(_ sender: UIButton) {
        switch currentScene {
        case .register:
            // 执行注册相关逻辑:调用注册接口、返回注册页面等
            print("处理注册流程")
            navigationController?.popViewController(animated: true)
        case .profileUpdate:
            // 执行资料更新逻辑:调用更新接口、返回个人资料页等
            print("处理资料更新流程")
            navigationController?.popViewController(animated: true)
        default:
            break
        }
    }
}

跳转时给场景属性赋值:

// 从RegisterViewController跳转
let userDataVC = UserDataViewController()
userDataVC.currentScene = .register
navigationController?.pushViewController(userDataVC, animated: true)

// 从ProfileViewController跳转
let userDataVC = UserDataViewController()
userDataVC.currentScene = .profileUpdate
navigationController?.pushViewController(userDataVC, animated: true)
方案2:直接判断来源控制器类型(快速实现)

如果你的项目逻辑简单,不想额外定义枚举,可以直接判断来源控制器的类型。不过这种方式耦合度高,以后来源控制器改名或者结构调整时,这里也要跟着改,适合小场景快速实现。

class UserDataViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 页面加载时判断来源
        identifySourceViewController()
    }
    
    private func identifySourceViewController() {
        // 处理push过来的情况:取导航栈里的前一个控制器
        if let viewControllers = navigationController?.viewControllers, viewControllers.count >= 2 {
            let previousVC = viewControllers[viewControllers.count - 2]
            if previousVC is RegisterViewController {
                print("来源是注册页面,准备处理注册逻辑")
            } else if previousVC is ProfileViewController {
                print("来源是个人资料页面,准备处理更新逻辑")
            }
        }
        // 处理present过来的情况:判断presentingViewController
        else if let presentingVC = presentingViewController {
            if presentingVC is RegisterViewController {
                print("来源是注册页面")
            } else if presentingVC is ProfileViewController {
                print("来源是个人资料页面")
            }
        }
    }
}
方案3:闭包回调(适合需要反向传值的场景)

如果UserDataViewController收集完数据后,需要把数据回传给来源控制器,用闭包回调会很方便,同时也能附带场景信息。

// 先定义一个用户数据模型(假设你需要回传这类数据)
struct UserData {
    let name: String
    let email: String
}

class UserDataViewController: UIViewController {
    // 定义闭包,参数是收集到的用户数据和当前场景
    var onSubmit: ((UserData, UserDataScene) -> Void)?
    
    @IBAction func submitButtonTapped(_ sender: UIButton) {
        // 模拟收集到的用户数据
        let collectedData = UserData(name: "Farid", email: "farid@example.com")
        
        // 确定当前场景
        guard let viewControllers = navigationController?.viewControllers, viewControllers.count >= 2 else { return }
        let previousVC = viewControllers[viewControllers.count - 2]
        let scene: UserDataScene = previousVC is RegisterViewController ? .register : .profileUpdate
        
        // 调用闭包回传数据
        onSubmit?(collectedData, scene)
        navigationController?.popViewController(animated: true)
    }
}

跳转时设置闭包:

// 从RegisterViewController跳转
let userDataVC = UserDataViewController()
userDataVC.onSubmit = { [weak self] userData, scene in
    guard let self = self else { return }
    // 这里处理注册逻辑,比如提交到服务器
    self.completeRegistration(with: userData)
}
navigationController?.pushViewController(userDataVC, animated: true)

// 从ProfileViewController跳转
let userDataVC = UserDataViewController()
userDataVC.onSubmit = { [weak self] userData, scene in
    guard let self = self else { return }
    // 这里处理资料更新逻辑
    self.updateUserProfile(with: userData)
}
navigationController?.pushViewController(userDataVC, animated: true)

内容的提问来源于stack exchange,提问作者Farid Valiyev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:40:28