You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI的Button动作内调用HymnLyrics报初始化结果未使用错误如何解决

问题原因分析
  • HymnLyrics是SwiftUI视图结构体,只有被放入视图渲染树才会生效,Button的action闭包是纯逻辑执行回调,不会解析渲染内部写入的视图,你在此处直接初始化HymnLyrics仅创建了实例但没有任何使用场景,因此编译器触发「初始化结果未使用」报错。
  • NavigationLink的destination参数本身要求传入视图类型,你把HymnLyrics写在此处时,系统会自动将其作为跳转目标加入渲染栈,因此不会报错。
解决方案

不需要使用NavigationLink的情况下,可以通过状态控制视图展示的方式实现需求,操作步骤如下:

  1. 首先在你的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 12:48:02