【问题标题】:Unable to rerender a View using onAppear无法使用 onAppear 重新渲染视图
【发布时间】:2021-09-17 08:38:56
【问题描述】:

如果声音文件正在播放,我试图显示一个暂停按钮,我有一个统一的声音文件来源,我可以通过 ViewModel 访问它,现在在其他视图上一切正常,但在父视图上所有导航链接都是,当我使用其他视图的后退按钮返回它时,显示暂停的迷你播放器会消失......

所以我决定在 NavigationView 的 .onAppear 或父 View 的文本视图上实现可以检测声音文件是否正在播放的逻辑,如果是,则在底部显示一个按钮以暂停声音文件。

现在我可以使用 print 并且它在 onAppear 上显示正确的值是否播放声音文件,但是当我尝试使用 HStack 或要添加的任何其他视图时我收到警告 -

Result of 'HStack<Content>' initializer is unused

现在,如果我决定使用 State,那么我也会收到类似的警告,我怎样才能让 View 在 Appear 上重新渲染,或者那是不可能的,如果是这样的话,我可以从哪里实现这个逻辑,谢谢....

import Foundation
import SwiftUI

struct HomePageTabView: View {
    @Binding var songLVM: SongListVM
    @State var miniBar: Bool = false
    
    init(songLVM: Binding<SongListVM>){
        
        self._songLVM = songLVM
        
        UITableView.appearance().backgroundColor = UIColor(.white)
        
        
    }
    
    
    
    var body: some View {
        
        
        NavigationView {
            List {
                //Artists
                NavigationLink(
                    
                    destination: ArtistList(songLVM: $songLVM))
                {
                    HStack {
                        Image(systemName: "music.mic")
                        Text("Artists")
                    }
                    
                    
                }
                
                //Albums
                NavigationLink(
                    destination: Text("Albums"))
                {
                    HStack {
                        Image(systemName: "music.note.list")
                        Text("Albums")
                    }
                    
                }
                //Collections
                
                NavigationLink(
                    //destination: ArtistView())
                    destination: ArtistViewMain( songLVM: $songLVM))
                {
                    HStack {
                        Image(systemName: "music.quarternote.3")
                        Text("Collections")
                    }
                    
                }
                
                //About Us
                
                NavigationLink(
                    destination: Text("About Us"))
                {
                    HStack {
                        Image(systemName: "music.note.house.fill")
                        Text("About Us")
                    }
                    
                }
                
                //Contact Us
                NavigationLink(
                    
                    destination: ArtistView())
                {
                    HStack {
                        Image(systemName: "phone.circle")
                        Text("Contact Us")
                        
                        
                    }
                    
                    
                }
                
                
                
                
                
                
            }
            
            
        }
        .onAppear {
            if(songLVM.audioPlayer?.isPlaying != nil){
                HStack {

                    Button("Stop") {
                        songLVM.audioPlayer?.stop()
                    }

                }
            }
        }

        
    }
    
}

我也试过

.onAppear{
            miniBar.toggle()
            if(miniBar == true){
                HStack {
                    Text("Stop")
                }
            }
        }

但得到Result of 'HStack&lt;Content&gt;' initializer is unused

【问题讨论】:

  • .onAppear 不是放视图的地方,只保留miniBar.toggle() 并将其他内容移至{} 范围上方
  • 是的,我在想可能是这种情况,但是如果我在 onAppear 中检查真相,那么根据该真相从那里我可以调用结构吗?谢谢

标签: swift swiftui


【解决方案1】:

我将为使用 swift 的 ui 状态提供简单且基本的模板。 您可以参考它并添加您的视图或导航链接。

struct YourView: View {
   /// If you want to pass it on init, use @ObservedObject instead
   /// https://www.hackingwithswift.com/quick-start/swiftui/whats-the-difference-between-observedobject-state-and-environmentobject
   @StateObject var viewModel = YourViewModel()

   var body: some View {
      NavigationView {
         VStack {
             if viewModel.isPlaying {
                 Button {
                     viewModel.stop()
                 } label: {
                     Text("Stop")
                 }
             } else {
                 Button {
                     viewModel.start()
                 } label: {
                     Text("Start")
                 }
             }

             Toggle(isOn: $viewModel.isPlaying) {
                 Text("isPlaying")
             }
         }
      }
      .onAppear {
          viewModel.transform()
      }
   }
}
class YourViewModel: ObservableObject {
   @Published var isPlaying = false
   
   func transform() {
      fetchStatus()
   }

   func fetchStatus() {
      isPlaying = true
   }

   func stop() { isPlaying = false }
   func start() { isPlaying = true }
}

【讨论】:

  • 它也有效,我理解你的观点并在 Text 上添加了 .onAppear 并且效果很好,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多