Home > Blockchain >  Unable to rerender a View using onAppear
Unable to rerender a View using onAppear

Time:09-16

I am trying to show a pause button if a sound file is playing, i have a uniform source of truth for the sound file, which i can access via ViewModel, now all works well on other Views, but on parent View where all navigation links are, when i go back to it using the back button from other Views, the miniplayer that shows pause disappears...

So i decided that on the .onAppear of NavigationView or text view of parent View i will implement the logic that can detect if a sound file is playing and if so , show a button at bottom to pause the sound file.

Now i can use print and it shows correct value on onAppear in terms of sound file playing or not, but the moment i try to use HStack or any other View to be added i get warning -

Result of 'HStack<Content>' initializer is unused

Now if i decide to use State then also i get similar warning, how can i make the View rerender onAppear, or is that not possible, if that is the case from where i can implement this logic, thanks ....

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()
                    }

                }
            }
        }

        
    }
    
}

I had also tried

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

but got Result of 'HStack<Content>' initializer is unused

CodePudding user response:

I will give easy and basic template for working with swift's ui states. You can refer it and add your views or navigation link.

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()
      }
   }
}
struct YourViewModel: ObservableObject {
   @Published var isPlaying = false
   
   func transform() {
      fetchStatus()
   }

   func fetchStatus() {
      isPlaying = true
   }

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