#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(""))
}
}
}
}
}
}