I'm using SWIFTUI for IOS16 development. I have a view with a navigation link that used to work great, but now that I have added an onTapGesture, stopped working. This is my code:
import SwiftUI
import AVKit
struct SpecialVideo6: View {
let videoURL = Bundle.main.url(forResource: "war", withExtension: "mp4")!
@Binding var path: NavigationPath
var player: AVPlayer {
let player = AVPlayer(url: videoURL)
player.play()
return player
}
var body: some View {
ZStack {
Color(.black).ignoresSafeArea()
VideoPlayer(player: player)
.scaledToFill()
HStack{
Spacer()
VStack {
NavigationLink("", value: Route.linkSpecials).buttonStyle(BtnVid(vidIcon: "share"))
NavigationLink("", value: Route.linkSpecials).buttonStyle(BtnVid(vidIcon: "hearth"))
Spacer()
}.frame(maxHeight: 330).padding(.trailing, 16).padding(.top, 50)
}
VStack {
Spacer()
NavigationLink("Bet", value: Route.linkBetBlackOps).buttonStyle(BtnFull2(player: player))
}.frame(maxHeight: 330)
}
.navigationBarBackButtonHidden()
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
path.removeLast()
} label: {
HStack(spacing: 0) {
Spacer()
Image("x")
}.padding(.top, 25)
}
}
}
}
}
struct BtnFull2: ButtonStyle {
let player: AVPlayer? // Add a parameter to store the AVPlayer instance
func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.custom("Bebas Neue", size: 24))
.foregroundColor(.white)
.frame(width: 98, height: 50)
.background(LinearGradient(gradient: Gradient(colors: [Color("lb"), Color("rb")]),startPoint: .top, endPoint: .bottom))
.cornerRadius(10)
.onTapGesture {
player?.pause() // Use the player instance passed as a parameter
}
}
}
Can anyone tell me how to fix it? What I am trying to do is to stop the video from playing when going on that link, right now the video sound keep on playing.
Your player
variable is a computed property, this will be different every time you access it.
Try modifying your code like this:
let player: AVPlayer = {
let player = AVPlayer(url: videoURL)
player.play()
return player
}()
This is just a temporal solution though, there is still the risk for the player
to be generated again every time your View
changes, due to SwiftUI Views life-cycle (they are value types, not reference types).
A longer term solution would be to abstract the player from the view itself, on an ObservableObject for example.