1

I have a SwiftUI View that I am presenting in a UIViewController container. When a user creates a post I want the feed to fetch that new post from the service and insert it at the beginning of the array. All of that is working (the service fetches the correct post), but the issue is the SwiftUI view does not update to reflect the insertion of that new post. If I scroll down and then back up the feed will have a duplicate post of the last post before the newest one.

Any ideas why this may be happening?

I've tried removing Lazy from the VStack but that didn't help, I'm not sure why the Published posts array wouldn't update the view

The SwiftUI View:

var contentView: some View {
    ScrollViewReader { scrollViewProxy in
        ScrollView {
            LazyVStack(alignment: .center, spacing: 6) {
                
                ForEach(viewModel.posts.indices, id: \.self) { index in
                    // Business Logic
                }
            }
        }
    }
}

func reloadWithPost() {
    Task {
        await viewModel.loadNew()
    }
}

In View Model

@Published var posts: [PostOBJ] = []    

@MainActor
func loadNew() async {
    self.loadingNew = true
    
    do {
        let posts = try await service.getPageZero()
        
        let newPosts: [PostOBJ]? = posts.filter { post in
            !self.posts.contains { $0.id == post.id }
        }
                    
        guard let newPosts: [PostOBJ] = newPosts, !newPosts.isEmpty else {
            return
        }
        
        let allPosts: [PostOBJ] = newPosts + self.posts
        
        self.posts = allPosts
        
    } catch { }
}

In UIKit UIViewController Container

var feedView: FeedView?

override func viewDidLoad() {
    super.viewDidLoad()
    
    let view = FeedView(openDelegate: self)
    self.feedView = view
    let controller: UIViewController = UIHostingController(rootView: view)
    presentedVC = controller
}

extension ViewControllersContainer: ComposePostDelegate {
    func postComposed() {
        self.feedView?.reloadWithPost()
    }
}
tHatpart
  • 1,302
  • 3
  • 12
  • 27
  • This isn't a [mre], so it's not possible to debug definitively, but you almost certainly shouldn't be using `viewModel.posts.indices` -- `indices` in `ForEach` will create exactly the type of problems you're describing. Instead, use `Identifiable` models – jnpdx Jun 04 '23 at 17:16
  • You can’t hold on to the value of a SwiftUI view. It will be “outdated” very quickly. You can hold on the view model but not the view itself – lorem ipsum Jun 04 '23 at 17:26
  • https://stackoverflow.com/questions/70435695/call-uikit-function-from-swiftui/70437340#70437340 – lorem ipsum Jun 04 '23 at 17:28
  • ForEach is a View not a for loop you can't use it with indices – malhal Jun 05 '23 at 05:29

0 Answers0