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

Swift 4中实现导航栏刷新按钮及5分钟自动刷新功能

嘿,我来帮你实现这个导航栏刷新的需求!既要支持手动点击刷新,又要每5分钟自动更新,还要在加载时显示Activity Indicator,咱们一步步来搞定:

第一步:定义所需的变量

首先在你的ViewController里声明几个核心变量,用来管理刷新按钮、加载指示器和自动刷新定时器:

private var refreshButton: UIBarButtonItem!
private var activityIndicator: UIActivityIndicatorView!
private var refreshTimer: Timer?
第二步:初始化UI组件和启动自动刷新

在viewDidLoad里完成控件初始化、设置导航栏按钮,同时启动自动刷新和初始数据加载:

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 初始化Activity Indicator,适配导航栏风格
    activityIndicator = UIActivityIndicatorView(style: .medium)
    activityIndicator.tintColor = .white // 根据你的导航栏背景色调整颜色
    
    // 创建刷新按钮并绑定点击事件
    refreshButton = UIBarButtonItem(barButtonSystemItem: .refresh, target: self, action: #selector(refreshButtonTapped))
    navigationItem.rightBarButtonItem = refreshButton
    
    // 启动每5分钟一次的自动刷新
    startAutoRefresh()
    
    // 首次加载数据
    getCoinData { [weak self] in
        self?.coinTableView.reloadData()
    }
}
第三步:改造数据获取方法,添加完成回调

你的getCoinData是异步网络请求,必须添加闭包回调,这样才能在数据加载完成后更新UI并恢复按钮状态:

func getCoinData(completion: @escaping () -> Void) {
    // 替换成你的JSON请求URL
    guard let url = URL(string: "https://your-api-url.com/coins") else {
        print("无效的请求URL")
        DispatchQueue.main.async { completion() }
        return
    }
    
    URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
        guard let self = self else { 
            DispatchQueue.main.async { completion() }
            return 
        }
        
        if let error = error {
            print("数据请求失败: \(error.localizedDescription)")
            DispatchQueue.main.async { completion() }
            return
        }
        
        guard let data = data else {
            print("未获取到有效数据")
            DispatchQueue.main.async { completion() }
            return
        }
        
        // 解析JSON到你的数据源数组(这里假设你的数据模型是Coin)
        do {
            self.coinDataArray = try JSONDecoder().decode([Coin].self, from: data)
        } catch {
            print("JSON解析失败: \(error.localizedDescription)")
        }
        
        // 回到主线程执行回调,更新UI
        DispatchQueue.main.async {
            completion()
        }
    }.resume()
}
第四步:实现手动刷新逻辑和状态切换

编写点击事件方法,切换按钮和加载指示器的显示状态,同时处理数据刷新:

@objc private func refreshButtonTapped() {
    // 用户手动刷新后,重置自动刷新定时器(重新计算5分钟的自动刷新时间)
    refreshTimer?.invalidate()
    
    // 切换到加载状态,隐藏刷新按钮显示指示器
    toggleRefreshLoadingState(isLoading: true)
    
    // 获取数据并更新表格
    getCoinData { [weak self] in
        guard let self = self else { return }
        self.coinTableView.reloadData()
        self.toggleRefreshLoadingState(isLoading: false)
        // 重新启动自动刷新
        self.startAutoRefresh()
    }
}

// 封装状态切换逻辑,方便复用
private func toggleRefreshLoadingState(isLoading: Bool) {
    if isLoading {
        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: activityIndicator)
        activityIndicator.startAnimating()
    } else {
        navigationItem.rightBarButtonItem = refreshButton
        activityIndicator.stopAnimating()
    }
}
第五步:实现自动刷新和内存清理

编写自动刷新的定时器逻辑,同时在页面消失时销毁定时器,避免内存泄漏:

private func startAutoRefresh() {
    // 5分钟 = 300秒,设置定时器并加入RunLoop,避免后台暂停
    refreshTimer = Timer.scheduledTimer(timeInterval: 300, target: self, selector: #selector(autoRefresh), userInfo: nil, repeats: true)
    RunLoop.current.add(refreshTimer!, forMode: .common)
}

@objc private func autoRefresh() {
    // 自动刷新的逻辑和手动刷新完全一致
    toggleRefreshLoadingState(isLoading: true)
    
    getCoinData { [weak self] in
        guard let self = self else { return }
        self.coinTableView.reloadData()
        self.toggleRefreshLoadingState(isLoading: false)
    }
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    // 页面消失时销毁定时器,释放资源
    refreshTimer?.invalidate()
    refreshTimer = nil
}
一些细节提醒
  • 全程用[weak self]避免循环引用,尤其是在闭包和定时器中,防止内存泄漏
  • 网络请求失败时一定要执行completion回调,确保加载状态能恢复,不会一直转圈
  • 如果你的导航栏是深色背景,记得调整Activity Indicator的tintColor,保证可见性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:05:39