【问题标题】:TabView blank when trying to display json data via onAppear()尝试通过 onAppear() 显示 json 数据时 TabView 空白
【发布时间】:2020-07-31 22:03:33
【问题描述】:

我关注this tutorial 从我的 API 调用数据。我稍微偏离了方向,而是使用 TabView 来显示一个“主页”,其中数据在第一个选项卡中加载。它在某种意义上“有效”,如果我导航到另一个选项卡并返回主选项卡,数据就会出现。但是,当我打开应用程序时,选项卡是空白的。我最初将posts 声明为一个空数组,为什么onAppear() 没有填充它?

这是应该显示我的数据的视图

struct DiscoverView: View {
    @ObservedObject var discoverPosts: DiscoverPosts
    
    var body: some View {
        NavigationView{
            ScrollView(.vertical, showsIndicators: false) {
                VStack(alignment: .center){
                    ForEach(self.discoverPosts.posts) { post in
                        HStack{
                            DiscoverList(isModal : false,displayName : post.displayName,id : post.id,likes : post.likes,owner : post.owner,avatar : post.avatar,author_id : post.author_id,icebreaker : post.icebreaker,answer : post.answer,mediaLink : post.mediaLink,songURL : post.songURL,type : post.type,liked: post.liked)
                        }
                        .padding(10)
                    }
                }
            }
            .onAppear(){
                // self.discoverPosts.getPosts()
            }
            .navigationViewStyle(StackNavigationViewStyle())
            .navigationBarTitle("Discover")
        }
    }
}

这是我的discoverPosts()

class discoverPosts : ObservableObject {
    @State var posts : [Post] = []
    func getPosts(completion: @escaping ([Post]) -> ()){
        let feedURL = "URL"
        guard let url = URL(string: feedURL) else { return }
        URLSession.shared.dataTask(with: url) { (data, _, _) in
            let posts = try! JSONDecoder().decode([Post].self, from: data!)
            DispatchQueue.main.async {
                self.posts = posts
                completion(posts)
            }
        }
        .resume()
    }
}

显示 TabView 的我的 ConventView.swift。我认为问题可能出在层次结构上

struct ContentView: View {
    var body: some View {
        
        Home()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct Home : View {
    
    @State var show = false
    @State var status = UserDefaults.standard.value(forKey: "status") as? Bool ?? false
    
    var body: some View{
            VStack{
                
                if self.status{
                    
                    TabView {
                        DiscoverView(discoverPosts: DiscoverPosts())
                            .tabItem(){
                                Image(systemName: "person")
                                .font(.system(size:20))
                            }
                            .tag(1)
                        InboxView(offsetLine: IndexSet.Element())
                            .tabItem(){
                                Image(systemName: "message")
                                .font(.system(size: 20))
                            }
                            .tag(2)
                        ProfileView()
                            .tabItem(){
                                Image(systemName: "person")
                                .font(.system(size: 20))
                            }
                            .tag(3)
                    }
                    .accentColor(Color.purple)
                    .navigationViewStyle(StackNavigationViewStyle())
                }
                else{
                    
                    ZStack{
                        
                        NavigationLink(destination: SignUp(show: self.$show), isActive: self.$show) {
                            
                            Text("")
                        }
                        .hidden()
                        
                        Login(show: self.$show)
                    }
                }
            }
            .navigationBarTitle("")
            .navigationBarHidden(true)
            .navigationBarBackButtonHidden(true)
            .onAppear {
                
                NotificationCenter.default.addObserver(forName: NSNotification.Name("status"), object: nil, queue: .main) { (_) in
                    
                    self.status = UserDefaults.standard.value(forKey: "status") as? Bool ?? false
                }
            }
    }
}

遇到这种情况的朋友可以把Text("").frame(width: UIScreen.main.bounds.width)扔到ScrollView底部

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    将您的 ObservableObject 更改为:

    class DiscoverPosts: ObservableObject { // make Types capitalised
        @Published var posts: [Post] = [] // <- replace @State with @Published
    
        init() {
            getPosts()
        }
    
        func getPosts() { // <- no need for completion handler, update `self.posts`
            let feedURL = "URL"
            guard let url = URL(string: feedURL) else { return }
            URLSession.shared.dataTask(with: url) { data, _, _ in
                let posts = try! JSONDecoder().decode([Post].self, from: data!)
                DispatchQueue.main.async {
                    self.posts = posts
                }
            }
            .resume()
        }
    }
    

    并像这样在您的视图中使用它:

    struct DiscoverView: View {
        @ObservedObject var discoverPosts: DiscoverPosts // declare only
    
        var body: some View {
            ZStack {
                ...
            }
            //.onAppear { // <- remove onAppear
            //    self.discoverPosts.getPosts()
            //}
        }
    }
    

    您还需要将DiscoverPostsHome 视图传递给DiscoverView

    DiscoverView(discoverPosts: DiscoverPosts())
    

    请注意,如果您之前在视图中访问过self.posts,那么您现在需要访问self.discoverPosts.posts

    【讨论】:

    • 我已经编辑了我的帖子以包含我的 discoverPosts() 并在您的指导下进行了一些编辑。不幸的是,当应用首次加载时,主页选项卡仍显示为空白。
    • 谢谢!我在@ObservedObject var discoverPosts = DiscoverPosts() 线上收到此错误Variable used within its own initial value
    • @MarkusProctor 请注意,我更改了class DiscoverPosts,现在它已大写。 Swift 中的好习惯是使用大写的类型名称。
    • 是的,刚刚注意到。仍然是空白 X(我将编辑我的原始帖子以在代码中上一层。
    • 感谢您的帮助。初始加载时它仍然是空白的。我仍然需要更改标签。
    猜你喜欢
    • 2019-02-03
    • 2022-01-11
    • 2017-09-04
    • 2021-09-05
    • 1970-01-01
    • 2021-12-25
    • 2023-03-16
    • 1970-01-01
    • 2011-07-10
    相关资源
    最近更新 更多