Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

535
Views
Cambiar la etiqueta y el título del botón dinámicamente para los botones creados desde Array (en Swift)

Mi entorno: El siguiente código está escrito en Swift Playgrounds 4 en el iPad de mi empresa.

Objetivo del proyecto: Estoy tratando de mejorar la herramienta de gestión del aula de mi escuela, que es básicamente un semáforo de papel con una pinza para la ropa para cada alumno. Quiero una aplicación en la que todos mis 28 estudiantes estén representados por un botón cada uno. Se supone que esos botones cambian de verde a amarillo cuando se tocan 4 veces y a rojo si se tocan tres veces más. Como una característica agradable de tener, el número total de pestañas de botones ob (también conocidas como advertencias) debe mostrarse en los botones. Además, los botones deben estar estructurados de manera significativa (como las tablas de mis alumnos, una cuadrícula de 7 x 4).

Mi progreso hasta ahora: escribí una clase (estudiante) y creé instancias de esa clase para representar a cuatro de mis estudiantes favoritos. Los empaqueté en una matriz (estudiantes) para crear fácilmente un botón para cada uno de ellos. En esta clase, "estado" es la cantidad de veces que se ha advertido al estudiante (se ha tocado el botón) y se supone que "color" es el color del botón respectivo.

Al momento de escribir esto, necesito una variable (col) para el manejo del color. Creo que sería innecesario, pero no conseguí que el cambio de color funcionara de una manera diferente.

Después de estructurar en una cuadrícula, creo un botón para cada elemento de la matriz (estudiantes). Al presionar el botón, el estado y el color se actualizan para el estudiante respectivo y (por razones desconocidas para mí) el color también se actualiza.

La etiqueta del botón luego muestra el nombre, el estado y el color del estudiante respectivo... ¿o no?

Mis problemas en este punto: el estado (como se muestra en los botones) se actualiza solo cuando cambia el color y cuando lo hace, cambia el color de todos los botones y no solo de uno. Me gustaría que los botones cambien de color individualmente y que la etiqueta se actualice con cada pulsación de un botón. Lamentablemente, no he encontrado la sintaxis correcta para hacerlo.

Mis preguntas:

¿Cómo puedo establecer un color predeterminado (verde) dentro de mi clase? ¿Cómo persuado a mis botones para que cambien de color individualmente? ¿Cómo puedo hacer que mis etiquetas se actualicen en buttonPress?

¡Gracias por adelantado!

Código

 import SwiftUI public class student{ public var first: String public var last: String public var state: Int public var color: Color public init(first: String, last: String, color: Color){ self.first = first self.last = last state = Int() self.color = color } } var John = student(first: "John", last: "Lennon", color: .green) var Paul = student(first: "Paul", last: "McCartney", color: .green) var Georg = student(first: "Georg", last: "Harrison", color: .green) var Ringo = student(first: "Ringo", last: "Starr", color: .green) var students = [John, Paul, Georg, Ringo] struct ContentView: View { @State private var col = Color.green let columnLayout = Array(repeating: GridItem(), count: 7) var body: some View { NavigationView{ ScrollView{ LazyVGrid(columns: columnLayout){ ForEach(students, id: \.last) { student in Button{ student.state += 1 //print(student.state) if (student.state < 4) { student.color = .green } else if (student.state >= 7){ student.color = .red } else { student.color = .yellow } col = student.color //print(col) } label:{ ZStack{ RoundedRectangle(cornerRadius: 10, style: .continuous) .foregroundColor(col) .aspectRatio(2.0, contentMode: ContentMode.fit) Text("\(student.first) - \(student.state)") .foregroundColor(.black) //.font(.largeTitle) .scaledToFit() } } } } }.navigationTitle("Classroom Management") }.navigationViewStyle(.stack) } }
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Aquí hay un par de problemas. La primera es que en SwiftUI, por lo general desea que su modelo sea una struct , ya que las vistas de SwiftUI responden bien a los cambios en los tipos de valores (como una struct ) listos para usar.

 public struct Student { public var first: String public var last: String public var state: Int public var color: Color public init(first: String, last: String, color: Color){ self.first = first self.last = last state = Int() self.color = color } } var john = Student(first: "John", last: "Lennon", color: .green) var paul = Student(first: "Paul", last: "McCartney", color: .green) var georg = Student(first: "Georg", last: "Harrison", color: .green) var ringo = Student(first: "Ringo", last: "Starr", color: .green)

Tenga en cuenta que también he cambiado un poco su código para usar las convenciones de Swift de poner en mayúsculas los nombres de los tipos y poner en minúsculas los nombres de las variables.

A continuación, dado que está tratando de cambiar las propiedades de los Student , querrá representarlos con una matriz @State . Luego, al usar la nueva sintaxis de vinculación de elementos en la línea ForEach (consulte los caracteres $ ), puede obtener una referencia para cada Student que puede modificar.

 struct ContentView: View { @State private var students = [john, paul, georg, ringo] let columnLayout = Array(repeating: GridItem(), count: 7) var body: some View { NavigationView{ ScrollView{ LazyVGrid(columns: columnLayout){ ForEach($students, id: \.last) { $student in Button{ student.state += 1 if (student.state < 4) { student.color = .green } else if (student.state >= 7){ student.color = .red } else { student.color = .yellow } } label:{ ZStack{ RoundedRectangle(cornerRadius: 10, style: .continuous) .foregroundColor(student.color) .aspectRatio(2.0, contentMode: .fit) Text("\(student.first) - \(student.state)") .foregroundColor(.black) .scaledToFit() } } } } }.navigationTitle("Classroom Management") }.navigationViewStyle(.stack) } }
over 4 years ago · Santiago Trujillo Report

0

Hay 2 preguntas que he identificado en su solicitud que son la clave de su problema.

  1. ¿Cómo puedo establecer un color predeterminado (verde) dentro de mi clase?

Simplemente cree un valor predeterminado dentro de la definición de su clase. Reemplace el init() existente de su clase con:

 public init(first: String, last: String, color: Color = .green) // Default value, you can even omit the colour in your initializer
  1. ¿Cómo persuado a mis botones para que cambien de color individualmente?

Primero, su vista tiene una col variable que conserva el mismo valor en toda la vista. Ese es el color de tu botón. Simplemente elimínelo y use el color de cada estudiante:

 .foregroundColor(student.color)

Editar

En segundo lugar, students son una matriz de estructuras, no publicarán cambios. Una solución alternativa (promovida también por Apple debido a los beneficios de SwiftUI) es crear una vista adicional que cambiará el estado cada vez que cambie un solo estudiante.

Entonces, cree otra vista llamada "StudentButton", y dentro de esa vista puede tener la propiedad @State para el estudiante individual.

Aquí está el código que probé y funciona (modifiqué un poco el diseño, pero puede configurar su vista como desee):

 struct Example: View { @State private var students = [john, paul, georg, ringo] let columnLayout = Array(repeating: GridItem(), count: 4) var body: some View { NavigationView{ ScrollView{ LazyVGrid(columns: columnLayout){ ForEach(students, id: \.last) { student in // Call another view here StudentButton(student) } } }.navigationTitle("Classroom Management") }.navigationViewStyle(.stack) } } // Here's the other view struct StudentButton: View { // This is the state var of each single student @State private var student: Student init(_ student: Student) { self.student = student } var body: some View { Button{ student.state += 1 if (student.state < 4) { student.color = .green } else if (student.state >= 7){ student.color = .red } else { student.color = .yellow } } label:{ // I changed this just to visualize better, but just do as you please Text("\(student.first) - \(student.state)") .foregroundColor(.black) .padding() .background { RoundedRectangle(cornerRadius: 10, style: .continuous) .foregroundColor(student.color) .aspectRatio(2.0, contentMode: .fit) } } } }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!