ForEach 完成时执行代码 - swiftUI

Execute code when ForEach finish - swiftUI

我想知道是否有一种方法可以在 forEach 函数完成事件上执行给定代码(如 OnAppear 或苹果提供的类似方法),如果没有方法可用,我如何在 ForEach 时执行代码完成。

我有以下代码:

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: {
                        [=10=].screenName == tweets[index].screenName
                    })?.screenName?.lowercased()
                )) {
                    VStack {
                        TweetView(
                            style: .withNoImage,
                            withHeight: true,
                            account: self.viewModel.viewState.selectedAccounts.first(where: {
                                [=10=].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)
            }
        }
    }
}

我想在 ForEach 完成事件中执行的代码:

value.scrollTo(viewModel.viewState.tweetSelectedIndex ?? 0)

ForEach 本身没有任何外观。它表示视图集合,由 ForEach 的容器决定如何显示该集合。那么 onAppear 附加到 ForEach 时甚至意味着什么?它是否流向集合中的每个视图?最好避免依赖这种奇怪组合的行为。

改为将 onAppear 附加到包含的 VStack

scrollTo 方法采用您提供的 id(在本例中为 viewModel.viewState.tweetSelectedIndex ?? 0)并尝试查找具有 id 修饰符的视图相同的标识符。但是您还没有在 ScrollView 中的任何视图上放置 id 修饰符。您需要使用 id 修饰符:

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: {
                        [=10=].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)
        }
    }
}