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

SwiftUI使用onAppear无法触发View重绘、不显示暂停按钮问题求助

问题根因

.onAppear 是 SwiftUI 提供的生命周期回调方法,仅用于执行状态变更、数据加载这类副作用逻辑,不能在其闭包内声明视图。你在闭包里创建的 HStack 没有被加入到当前页面的视图树中,因此会触发「初始化结果未使用」的警告。

正确实现步骤

你需要把迷你播放条的视图声明放在 body 的视图层级内,通过状态变量控制显隐,.onAppear 仅负责更新控制显隐的状态值即可。

修改后代码示例

import Foundation
import SwiftUI

struct HomePageTabView: View {
    @Binding var songLVM: SongListVM
    // 控制迷你播放条显隐的状态
    @State var showMiniPlayer: Bool = false
    
    init(songLVM: Binding<SongListVM>){
        self._songLVM = songLVM
        UITableView.appearance().backgroundColor = UIColor(.white)
    }
    
    var body: some View {
        // 外层套VStack,把导航栏和迷你播放条垂直排列
        VStack(spacing: 0) {
            NavigationView {
                List {
                    // 艺术家入口
                    NavigationLink(
                        destination: ArtistList(songLVM: $songLVM))
                    {
                        HStack {
                            Image(systemName: "music.mic")
                            Text("Artists")
                        }
                    }
                    
                    // 专辑入口
                    NavigationLink(
                        destination: Text("Albums"))
                    {
                        HStack {
                            Image(systemName: "music.note.list")
                            Text("Albums")
                        }
                    }
                    
                    // 收藏入口
                    NavigationLink(
                        destination: ArtistViewMain( songLVM: $songLVM))
                    {
                        HStack {
                            Image(systemName: "music.quarternote.3")
                            Text("Collections")
                        }
                    }
                    
                    // 关于我们入口
                    NavigationLink(
                        destination: Text("About Us"))
                    {
                        HStack {
                            Image(systemName: "music.note.house.fill")
                            Text("About Us")
                        }
                    }
                    
                    // 联系我们入口
                    NavigationLink(
                        destination: ArtistView())
                    {
                        HStack {
                            Image(systemName: "phone.circle")
                            Text("Contact Us")
                        }
                    }
                }
            }
            
            // 迷你播放条视图声明放在这里,通过状态控制显隐
            if showMiniPlayer {
                HStack {
                    Button("暂停") {
                        songLVM.audioPlayer?.pause()
                    }
                    .foregroundColor(.white)
                    .frame(maxWidth: .infinity, minHeight: 44)
                    .background(Color.blue)
                }
            }
        }
        .onAppear {
            // onAppear仅更新状态,触发视图自动重渲染
            showMiniPlayer = (songLVM.audioPlayer?.isPlaying ?? false)
        }
    }
}

更优化的方案

如果你的 SongListVM 中 audioPlayer 的播放状态是通过 @Published 修饰的响应式状态,可以直接在显隐判断中使用,无需额外的 @State 变量和 onAppear 回调,状态变更时视图会自动刷新:

// 无需额外定义showMiniPlayer状态和onAppear回调,直接判断ViewModel的播放状态即可
if songLVM.audioPlayer?.isPlaying ?? false {
    HStack {
        Button("暂停") {
            songLVM.audioPlayer?.pause()
        }
        .foregroundColor(.white)
        .frame(maxWidth: .infinity, minHeight: 44)
        .background(Color.blue)
    }
}

内容的提问来源于stack exchange,提问作者multiverse

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:27:02