Swift ForEach内页不';t循环项目快速用户界面

Swift ForEach内页不';t循环项目快速用户界面,swift,foreach,swiftui,Swift,Foreach,Swiftui,我在ForEach中使用工作表时遇到了一个问题。基本上,我有一个显示数组中许多项的列表和一个触发工作表的图像。问题是,当我的工作表出现时,它只显示我数组的第一项,在本例中是“哈利波特” 这是密码 struct ContentView: View { @State private var showingSheet = false var movies = ["Harry potter", "Mad Max", "Obliv

我在ForEach中使用工作表时遇到了一个问题。基本上,我有一个显示数组中许多项的列表和一个触发工作表的图像。问题是,当我的工作表出现时,它只显示我数组的第一项,在本例中是“哈利波特”

这是密码

struct ContentView: View {
    @State private var showingSheet = false
    
    var movies = ["Harry potter", "Mad Max", "Oblivion", "Memento"]
    var body: some View {
        NavigationView {
            List {
                ForEach(0 ..< movies.count) { movie in
                    HStack {
                        Text(self.movies[movie])
                        Image(systemName: "heart")
                    }
                        .onTapGesture {
                            self.showingSheet = true
                    }
                    .sheet(isPresented: self.$showingSheet) {
                        Text(self.movies[movie])
                    }
                }
            }
        }
    }
}
struct ContentView:View{
@状态私有变量显示表=false
var电影=[《哈利波特》、《疯狂麦克斯》、《遗忘》、《纪念品》]
var body:一些观点{
导航视图{
名单{
ForEach(0..
应该只有一个工作表,所以这里有一种可能的方法-使用另一个工作表修改器并通过选择激活它

使用Xcode 12/iOS 14进行测试(与iOS 13兼容)

扩展名Int:可识别{
公共变量id:Int{self}
}
结构ContentView:View{
@国家私有变量selectedMovie:Int?=nil
var电影=[《哈利波特》、《疯狂麦克斯》、《遗忘》、《纪念品》]
var body:一些观点{
导航视图{
名单{
ForEach(0..
我将您的代码更改为只有一张工作表,并将选定的电影放在一个变量中

extension String: Identifiable {
    public var id: String { self }
}

struct ContentView: View {
    @State private var selectedMovie: String? = nil
    
    var movies = ["Harry potter", "Mad Max", "Oblivion", "Memento"]
    var body: some View {
        NavigationView {
            List {
                ForEach(movies) { movie in
                    HStack {
                        Text(movie)
                        Image(systemName: "heart")
                    }
                    .onTapGesture {
                        self.selectedMovie = movie
                    }
                }
            }
            .sheet(item: self.$selectedMovie, content: { selectedMovie in
                Text(selectedMovie)
            })
        }
    }
}

我想在这件事上给我2美分。 我遇到了同样的问题,Asperi的解决方案对我很有效。 但是-我还想在工作表上有一个按钮,可以取消模态

当您使用
isPresented
调用
工作表
时,您会传递一个绑定布尔值,因此您会将其更改为
false
,以解除绑定。 在
item
案例中,我所做的是将该项作为绑定传递。在工作表中,我将该绑定项更改为
nil
,并取消了工作表

例如,在这种情况下,代码是:

var movies = ["Harry potter", "Mad Max", "Oblivion", "Memento"]
var body: some View {
    NavigationView {
        List {
            ForEach(0 ..< movies.count) { movie in
                HStack {
                    Text(self.movies[movie])
                    Image(systemName: "heart")
                }
                    .onTapGesture {
                        self.selectedMovie = movie
                }
            }
        }
        .sheet(item: self.$selectedMovie) {
            Text(self.movies[$0])

            // My addition here: a "Done" button that dismisses the sheet

            Button {
                selectedMovie = nil
            } label: {
                Text("Done")
            }

        }
    }
}
var movies=[《哈利波特》、《疯狂麦克斯》、《遗忘》、《纪念品》]
var body:一些观点{
导航视图{
名单{
ForEach(0..
我展示的这个示例非常简单,它可以通过您如何更改它来工作,但我有一个更复杂的情况,我需要跟踪项目在数组中的位置,并且我还需要在单击按钮时关闭工作表。有没有其他方法可以在不使用@State属性调用的情况下解决此问题?我只是不明白为什么在ForEach中使用Sheet时,它在循环时不跟踪“movie”位置。该self.movies[movie]应该每次都会更改,但当您在ForEach中添加.sheet修饰符时,它不会更改。您添加了多个连接到该状态的工作表(每行一个),因此切换一个状态会激活所有工作表,这会导致不可预知的行为。你需要一张工作表和一个选定的项目,无论是按索引还是直接按项目-这是按偏好。哦,好的,我现在明白了。我会试着在这个基础上调整一切。谢谢如果您有一个自定义对象而不是字符串,请阅读本文。如果Asperi的答案对您有效,您可以将其标记为“已接受”。
var movies = ["Harry potter", "Mad Max", "Oblivion", "Memento"]
var body: some View {
    NavigationView {
        List {
            ForEach(0 ..< movies.count) { movie in
                HStack {
                    Text(self.movies[movie])
                    Image(systemName: "heart")
                }
                    .onTapGesture {
                        self.selectedMovie = movie
                }
            }
        }
        .sheet(item: self.$selectedMovie) {
            Text(self.movies[$0])

            // My addition here: a "Done" button that dismisses the sheet

            Button {
                selectedMovie = nil
            } label: {
                Text("Done")
            }

        }
    }
}