Tunko Development Diary

SwiftUI) VideoPlayer navigationBarHidden not working [🐛] 본문

Development/SwiftUI

SwiftUI) VideoPlayer navigationBarHidden not working [🐛]

Tunko 2022. 9. 21. 23:45

정말 오랜만에 하는 버그에 대한 글입니다.

VideoPlayer를 생성을하면 Hidden을 한 NavigationBar이 보이는 현상이 있습니다. 

자세히 보시면 StatusBar에 시간 베터리 표시가 사라져있는것을 확인할 수 있습니다. 

하지만 특정 조건을 만족해서 발생하는 특수한 버그이기에 글을 남깁니다. ㅠㅡㅠ

 

아주 정확한 원인은 모르지만…

버그가 재현되는 상황을 정리하는것도 우습지만 저와 같은 일이 발생하지 않길 바라며 공유합니다.

 

NavigationView

      → NaigationLink → A

             A → NavigationLink → B

                      B 뷰에서 VideoPlayer 사용시 발생!

 

.navigationBarHidden(true) 을 통해서 네비게이션을 안보이게 설정해 줍니다.

해당 상황을 재현한 코드 입니다.

struct VideoNavi: View {
    var body: some View {
        NavigationLink {
            VideoPlayerTest()
        } label: {
            Text("VideoPlayer")
        }
    }
}
struct VideoPlayerTest: View {
    
    @State var player = AVPlayer()
    @State var toggle : Bool = true 
    
    var videoUrl: String = "비디오URL"
    
    var body: some View {
        VStack{
            Button {
                toggle.toggle()
            } label: {
                Text("toggle")
            }
            
            toggle ? AnyView(videoView()) : AnyView(EmptyView())
        }
        .navigationBarHidden(true)
    }
}

extension VideoPlayerTest {
    
    @ViewBuilder
    func videoView() -> some View {
        VStack{
            HStack{
                Spacer()
                VideoPlayer(player: player)
                    .onAppear() {
                        player = AVPlayer(url: URL(string: videoUrl)!)
                    }
                Spacer()
            }
        }
    }
}

간단하게 toggle 버튼을 통해서 VideoPlayer 뷰가 보이고 안보이게 하는 코드입니다.

네비게이션이 추가로 등장하게 됩니다.

따라서 위 버그를 수정이 아닌 회피…를 하기위해

UIKit에 있는 AVPlayerViewController를 사용할 수 밖에 없었습니다.

더 좋은 방법을 찾거나 알게 되면 추가로 해결방법을 게시하겠습니다. ㅠㅡㅠ

struct CustomPlayer: UIViewControllerRepresentable {
    let urlString: String
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<CustomPlayer>) -> AVPlayerViewController {
        let controller = AVPlayerViewController()
        let player = AVPlayer(url: URL(string: urlString)!)
        controller.player = player
        player.play()
        return controller
    }
    
    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<CustomPlayer>) { }
}

CustomPlayer 를 선언해주고 urlString을 넘겨 사용해 줍니다.

struct VideoPlayerTest: View {
    
    @State var player = AVPlayer()
    @State var toggle : Bool = true//false
    
    var videoUrl: String = "비디오URL"
    
    var body: some View {
        VStack{
            Button {
                toggle.toggle()
            } label: {
                Text("toggle")
            }
            
            toggle ? AnyView(CustomPlayer(urlString: videoUrl)) : AnyView(EmptyView())
        }
        .navigationBarHidden(true)
    }
}

 

나름대로의 대체 방법으로 문제를 해결했습니다.

마지막 TMI

플레이어에서 제공하는 인터페이스에 차이가 있습니다.

SwiftUI : VideoPlayer

UIKit: AVPlayerViewController

동영상 위에 버튼을 커스텀해서 배치하게 되는 경우 참고하세요. 이상입니다 😀

반응형
Comments