SwiftUI中如何初始将枚举allCases值填充至空sportsArray数组
解决SwiftUI中默认全选运动项的问题
问题说明
已实现按钮点击切换选中状态,可将运动项添加/移除至sportsArray数组,但无法实现当sportsArray初始为空时,自动把枚举HelperIntervalsIcu.icuActivityType.allCases的所有值初始化到数组中。直接在视图代码里添加初始化逻辑时,Xcode持续报错type() cannot conform to View。
尝试的错误代码
if sportsArray.isEmpty { HelperIntervalsIcu.icuActivityType.allCases.forEach { sportsArray.append($0.rawvalue) // 注意此处rawvalue拼写错误,应为rawValue } }
相关完整代码
struct selectSports: View { @State private var sportsArray = [String]() var body: some View { ScrollView(.horizontal, showsIndicators: false) { HStack { ForEach(Array(HelperIntervalsIcu.icuActivityType.allCases), id:\.rawValue) { sport in Button(action: { addSports(sport: sport.rawValue) }) { HStack { Image(getSportsIcon(sport: sport.rawValue)) .selectedSportsImageStyle(sportsArray: sportsArray, sport: sport.rawValue) Text(sport.rawValue) } } .buttonStyle(SelectedSportButtonStyle(sportsArray: sportsArray, sport: sport.rawValue)) } } } } struct SelectedSportButtonStyle: ButtonStyle { var sportsArray: [String] var sport: String var selectedSport : Bool { sportsArray.contains(sport) } func makeBody(configuration: Self.Configuration) -> some View { configuration.label .font(selectedSport ? Font.subheadline.bold() : Font.subheadline) .aspectRatio(contentMode: .fit) .foregroundColor(selectedSport ? Color.orange : Color(UIColor.label)) .padding([.leading, .trailing], 15) .padding([.top, .bottom],10) .overlay( RoundedRectangle(cornerRadius: 5.0) .stroke(lineWidth: 2.0) .foregroundColor(selectedSport ? Color.orange : Color.gray) ) .offset(x: 10, y: 0) } } func addSports(sport: String) { if let index = sportsArray.firstIndex(of: sport) { sportsArray.remove(at: index) } else { sportsArray.append(sport) } print("Selected Sports:\(sportsArray)") } }
需求
将当前“初始空数组无选中项”的逻辑,改为默认全选所有运动项。
解决方案
方案1:直接初始化@State变量(推荐)
SwiftUI的@State变量可以在声明时直接赋值,不需要在视图的body中处理。修改sportsArray的初始化代码,直接将所有枚举的rawValue填充进去:
@State private var sportsArray = HelperIntervalsIcu.icuActivityType.allCases.map { $0.rawValue }
这样视图加载时,数组就已经包含所有运动项,默认全选。
方案2:利用视图生命周期方法初始化
如果需要保留“数组为空时才初始化”的逻辑,或者不想在声明时直接赋值,可以使用.onAppear修饰符,在视图首次出现时执行初始化:
ScrollView(.horizontal, showsIndicators: false) { // 原有HStack及按钮代码 } .onAppear { if sportsArray.isEmpty { // 修正rawValue的拼写错误 sportsArray = HelperIntervalsIcu.icuActivityType.allCases.map { $0.rawValue } } }
错误原因解释
之前的代码报错是因为SwiftUI的body是ViewBuilder,只能返回View类型的内容,不能直接在body中编写修改状态的逻辑代码(比如修改sportsArray的操作),这类副作用代码应该放在视图生命周期方法(如.onAppear)或者初始化代码中。
另外,你尝试的代码里还有一个拼写错误:$0.rawvalue应该改为$0.rawValue(大写V),这也是潜在的问题点。
内容的提问来源于stack exchange,提问作者app4g
相关产品推荐
相关产品推荐

