我正在为IOS开发应用程序,我是第一次使用SwiftUI,只是一个初学者。问题是,我试图通过使用ForEach Identifiable按钮单击来更改Text((的值。一切都很好,但这是我唯一不能做的事情,也不能在互联网上为自己找到答案。
这是应用的观点
这是我的代码
import SwiftUI
private struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {}
}
public struct SemaphoreFlags: View {
@State private var headerHeight = CGSize()
public var body: some View {
ZStack{
Image("background")
.resizable()
.scaledToFill()
.frame(maxWidth: UIScreen.screenWidth, maxHeight: UIScreen.screenHeight )
.edgesIgnoringSafeArea(.bottom)
VStack{
Image("header_inv")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: UIScreen.screenWidth ,alignment: .top)
.opacity(0.0)
.readSize {
height in headerHeight = height
}.padding(.bottom, 16)
Text("HEADER TEXT")
.foregroundColor(.white)
.font(.system(size: 24))
.fontWeight(.medium)
.frame(width: UIScreen.screenWidth - 25, height: UIScreen.screenWidth / 6, alignment: .center)
.background(Color(red: 0.29, green: 0.67, blue: 0.88))
.padding(.bottom, 4.0)
ScrollView{
Text(NSLocalizedString("BeaufortScale_Description", comment: "BeaufortScale_Description"))
.font(.system(size: 20))
.multilineTextAlignment(.center)
.background(Color.white)
.padding(.horizontal,8)
.foregroundColor(.black)
.frame(width: .infinity, height: .infinity)
}
Image("blank")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: UIScreen.screenWidth - 25, height: UIScreen.screenWidth / 2, alignment: .center)
Text("BottomLETTER")
.font(.system(size: UIScreen.screenWidth/6))
.fontWeight(.medium)
.multilineTextAlignment(.center)
.foregroundColor(Color(red: 0.09, green: 0.30, blue: 0.47))
.frame(width: UIScreen.screenWidth, height: .infinity, alignment: .center)
Spacer()
ScrollView(.horizontal, showsIndicators: false){
HStack{
ForEach(semaphoreButtonPropsData) { item in
semaphoreFlagsButton(SemaphoreButtonProps: item)
}
}
}.clipped().edgesIgnoringSafeArea(.bottom).padding(.vertical)
}.frame(width: .infinity, height: .infinity)
Image("header")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: UIScreen.screenWidth, maxHeight: UIScreen.screenHeight ,alignment: .top)
VStack {
HStack {
Button (action: gotoMenu, label: {
Image("back")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 32, height: headerHeight.height)
.padding(.leading, 16.0)
})
Spacer()
}
Spacer()
}
}.background(Color(red: 0.09, green: 0.30, blue: 0.47).edgesIgnoringSafeArea(.all))
}
}
struct SemaphoreFlags_Previews: PreviewProvider {
static var previews: some View {
SemaphoreFlags()
}
}
struct semaphoreFlagsButton: View {
var SemaphoreButtonProps: semaphoreButtonProps
var body: some View {
Button(action:{
// ACTION TO CHANGE THE VALUES OF DESIGN
(HEADER TEXT, DESCRIPTION, IMAGE, BOTTOM LETTER)
}, label: {
Text(SemaphoreButtonProps.buttonLetter)
.font(.system(size: 26))
.fontWeight(.light)
.foregroundColor(Color.white)
.multilineTextAlignment(.leading)
.padding(.all, 4.0)
.foregroundColor(.white)
.frame(width: .infinity, height: 50, alignment: .center)
})
.frame(width: 100, height: 50 , alignment: .center)
.background(Color(red: 0.29, green: 0.67, blue: 0.88))
.cornerRadius(12)
.padding(.leading, 8)
}
}
struct semaphoreButtonProps: Identifiable {
var id = UUID()
var headerText: String
var description: String
var image: Image
var bottomLetter: String
var buttonLetter: String
}
let semaphoreButtonPropsData = [
semaphoreButtonProps(headerText: "About",
description: NSLocalizedString("BeaufortScale_Description", comment: "BeaufortScale_Description"),
image: Image("blank"),
bottomLetter: " ",
buttonLetter: "About"),
semaphoreButtonProps(headerText: "Alpha",
description: " ",
image: Image("a-alpha"),
bottomLetter: "A",
buttonLetter: "A"),
semaphoreButtonProps(headerText: "Bravo",
description: " ",
image: Image("b-bravo"),
bottomLetter: "B",
buttonLetter: "B")
]
非常感谢!
为了使数据数组是可变的,它应该存储在View
的@State
中。然后,您可以通过Binding
将其传递给您的孩子View
。
(我还调整了类型的大小写以符合Swift惯例,所以如果复制/粘贴,请小心在代码中反映这一点(
public struct SemaphoreFlags: View {
@State private var semaphoreButtonPropsData = [ //<-- Here
SemaphoreButtonProps(headerText: "About",
description: NSLocalizedString("BeaufortScale_Description", comment: "BeaufortScale_Description"),
image: Image("blank"),
bottomLetter: " ",
buttonLetter: "About"),
SemaphoreButtonProps(headerText: "Alpha",
description: " ",
image: Image("a-alpha"),
bottomLetter: "A",
buttonLetter: "A"),
SemaphoreButtonProps(headerText: "Bravo",
description: " ",
image: Image("b-bravo"),
bottomLetter: "B",
buttonLetter: "B")
]
public var body: some View {
ScrollView(.horizontal, showsIndicators: false){
HStack{
ForEach($semaphoreButtonPropsData) { $item in //<-- Here
SemaphoreFlagsButton(semaphoreButtonProps: $item) //<-- Here
}
}
}
}
}
struct SemaphoreFlagsButton: View {
@Binding var semaphoreButtonProps: SemaphoreButtonProps //<-- Here
var body: some View {
Button(action:{
semaphoreButtonProps.buttonLetter = "(Date())" //<-- Here
}, label: {
Text(semaphoreButtonProps.buttonLetter)
})
.frame(width: 100, height: 50 , alignment: .center)
.background(Color(red: 0.29, green: 0.67, blue: 0.88))
.cornerRadius(12)
.padding(.leading, 8)
}
}
struct SemaphoreButtonProps: Identifiable { //<-- Here
var id = UUID()
var headerText: String
var description: String
var image: Image
var bottomLetter: String
var buttonLetter: String
}
更新,基于询问者的新信息:
public struct SemaphoreFlags: View {
@State private var headerText : String = "HEADER TEXT"
@State private var semaphoreButtonPropsData = [ //<-- Here
SemaphoreButtonProps(headerText: "About",
description: NSLocalizedString("BeaufortScale_Description", comment: "BeaufortScale_Description"),
image: Image("blank"),
bottomLetter: " ",
buttonLetter: "About"),
SemaphoreButtonProps(headerText: "Alpha",
description: " ",
image: Image("a-alpha"),
bottomLetter: "A",
buttonLetter: "A"),
SemaphoreButtonProps(headerText: "Bravo",
description: " ",
image: Image("b-bravo"),
bottomLetter: "B",
buttonLetter: "B")
]
public var body: some View {
Text(headerText)
ScrollView(.horizontal, showsIndicators: false){
HStack{
ForEach(semaphoreButtonPropsData) { item in //<-- Here
SemaphoreFlagsButton(semaphoreButtonProps: item, headerText: $headerText) //<-- Here
}
}
}
}
}
struct SemaphoreFlagsButton: View {
var semaphoreButtonProps: SemaphoreButtonProps
@Binding var headerText : String
var body: some View {
Button(action:{
headerText = semaphoreButtonProps.headerText
}, label: {
Text(semaphoreButtonProps.buttonLetter)
})
.frame(width: 100, height: 50 , alignment: .center)
.background(Color(red: 0.29, green: 0.67, blue: 0.88))
.cornerRadius(12)
.padding(.leading, 8)
}
}
struct SemaphoreButtonProps: Identifiable { //<-- Here
var id = UUID()
var headerText: String
var description: String
var image: Image
var bottomLetter: String
var buttonLetter: String
}
或者,一个存储所选项目ID的选项:
public struct SemaphoreFlags: View {
@State private var selectedSemaphore : UUID? = nil
@State private var semaphoreButtonPropsData = [ //<-- Here
SemaphoreButtonProps(headerText: "About",
description: NSLocalizedString("BeaufortScale_Description", comment: "BeaufortScale_Description"),
image: Image("blank"),
bottomLetter: " ",
buttonLetter: "About"),
SemaphoreButtonProps(headerText: "Alpha",
description: " ",
image: Image("a-alpha"),
bottomLetter: "A",
buttonLetter: "A"),
SemaphoreButtonProps(headerText: "Bravo",
description: " ",
image: Image("b-bravo"),
bottomLetter: "B",
buttonLetter: "B")
]
public var body: some View {
if let selected = semaphoreButtonPropsData.first(where: { $0.id == selectedSemaphore }) {
Text(selected.headerText)
}
ScrollView(.horizontal, showsIndicators: false){
HStack{
ForEach(semaphoreButtonPropsData) { item in //<-- Here
SemaphoreFlagsButton(semaphoreButtonProps: item, selectedSemaphore: $selectedSemaphore) //<-- Here
}
}
}
}
}
struct SemaphoreFlagsButton: View {
var semaphoreButtonProps: SemaphoreButtonProps
@Binding var selectedSemaphore : UUID?
var body: some View {
Button(action:{
selectedSemaphore = semaphoreButtonProps.id
}, label: {
Text(semaphoreButtonProps.buttonLetter)
})
.frame(width: 100, height: 50 , alignment: .center)
.background(Color(red: 0.29, green: 0.67, blue: 0.88))
.cornerRadius(12)
.padding(.leading, 8)
}
}