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

如何在用户无网络连接时禁用所有UIViewController的用户交互?

嘿,这个需求挺实用的,我来给你一步步捋清楚怎么实现👇

无网络时全局禁用UIViewController用户交互的方案

1. 先搞定网络状态的全局通知

既然你已经有了检测网络的方法,那第一步就是把网络状态的变化广播给所有页面。我们可以用NotificationCenter来做这件事:

// 先定义一个专属的通知名称,避免和其他通知冲突
extension Notification.Name {
    static let networkStatusUpdated = Notification.Name("NetworkStatusUpdated")
}

// 当你检测到网络状态变化时,发送这个通知
func broadcastNetworkStatus() {
    let isConnected = isConnectedToNetwork() // 这里用你已有的网络检测方法
    NotificationCenter.default.post(
        name: .networkStatusUpdated,
        object: nil,
        userInfo: ["isConnected": isConnected]
    )
}

如果你的网络检测是实时的(比如用监听回调),那就在状态变化时调用broadcastNetworkStatus();如果是定时检测,就在每次检测后调用就行。

2. 给所有UIViewController加个扩展

为了不用每个VC都写重复代码,我们给UIViewController写个扩展,让所有页面自动拥有处理网络状态的能力:

extension UIViewController {
    // 注册网络状态监听的方法
    func setupNetworkInteractionHandler() {
        // 监听网络状态变化通知
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleNetworkChange(_:)),
            name: .networkStatusUpdated,
            object: nil
        )
        // 页面加载时先检查一次当前网络状态
        checkInitialNetworkStatus()
    }
    
    // 初始化时检查网络状态并更新UI交互
    private func checkInitialNetworkStatus() {
        let isConnected = isConnectedToNetwork()
        updateUserInteraction(enabled: isConnected)
    }
    
    // 处理网络状态变化的回调
    @objc private func handleNetworkChange(_ notification: Notification) {
        guard let isConnected = notification.userInfo?["isConnected"] as? Bool else { return }
        updateUserInteraction(enabled: isConnected)
    }
    
    // 更新用户交互状态,同时添加/移除无网络提示遮罩
    private func updateUserInteraction(enabled: Bool) {
        view.isUserInteractionEnabled = enabled
        
        // 给用户加个无网络提示的遮罩,体验更好
        let maskTag = 999 // 用tag标记遮罩,方便后续移除
        if !enabled {
            let noNetworkMask = UIView(frame: view.bounds)
            noNetworkMask.backgroundColor = UIColor.black.withAlphaComponent(0.6)
            noNetworkMask.tag = maskTag
            
            let tipLabel = UILabel()
            tipLabel.text = "当前无网络连接,请检查网络后重试"
            tipLabel.textColor = .white
            tipLabel.textAlignment = .center
            tipLabel.numberOfLines = 0
            tipLabel.frame = CGRect(x: 40, y: view.center.y - 60, width: view.bounds.width - 80, height: 120)
            
            noNetworkMask.addSubview(tipLabel)
            view.addSubview(noNetworkMask)
        } else {
            // 网络恢复后移除遮罩
            view.viewWithTag(maskTag)?.removeFromSuperview()
        }
    }
    
    // 页面销毁时移除监听,避免内存泄漏
    deinit {
        NotificationCenter.default.removeObserver(self, name: .networkStatusUpdated, object: nil)
    }
}

3. 让所有VC用上这个功能

有两种省心的方式:

  • 方式一:手动调用:在每个VC的viewDidLoad里加一行代码:
override func viewDidLoad() {
    super.viewDidLoad()
    setupNetworkInteractionHandler()
}
  • 方式二:自定义基类:创建一个BaseViewController,让所有VC都继承它,在基类的viewDidLoad里自动调用方法,彻底解放双手:
class BaseViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        setupNetworkInteractionHandler()
    }
}

// 其他VC直接继承BaseViewController就行
class HomeViewController: BaseViewController {
    // ... 你的业务代码
}

额外小优化(iOS 12+)

如果你的APP支持iOS12及以上,推荐用苹果原生的NWPathMonitor实时监听网络变化,比定时检测更高效:

import Network

class NetworkMonitor {
    static let shared = NetworkMonitor()
    private let monitor = NWPathMonitor()
    private(set) var isConnected = false
    
    private init() {
        monitor.pathUpdateHandler = { [weak self] path in
            self?.isConnected = path.status == .satisfied
            // 状态变化时自动发送通知
            NotificationCenter.default.post(
                name: .networkStatusUpdated,
                object: nil,
                userInfo: ["isConnected": self?.isConnected ?? false]
            )
        }
        let queue = DispatchQueue(label: "NetworkMonitorQueue")
        monitor.start(queue: queue)
    }
}

这样就能实时感知网络状态变化,用户体验会更流畅~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:57:59