Изменение значения только что нажатого объекта в каждом

#foreach #swiftui

Вопрос:

Когда я нажимаю на ячейку вверху, я хочу, чтобы на этом объекте отображался только текст «Нажал». Почему я вижу этот текст в других ячейках? Как я могу решить эту проблему?

введите описание изображения здесь

CellView

 struct CellView: View {
    @Binding var text: String
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 30)
                .foregroundColor(Color(UIColor.secondarySystemBackground))
                .frame(width: 300, height: 100)
            Text(text)
        }
    }
}
 

Представление содержимого

 struct ContentView: View {
    @State var text: String = ""
    var body: some View {
        VStack {
            ForEach(0 ..< 5) { item in
                
                Button(action: {
                    self.text = "Clicked"
                }) {
                    CellView(text: $text) 
                }
            }
        }
    }
}
 

Ответ №1:

Вы обновляете одну строку text , которая используется для всех ячеек. Когда он изменится, все ячейки будут обновлены этой единственной строкой. Вот несколько вариантов:

Вы можете сделать ячейку ответственной за хранение и обновление своего собственного состояния:

 struct CellView: View {
    @State var text: String = ""

    var body: some View {
        Button(action: {
            self.text = "Clicked"
        }) {
            ZStack {
                RoundedRectangle(cornerRadius: 30)
                    .foregroundColor(Color(UIColor.secondarySystemBackground))
                    .frame(width: 300, height: 100)
                Text(text)
            }
        }
    }
}

struct CellClickContentView: View {
    var body: some View {
        VStack {
            ForEach(0 ..< 5) { item in
                CellView()
            }
        }
    }
}
 

или вы могли бы каким-то образом сохранить состояние для каждой ячейки в родительском представлении:

 class CellState: ObservableObject, Identifiable {
    var id = UUID()
    @Published var text = ""
}

struct CellView: View {
    @ObservedObject var state: CellState

    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 30)
                .foregroundColor(Color(UIColor.secondarySystemBackground))
                .frame(width: 300, height: 100)
            Text(state.text)
        }
    }
}

struct CellClickContentView: View {
    @State var states: [CellState] = (0..<5).map { _ in CellState() }

    var body: some View {
        VStack {
            ForEach(states) { state in
                Button(action: {
                    state.text = "Clicked"
                }) {
                    CellView(state: state)
                }
            }
        }
    }
}
 

Ответ №2:

Вы видите текст в других ячейках, потому что это то, что вы отображаете во всех ячейках. Попробуйте что-нибудь вроде этого:

 struct ContentView: View {
    @State var text: String = ""
    @State var selection: Int?
    
    var body: some View {
        VStack {
            ForEach(0 ..< 5) { item in
                Button(action: {
                    selection = item
                    text = "Clicked"
                }) {
                    if selection == item {
                        CellView(text: $text)
                    } else {
                        CellView(text: .constant(""))
                    }
                }
            }
        }
    }
}