0

我想知道是否有一种方法可以在事件 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: {
                        $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)
            }
        }
    }
}

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

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

1 回答 1

2

ForEach没有任何自己的外观。它表示视图的集合,由容器ForEach决定如何显示该集合。onAppear那么,当连接到时,甚至是什么意思ForEach?它会流向集合中的每个视图吗?最好避免依赖这种奇怪组合的行为。

而是将其附加onAppear到容器上。VStack

scrollTo方法接受id您给它的(在本例中为viewModel.viewState.tweetSelectedIndex ?? 0)并尝试找到一个具有id相同标识符的修饰符的视图。但是您没有将id修饰符放在ScrollView. 您需要使用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: {
                        $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)
        }
    }
}
于 2021-11-19T14:58:22.030 回答