videoplayer inswiftui view not using fullscreen

81 views Asked by At

I am building an app with a feed of videos which looks like TikTok or Facebook Reels, in a sense that I want one post using fullscreen so the video use the entire space.

It seems not working, and only the header is displayed as shown below:

enter image description here

but is should look like this:

enter image description here

I do not see why in the emulator, the videos are not shown but only the header when the Xcode preview works.

Below is the code I am using:

struct ClassesFeedView: View {
    var body: some View {
        ScrollView {
            LazyVStack(spacing: 32) {
                ForEach(ClassPost.MOCKED_CLASSES) { post in
                    ClassCellView(item: post)
                }
            }
        }
    }
}

The ClassCellView is describe as below:

struct ClassCellView: View {
    @State var item: ClassPost
    @State var player = AVPlayer()

    
    var body: some View {
        VStack() {
            ZStack() {
                VideoPlayer(player: player) {
                    VStack() {
                        HStack(){
                            if let imageUrl = item.user?.profileImageUrl {
                                Image(imageUrl)
                                    .resizable()
                                    .scaledToFill()
                                    .frame(width: 40, height: 40)
                                    .clipShape(Circle())
                                
                            } else {
                                Image(systemName: "person.crop.circle")
                                    .resizable()
                                    .frame(width: 40, height: 40)
                                    .foregroundColor(.black.opacity(0.7))
                            }
                            VStack(alignment: .leading) {
                                Text(item.user?.username ?? "")
                                Text(item.user?.displayName ?? "")
                            }
                            .font(.footnote)
                            Spacer()
                        }
                        .padding(.horizontal)
                        .background(FoodlooseColors.cOrange)
                        Spacer()
                    }
                }
                .onAppear {
                    if player.currentItem == nil {
                        let videoItem = AVPlayerItem(url: Bundle.main.url(forResource: item.videoUrl, withExtension: "mp4")!)
                        player.replaceCurrentItem(with: videoItem)
                    }
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
                        player.play()
                    })
                }
            }
        }
    }
}

The ClassPost.MOCKED_CLASSES is just a list of elements containing the data required.

Any idea how to force the video to be full screen? I may modify the header later, but I am trying first to at least display the video as I want to.

Thanks

1

There are 1 answers

0
Pierre Janineh On
  • First, remove the parent VStack and its ZStack child in your ClassCellView.

    They are really redundant.

  • Second, you'll need to add a GeometryReader as a parent in the ClassesFeedView to set the ClassCellViews' frame.

struct ClassesFeedView: View {
    var body: some View {
        GeometryReader { geometry in
            ScrollView {
                LazyVStack(spacing: 32) {
                    ForEach(ClassPost.MOCKED_CLASSES) { post in
                        ClassCellView(item: post)
                            .frame(width: geometry.size.width,
                                   height: geometry.size.height)
                    }
                }
            }
        }
    }
}

If you need to display every video on the whole screen ignoring safe area you'd add .ignoresSafeArea(.all) to the GeometryReader.