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

如何在UITableViewController之上添加UIView?数据加载场景需求

在UITableViewController上添加加载状态视图的实现方案

嘿,这个需求其实挺常见的,我来给你几个靠谱的实现思路,亲测好用~

方法一:全屏覆盖式加载视图(推荐用于需要阻止用户操作的场景)

这种方法会在整个tableView上方叠一层加载视图,直到数据加载完成,适合需要防止用户在加载时交互的情况。

步骤:

  • 先定义一个加载视图的属性,在viewDidLoad中初始化并添加到控制器的view上(因为UITableViewController的view就是tableView,所以添加后层级更高,会覆盖在tableView之上)
  • 发起网络请求前显示该视图,加载完成后隐藏并刷新tableView

代码示例(Swift):

class ContactsTableViewController: UITableViewController {
    private var loadingOverlayView: UIView!
    private var contacts: [Contact] = [] // 你的联系人模型数组
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupLoadingOverlay()
        startFetchingContacts()
    }
    
    // 初始化全屏加载视图
    private func setupLoadingOverlay() {
        loadingOverlayView = UIView(frame: view.bounds)
        // 设置半透明背景,让用户能看到下方的tableView但无法操作
        loadingOverlayView.backgroundColor = UIColor.systemBackground.withAlphaComponent(0.8)
        loadingOverlayView.isUserInteractionEnabled = true // 拦截用户点击
        
        // 添加活动指示器(换成UIImageView就是图片加载视图)
        let activityIndicator = UIActivityIndicatorView(style: .large)
        activityIndicator.center = loadingOverlayView.center
        activityIndicator.color = .systemBlue
        activityIndicator.startAnimating()
        loadingOverlayView.addSubview(activityIndicator)
        
        // 初始状态隐藏
        loadingOverlayView.isHidden = true
        view.addSubview(loadingOverlayView)
    }
    
    private func startFetchingContacts() {
        // 显示加载视图
        loadingOverlayView.isHidden = false
        
        // 模拟网络请求(替换成你的实际API请求)
        URLSession.shared.dataTask(with: URL(string: "https://your-contacts-api.com")!) { [weak self] data, response, error in
            guard let self = self else { return }
            
            // 这里处理数据解析,把结果赋值给contacts数组
            if let data = data {
                // 假设用JSONDecoder解析
                do {
                    self.contacts = try JSONDecoder().decode([Contact].self, from: data)
                } catch {
                    print("解析失败:\(error)")
                }
            }
            
            // 回到主线程更新UI
            DispatchQueue.main.async {
                self.loadingOverlayView.isHidden = true
                self.tableView.reloadData()
            }
        }.resume()
    }
}

方法二:TableHeaderView加载视图(适合非全屏的加载提示)

如果你希望加载视图只显示在tableView的顶部,而不是覆盖整个屏幕,可以用tableHeaderView来实现。

步骤:

  • 初始化一个加载视图作为tableView的header,初始时设置高度为0(隐藏状态)
  • 发起请求前设置header的高度为你想要的尺寸,显示加载视图
  • 加载完成后把header高度设回0,隐藏并刷新tableView

代码示例(Swift):

class ContactsTableViewController: UITableViewController {
    private var loadingHeaderView: UIView!
    private var contacts: [Contact] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupLoadingHeader()
        startFetchingContacts()
    }
    
    private func setupLoadingHeader() {
        let headerHeight: CGFloat = 200
        loadingHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: headerHeight))
        loadingHeaderView.backgroundColor = UIColor.systemGray5
        
        // 添加活动指示器或图片
        let loadingImage = UIImageView(image: UIImage(named: "loading-placeholder"))
        loadingImage.contentMode = .scaleAspectFit
        loadingImage.center = loadingHeaderView.center
        loadingHeaderView.addSubview(loadingImage)
        
        // 初始时设置header高度为0,隐藏
        tableView.tableHeaderView = loadingHeaderView
        tableView.tableHeaderView?.frame.size.height = 0
    }
    
    private func startFetchingContacts() {
        // 显示加载header
        tableView.tableHeaderView?.frame.size.height = 200
        
        URLSession.shared.dataTask(with: URL(string: "https://your-contacts-api.com")!) { [weak self] data, response, error in
            guard let self = self else { return }
            
            // 解析数据...
            if let data = data {
                do {
                    self.contacts = try JSONDecoder().decode([Contact].self, from: data)
                } catch {
                    print("解析错误:\(error)")
                }
            }
            
            DispatchQueue.main.async {
                // 隐藏header
                self.tableView.tableHeaderView?.frame.size.height = 0
                self.tableView.reloadData()
            }
        }.resume()
    }
}

额外注意点

  • 必须在主线程更新UI:网络请求是在后台线程执行的,所以更新加载视图的隐藏状态和刷新tableView一定要放到DispatchQueue.main.async里,否则会崩溃或者不生效。
  • 自定义加载视图:如果需要用图片代替活动指示器,只需要把代码中的UIActivityIndicatorView换成UIImageView,设置好图片和布局即可。
  • 用户交互控制:如果用全屏覆盖视图,记得设置isUserInteractionEnabled = true,这样用户在加载时无法点击tableView的单元格,避免无效操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:45:05