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

Swift新手求助:如何通过按钮或下拉刷新先更新JSON再刷新TableView?

嘿,作为Swift新手遇到这个问题太正常了,我来一步步给你讲清楚怎么实现按钮触发/下拉刷新更新JSON数据并刷新TableView~

Swift实现按钮触发/下拉刷新更新JSON并刷新TableView

首先咱们得把基础框架搭好:你需要一个UITableView、存储数据的数据源数组,还有处理网络请求的核心方法。假设你已经完成了TableView的基础配置(不管是Storyboard拖的还是代码创建的),下面分两种场景详细说:

一、按钮触发更新的实现

步骤1:绑定按钮点击事件

先在界面上放一个UIButton,按住Control键从按钮拖到ViewController里,创建一个IBAction方法,比如叫refreshWithButton(_ sender: UIButton)。

步骤2:核心流程实现(请求数据→解析→刷新TableView)

咱们用系统的URLSession做网络请求,配合Codable协议解析JSON到自定义模型,代码示例如下:

// 自定义数据模型,必须符合Codable才能解析JSON
struct YourDataModel: Codable {
    let id: Int
    let title: String
    // 其他你需要的字段,和JSON结构对应上
}

class YourViewController: UIViewController, UITableViewDataSource {
    @IBOutlet weak var tableView: UITableView!
    // 数据源数组,用来存解析后的数据
    var dataSource: [YourDataModel] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        // 页面加载时先拉一次初始数据
        fetchLatestData()
    }
    
    // 核心方法:获取最新JSON数据并更新数据源
    private func fetchLatestData() {
        guard let requestUrl = URL(string: "你的JSON接口地址") else {
            print("URL格式错误")
            return
        }
        
        // 发起网络请求(后台线程执行)
        let task = URLSession.shared.dataTask(with: requestUrl) { [weak self] data, _, error in
            guard let self = self else { return }
            
            // 处理请求错误
            if let error = error {
                print("请求失败:\(error.localizedDescription)")
                // 回到主线程给用户提示(可选)
                DispatchQueue.main.async {
                    let alert = UIAlertController(title: "提示", message: "数据加载失败", preferredStyle: .alert)
                    alert.addAction(UIAlertAction(title: "确定", style: .default))
                    self.present(alert, animated: true)
                }
                return
            }
            
            // 解析JSON数据
            guard let data = data else {
                print("未获取到有效数据")
                return
            }
            
            do {
                // 解析成模型数组
                let newDataList = try JSONDecoder().decode([YourDataModel].self, from: data)
                // 回到主线程更新UI(必须!网络请求在后台,UI操作只能在主线程)
                DispatchQueue.main.async {
                    self.dataSource = newDataList
                    // 刷新TableView
                    self.tableView.reloadData()
                }
            } catch {
                print("JSON解析失败:\(error.localizedDescription)")
            }
        }
        task.resume()
    }
    
    // 按钮点击事件
    @IBAction func refreshWithButton(_ sender: UIButton) {
        // 给按钮加个加载状态,避免重复点击
        sender.isEnabled = false
        let loadingIndicator = UIActivityIndicatorView(style: .medium)
        loadingIndicator.center = sender.center
        sender.addSubview(loadingIndicator)
        loadingIndicator.startAnimating()
        
        // 调用数据请求方法
        fetchLatestData()
        
        // 请求完成后恢复按钮状态(建议在fetchLatestData的回调里处理,这里简化示例)
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            sender.isEnabled = true
            loadingIndicator.stopAnimating()
            loadingIndicator.removeFromSuperview()
        }
    }
    
    // MARK: - UITableViewDataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellID", for: indexPath)
        let model = dataSource[indexPath.row]
        cell.textLabel?.text = model.title
        return cell
    }
}

二、下拉刷新(UIRefreshControl)的实现

用系统自带的UIRefreshControl就能轻松实现下拉刷新,不需要第三方库:

步骤1:给TableView添加下拉刷新控件

在viewDidLoad里初始化并绑定触发方法:

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.dataSource = self
    
    // 初始化下拉刷新控件
    let refreshControl = UIRefreshControl()
    refreshControl.addTarget(self, action: #selector(refreshWithPull), for: .valueChanged)
    // 设置刷新提示文字(可选)
    refreshControl.attributedTitle = NSAttributedString(string: "正在加载最新数据...")
    // 把控件绑定到TableView
    tableView.refreshControl = refreshControl
    
    // 初始加载数据
    fetchLatestData()
}

步骤2:实现下拉刷新的触发方法

@objc private func refreshWithPull() {
    // 调用核心数据请求方法
    fetchLatestData()
}

然后修改fetchLatestData方法,在请求结束后结束刷新状态(不管成功失败都要做):

private func fetchLatestData() {
    guard let requestUrl = URL(string: "你的JSON接口地址") else {
        print("URL格式错误")
        DispatchQueue.main.async {
            self.tableView.refreshControl?.endRefreshing()
        }
        return
    }
    
    let task = URLSession.shared.dataTask(with: requestUrl) { [weak self] data, _, error in
        guard let self = self else { return }
        
        // 不管请求成功失败,都结束下拉刷新状态
        DispatchQueue.main.async {
            self.tableView.refreshControl?.endRefreshing()
        }
        
        // 后续的错误处理、数据解析逻辑和之前一样...
        // (这里省略重复代码,和按钮触发的逻辑一致)
    }
    task.resume()
}

额外小Tips

  • 如果你的JSON结构是嵌套的(比如{"code":200,"data":[]}),需要创建一个根模型来解析:
    struct RootResponse: Codable {
        let code: Int
        let data: [YourDataModel]
    }
    
    解析时用JSONDecoder().decode(RootResponse.self, from: data),再取rootResponse.data作为数据源。
  • 网络请求可以封装成单独的工具类,避免ViewController代码冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:41:51