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

SwiftUI中EmptyView占用空间及API无限调用问题求助

解决SwiftUI中EmptyView占用空间与API无限调用的问题

问题根源分析

  • VStack作为布局容器,会为子视图分配默认布局空间,因此其中的EmptyView会占据不必要的位置
  • API无限调用的核心原因是请求逻辑被放在了视图body或高频调用的方法中,SwiftUI的body会因状态变化频繁重计算,每次重算都会触发API请求

解决方案

1. 用Group替代VStack消除EmptyView空间占用

Group仅作为视图逻辑分组容器,不会添加额外布局规则,EmptyView在这里不会占用任何空间:

Group {
    if let arr = vm.arrMessages {
        getContent()
            .padding(.top)
    } else if vm.isLoading {
        ProgressView()
    } else if vm.isError {
        EmptyView()
    }
}

2. 控制API请求触发时机,避免无限调用

将API请求逻辑移到ViewModel的初始化、视图onAppear或状态变化的onChange中,同时添加重复请求拦截:

ViewModel层控制示例:

class ViewModel: ObservableObject {
    @Published var arrMessages: [Message]?
    @Published var isLoading = false
    @Published var isError = false

    init() {
        fetchMessages() // 初始化时仅调用一次
    }

    func fetchMessages() {
        guard !isLoading else { return } // 拦截重复请求
        isLoading = true
        
        // 实际API请求逻辑
        URLSession.shared.dataTask(with: URL(string: "你的接口地址")!) { [weak self] data, _, error in
            DispatchQueue.main.async {
                self?.isLoading = false
                if let error = error {
                    self?.isError = true
                    return
                }
                // 解析数据并赋值给arrMessages
                self?.arrMessages = 你的数据解析逻辑
            }
        }.resume()
    }
}

视图层触发示例(如果需要在视图出现时请求):

struct YourView: View {
    @StateObject var vm = ViewModel()

    var body: some View {
        Group {
            // 上述条件视图逻辑
        }
        .onAppear {
            vm.fetchMessages() // 视图首次出现时触发请求
        }
    }
}

关键提示

  • 绝对不要在body或getContent()这类视图构建方法中发起网络请求,这些方法会被SwiftUI频繁调用
  • 利用isLoading状态拦截重复请求,是避免无限调用的核心手段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 07:38:19