首页 > 解决方案 > 条件渲染不起作用SwiftUI

问题描述

我有以下内容:

import SwiftUI

struct Search: View {
    @StateObject var genericObservable = GenericObservable(type: Type.card)
    
    var body: some View {
        switch genericObservable.cards {
        case .success(let cards):

>             Text("Success")

        case .failure(_):
            ProgressView().frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
}

上面的代码呈现了 this

但是,当我把它Text("Success")放在一个条件中(因为它应该可以工作)时,应用程序变为空白。

import SwiftUI

struct Search: View {
    @StateObject var genericObservable = GenericObservable(type: Type.card)
    
    var body: some View {
        switch genericObservable.cards {
        case .success(let cards):
          if (cards.isEmpty) {
              Text("Loading")
          } else {
              Text("Success")
          }
        case .failure(_):
            ProgressView().frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
}

这不会渲染任何东西->看这里

作为参考这里是GenericObservable()

import Foundation

enum Type: String {
    case card = "CARD"
    case none = "NONE"
}

class GenericObservable: ObservableObject {
    
    static let shared = GenericObservable(type: Type.none)
    @Published var cards: Result<[Card], Error> = .success([])
    
    func fetchAllCardsQuery(completion: @escaping(Result<[Card], Error>) -> Void) {
        request(route: .fetchAllCategories, method: .get, completion: completion)
    }
    
    init(type: Type) {
        if (type == Type.card) {
            fetchAllCardsQuery {(result) in
                switch result {
                case .success(let allCards):
                    self.cards = .success(allCards)
                    
                case .failure(let error):
                    self.cards = .failure(error)
                }
            }
        }
    }
    
    private func request<T: Decodable>(route: Route,
                                       method: Method,
                                       parameters: [String: Any]? = nil,
                                       completion: @escaping(Result<T, Error>) -> Void) {
        guard let request = createRequest(route: route, method: method, parameters: parameters) else {
            completion(.failure(AppError.unknownError))
            return
        }
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            var result: Result<Data, Error>?
            if let data = data {
                result = .success(data)
                // let responseString = String(data: data, encoding: .utf8) ?? "Could not stringify our data"
                // print("The response is:\n\(responseString)")
            } else if let error = error {
                result = .failure(error)
                // print("The error is: \(error.localizedDescription)")
            }
            
            DispatchQueue.main.async {
                self.handleResponse(result: result, completion: completion)
            }
        }.resume()
    }
    
    private func handleResponse<T: Decodable>(result: Result<Data, Error>?,
                                              completion:@escaping  (Result<T, Error>) -> Void) {
        guard let result = result else {
            completion(.failure(AppError.unknownError))
            return
        }
        
        switch result {
        case .success(let data):
            let decoder = JSONDecoder()
            guard let response = try? decoder.decode(T.self, from: data) else {
                completion(.failure(AppError.errorDecoding))
                return
            }
            completion(.success(response))
            
        case .failure(let error):
            completion(.failure(AppError.serverError(error.localizedDescription)))
        }
    }
    

    private func createRequest(route: Route,
                               method: Method,
                               parameters: [String: Any]? = nil) -> URLRequest? {
        let urlString = Route.baseUrl + route.description
        guard let url = URL(string: urlString) else { return nil }
        var urlRequest = URLRequest(url: url)
        urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
        urlRequest.httpMethod = method.rawValue
        
        if let params = parameters {
            switch method {
            case .get:
                var urlComponent = URLComponents(string: urlString)
                urlComponent?.queryItems = params.map { URLQueryItem(name: $0, value: "\($1)") }
                urlRequest.url = urlComponent?.url
            case .post, .delete, .patch:
                let bodyData = try? JSONSerialization.data(withJSONObject: params, options: [])
                urlRequest.httpBody = bodyData
            }
        }
        return urlRequest
    }
}

这是ContentView()

struct CoreView: View {
    @State private var selection = 1
    
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    
    private var items: FetchedResults<Item>
    
    var body: some View {
        VStack {
            TabView(selection: $selection) {
                Text("Bookmark").tag(0)
                
                Search().tag(1)
                
                Text("Add").tag(2)
                
                Text("Comment").tag(3)
                
                Text("Account").tag(4)
            }.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
            
            Divider()
            
            CustomTabBarUIView(selection: $selection)
        }
    }
}

标签: swiftswiftuiconditional-rendering

解决方案


推荐阅读