SwiftUI的Button动作内调用HymnLyrics报初始化结果未使用错误如何解决
问题原因分析
HymnLyrics是SwiftUI视图结构体,只有被放入视图渲染树才会生效,Button的action闭包是纯逻辑执行回调,不会解析渲染内部写入的视图,你在此处直接初始化HymnLyrics仅创建了实例但没有任何使用场景,因此编译器触发「初始化结果未使用」报错。NavigationLink的destination参数本身要求传入视图类型,你把HymnLyrics写在此处时,系统会自动将其作为跳转目标加入渲染栈,因此不会报错。
解决方案
不需要使用NavigationLink的情况下,可以通过状态控制视图展示的方式实现需求,操作步骤如下:
- 首先在你的
TapToggle可观察对象中新增存储选中歌词的属性:
class TapToggle: ObservableObject { // 原有其他属性保留 @Published var isHymnTapped = false // 新增属性存储要展示的歌词数据 @Published var selectedHymnLyrics: [Lyric]? }
方案1:sheet弹窗展示HymnLyrics
在原有视图外层添加sheet修饰符,根据状态控制弹窗显示:
import SwiftUI struct ContentView: View { @EnvironmentObject var tappingSwitches: TapToggle let zoLyrics: [Lyric] = LyricList.hymnLa.sorted { lhs, rhs in return lhs.zoTitle < rhs.zoTitle } var body: some View { ScrollView { ForEach(zoLyrics, id: \.id) { zoLyric in VStack { Button(action: { // 存储要展示的歌词,触发状态变更 self.tappingSwitches.selectedHymnLyrics = LyricList.hymnLa self.tappingSwitches.isHymnTapped.toggle() }, label: { HStack { Text(zoLyric.zoTitle) .foregroundColor(Color("bTextColor")) .lineLimit(1) .minimumScaleFactor(0.5) Spacer() Text("\(zoLyric.number)") .foregroundColor(Color("bTextColor")) } }) } .frame(maxWidth: .infinity, alignment: .leading) .padding([.leading, .bottom, .trailing]) } } // 新增sheet修饰符,状态为true时自动弹出歌词页 .sheet(isPresented: $tappingSwitches.isHymnTapped) { if let lyrics = tappingSwitches.selectedHymnLyrics { HymnLyrics(lyrics: lyrics) } } } }
方案2:条件渲染切换当前页展示内容
如果不需要弹窗,要在当前页面直接切换展示,可通过条件判断实现:
import SwiftUI struct ContentView: View { @EnvironmentObject var tappingSwitches: TapToggle let zoLyrics: [Lyric] = LyricList.hymnLa.sorted { lhs, rhs in return lhs.zoTitle < rhs.zoTitle } var body: some View { // 条件判断展示内容 if tappingSwitches.isHymnTapped, let lyrics = tappingSwitches.selectedHymnLyrics { HymnLyrics(lyrics: lyrics) } else { ScrollView { ForEach(zoLyrics, id: \.id) { zoLyric in VStack { Button(action: { self.tappingSwitches.selectedHymnLyrics = LyricList.hymnLa self.tappingSwitches.isHymnTapped.toggle() }, label: { HStack { Text(zoLyric.zoTitle) .foregroundColor(Color("bTextColor")) .lineLimit(1) .minimumScaleFactor(0.5) Spacer() Text("\(zoLyric.number)") .foregroundColor(Color("bTextColor")) } }) } .frame(maxWidth: .infinity, alignment: .leading) .padding([.leading, .bottom, .trailing]) } } } } }
内容的提问来源于stack exchange,提问作者Lian
相关产品推荐
相关产品推荐

