我的環境: 下面的代碼是用我公司 iPad 上的 swift Playgrounds 4 撰寫的。
專案目標: 我正在努力改進我學校的課堂管理工具,它基本上是一個紙質交通燈,每個學生都有一個衣夾。我想要一個應用程式,其中我所有的 28 名學生每個都由一個按鈕表示。這些按鈕應該在點擊 4 次時從綠色變為黃色,如果點擊三次則變為紅色。作為一個不錯的功能,按鈕標簽(又名警告)的總數應該顯示在按鈕上。此外,按鈕的結構應該有意義(比如我學生的表格;7 x 4 網格)。
到目前為止我的進步: 我寫了一個類(學生),并創建了該類的實體來代表我最喜歡的四個學生。我將它們打包成一個陣列(學生),以便為每個人輕松創建一個按鈕。在這個類中,“狀態”是學生被警告的次數(按鈕被點擊),“顏色”應該是相應按鈕的顏色。
在撰寫本文時,我需要一個變數 (col) 來處理顏色。我認為這是不必要的,但沒有讓顏色變化以不同的方式作業。
在網格中構建后,我為陣列中的每個元素(學生)創建了一個按鈕。在 buttonPress 上,相應學生的狀態和顏色會更新,并且(出于我未知的原因) col 也會更新。
然后按鈕的標簽會顯示相應學生的姓名、狀態和顏色……還是這樣?
我在這一點上 的問題:狀態(如按鈕上顯示的)僅在顏色更改時更新,并且當它更改所有按鈕的顏色時,而不僅僅是一個按鈕。我希望按鈕可以單獨更改顏色,并且每次按下按鈕時標簽都會更新。遺憾的是,我還沒有找到這樣做的正確語法。
我的問題:
如何在班級中設定默認顏色(綠色)?如何說服我的按鈕單獨更改顏色?如何讓我的標簽在 buttonPress 上更新?
提前致謝!
代碼
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)
}
}
uj5u.com熱心網友回復:
這里有幾個問題。首先是在 SwiftUI 中,通常你希望你的模型是 a struct,因為 SwiftUI 視圖可以很好地回應值型別的變化(比如 a struct)開箱即用。
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)
請注意,我還稍微更改了您的代碼以使用大寫型別名稱和小寫變數名稱的 Swift 約定。
接下來,由于您嘗試更改Students 上的屬性,因此您需要用@State陣列來表示它們。然后,通過ForEach在行中使用新的元素系結語法(參見$字符),您可以獲得對每個Student可以修改的參考。
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)
}
}
uj5u.com熱心網友回復:
我在您的請求中確定了 2 個問題,它們是您的問題的關鍵。
- 如何在班級中設定默認顏色(綠色)?
只需在類定義中創建一個默認值。將現有init()的類替換為:
public init(first: String, last: String, color: Color = .green) // Default value, you can even omit the colour in your initializer
- 如何說服我的按鈕單獨更改顏色?
首先,您的視圖有一個變數,該變數col在整個視圖中保留相同的值。那是按鈕的顏色。只需將其洗掉并使用每個學生的顏色:
.foregroundColor(student.color)
編輯
其次,students是一個結構陣列,它們不會發布更改。一種解決方法(由于 SwiftUI 的優勢也由 Apple 推廣)是創建一個額外的視圖,該視圖將在每次單個學生更改時更改狀態。
因此,創建另一個名為“StudentButton”的視圖,在該視圖中,您可以擁有@State單個學生的屬性。
這是我測驗和作業的代碼(我已經修改了一些布局,但您可以根據需要設定視圖):
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)
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/434338.html
