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

Swift 5中如何从Controller B刷新Controller A的TableView?

这是iOS开发里非常常见的跨控制器数据同步需求,我给你整理了三种实用的实现方案,你可以根据自己的场景来选:

方法一:使用闭包(Closure)

这种方式代码简洁,适合简单的一对一通信场景,直接把刷新逻辑“传递”给弹窗控制器。

步骤:

  1. 在Controller B(EnterQTYView)里定义一个闭包属性,用来传递提交后的响应数据
  2. 在Controller A弹出弹窗时,给这个闭包赋值,写入刷新TableView的逻辑
  3. Controller B提交成功后,调用闭包并传入响应字典

修改后的Controller B代码:

class EnterQTYView: UIViewController {
    // 定义闭包,参数为提交后返回的字典
    var onSubmitSuccess: (([String: Any]) -> Void)?

    // 提交按钮点击事件(假设你已经关联了这个方法)
    @IBAction func submitButtonTapped(_ sender: UIButton) {
        // 这里替换成你实际获取响应字典的逻辑
        let responseDict: [String: Any] = ["qty": "10", "status": "success"]
        
        // 调用闭包,把数据传递给Controller A
        onSubmitSuccess?(responseDict)
        
        // 关闭弹窗
        dismiss(animated: true, completion: nil)
    }
}

修改后的Controller A代码:

func btnQTYClickedFromcell(selectedIP: IndexPath) { 
    let storyboard = UIStoryboard(name: "Dashboard", bundle: nil) 
    // 这里要强制转成EnterQTYView类型,才能访问闭包属性
    guard let myAlert = storyboard.instantiateViewController(withIdentifier: "EnterQTYView") as? EnterQTYView else {
        return
    }
    myAlert.modalPresentationStyle = .overCurrentContext 
    myAlert.modalTransitionStyle = .crossDissolve 
    
    // 给闭包赋值,处理返回的数据并刷新TableView
    myAlert.onSubmitSuccess = { [weak self] responseDict in
        // 1. 先用responseDict更新你的数据源(比如self?.dataArray = 处理后的数据)
        // 2. 刷新TableView
        self?.tableView.reloadData()
    }
    
    self.present(myAlert, animated: true, completion: nil) 
}

方法二:使用代理(Delegate)

这种方式更符合iOS的设计规范,适合需要多个交互回调的复杂场景,代码可读性和扩展性更好。

步骤:

  1. 定义一个协议,包含提交成功的回调方法
  2. Controller B里定义代理属性
  3. Controller A遵守该协议并实现回调方法
  4. 弹出弹窗时设置Controller A为代理
  5. Controller B提交成功后调用代理方法

第一步:定义协议

// 定义代理协议,注意用AnyObject保证只能被类遵守
protocol EnterQTYViewDelegate: AnyObject {
    func enterQTYViewDidSubmit(with responseDict: [String: Any])
}

修改后的Controller B代码:

class EnterQTYView: UIViewController {
    // 代理属性必须用weak,避免循环引用
    weak var delegate: EnterQTYViewDelegate?

    @IBAction func submitButtonTapped(_ sender: UIButton) {
        let responseDict: [String: Any] = ["qty": "10", "status": "success"]
        
        // 调用代理方法传递数据
        delegate?.enterQTYViewDidSubmit(with: responseDict)
        
        dismiss(animated: true, completion: nil)
    }
}

修改后的Controller A代码:

// 让Controller A遵守代理协议
class ControllerA: UIViewController, EnterQTYViewDelegate {
    // ... 你的其他现有代码
    
    func btnQTYClickedFromcell(selectedIP: IndexPath) { 
        let storyboard = UIStoryboard(name: "Dashboard", bundle: nil) 
        guard let myAlert = storyboard.instantiateViewController(withIdentifier: "EnterQTYView") as? EnterQTYView else {
            return
        }
        myAlert.modalPresentationStyle = .overCurrentContext 
        myAlert.modalTransitionStyle = .crossDissolve 
        // 设置代理为当前Controller A
        myAlert.delegate = self
        
        self.present(myAlert, animated: true, completion: nil) 
    }
    
    // 实现代理方法
    func enterQTYViewDidSubmit(with responseDict: [String: Any]) {
        // 更新数据源
        // self?.dataArray = ...
        // 刷新TableView
        tableView.reloadData()
    }
}

方法三:使用通知中心(NotificationCenter)

这种方式适合跨多层控制器、或者多个地方需要监听提交事件的场景,但要注意内存管理,避免内存泄漏。

步骤:

  1. 定义一个自定义通知名称
  2. Controller A添加通知观察者,监听该通知
  3. Controller B提交成功后发送通知,携带响应字典
  4. Controller A收到通知后刷新TableView
  5. 在Controller A销毁时移除观察者

第一步:定义通知名称

// 用extension封装通知名称,更规范
extension Notification.Name {
    static let qtySubmitted = Notification.Name("qtySubmittedNotification")
}

修改后的Controller A代码:

class ControllerA: UIViewController {
    // ... 其他现有代码
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 添加通知观察者
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleQTYSubmitted(_:)),
            name: .qtySubmitted,
            object: nil
        )
    }
    
    // 页面销毁时移除观察者,避免内存泄漏
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    func btnQTYClickedFromcell(selectedIP: IndexPath) { 
        let storyboard = UIStoryboard(name: "Dashboard", bundle: nil) 
        let myAlert = storyboard.instantiateViewController(withIdentifier: "EnterQTYView") 
        myAlert.modalPresentationStyle = .overCurrentContext 
        myAlert.modalTransitionStyle = .crossDissolve 
        self.present(myAlert, animated: true, completion: nil) 
    }
    
    // 处理通知的方法
    @objc func handleQTYSubmitted(_ notification: Notification) {
        // 从通知里取出响应字典
        if let responseDict = notification.userInfo as? [String: Any] {
            // 更新数据源
            // self?.dataArray = ...
            // 刷新TableView
            tableView.reloadData()
        }
    }
}

修改后的Controller B代码:

@IBAction func submitButtonTapped(_ sender: UIButton) {
    let responseDict: [String: Any] = ["qty": "10", "status": "success"]
    
    // 发送通知,携带响应字典
    NotificationCenter.default.post(
        name: .qtySubmitted,
        object: nil,
        userInfo: responseDict
    )
    
    dismiss(animated: true, completion: nil)
}

方案选择建议:

  • 如果只是简单的提交后刷新,优先选闭包,代码最简洁
  • 如果需要多个回调交互(比如取消、编辑等),选代理,结构更清晰
  • 如果需要跨多层控制器或者多个页面监听事件,再考虑通知中心

内容的提问来源于stack exchange,提问作者Tushar Khopade

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:50:05