I want to know if there is a method that executes a given code on the event forEach funtion finish (like OnAppear or similar methods provided by apple) and in case no method is available, how can i executed code when ForEach finish.
I have the following code:
ScrollView {
ScrollViewReader { value in
VStack {
let tweets = getFilteredTweets()
ForEach((0..<tweets.count), id: \.self) { index in
NavigationLink(destination: TweetWebView(
tweetId: tweets[index].id,
accountId: self.viewModel.viewState.selectedAccounts.first(where: {
$0.screenName == tweets[index].screenName
})?.screenName?.lowercased()
)) {
VStack {
TweetView(
style: .withNoImage,
withHeight: true,
account: self.viewModel.viewState.selectedAccounts.first(where: {
$0.screenName == tweets[index].screenName
}),
tweet: tweets[index]
)
.frame(maxHeight: .infinity)
.onTapGesture {
viewModel.triggerEvent(.setTweetSelectedIndex(index: index))
}
}
}
.buttonStyle(PlainButtonStyle())
}
.onAppear {
value.scrollTo(viewModel.viewState.tweetSelectedIndex ?? 0)
}
}
}
}
The code I want to execute in the event ForEach finish:
value.scrollTo(viewModel.viewState.tweetSelectedIndex ?? 0)
ForEach
doesn't have any appearance of its own. It represents a collection of views, and it is up to the container of the ForEach
to decide how to show that collection. So what does onAppear
even mean when attached to ForEach
? Does it flow down to each view in the collection? It's better to avoid relying on the behavior of such a weird combination.
Attach the onAppear
to the containing VStack
instead.
The scrollTo
method takes the id
you give it (in this case, viewModel.viewState.tweetSelectedIndex ?? 0
) and tries to find a view that has a id
modifier with the same identifier. But you haven't put the id
modifier on any of the views in your ScrollView
. You need to use the id
modifier:
ScrollView {
ScrollViewReader { value in
VStack {
let tweets = getFilteredTweets()
ForEach(0 ..< tweets.count, id: \.self) { index in
NavigationLink(destination: TweetWebView(
tweetId: tweets[index].id,
accountId: self.viewModel.viewState.selectedAccounts.first(where: {
$0.screenName == tweets[index].screenName
})?.screenName?.lowercased()
)) {
// blah blah blah
}
.buttonStyle(PlainButtonStyle())
.id(index)
// ADD THIS ^^^^^^^^^^
}
}
.onAppear {
// ^^^^^^^^^ MOVE THIS ONTO THE VSTACK
value.scrollTo(viewModel.viewState.tweetSelectedIndex ?? 0)
}
}
}