>100 Views
December 25, 23
スライド概要
縦フリックのできる動画画面の簡単な実装方法 Mobile勉強会 Wantedly チームラボ Sansan #12 yoshitaka
yoshitaka iOS エンジニア コネヒト:出産育児系のQAアプリ ママリ 趣味:パデル
話すこと • 縦フリックのできる動画画面を実装する上で考えたこと • 実装例 • まとめ
要求 • 縦フリックで動画を見れるようにしたい • 画面をタップしたらコントローラーを表示したい • 画面の下部にシークバーを配置したい
実装する上で決めたこと • 新規画面なのでSwiftUIを使って実装する • 動画プレイヤーはAVPlayerを使う
縦のPagingができれば簡単に実装できそう🧐
TabViewにverticalPageは存在したが。。。 watchOS 10.0+のみ
縦フリックのできる動画画面の実装 ・・・・・ コンテンツ TabView TabView ・・・・・ コンテンツ コンテンツ ・・・・・ TabView
縦フリックのできる動画画面の実装 var body: some View { ZStack { GeometryReader { geometry in TabView(selection: $viewModel.currentPlayerViewModelId) { ForEach(viewModel.videos) { playerViewModel in ReelVideoPlayerContainerView( isMuted: $viewModel.isMuted, playerViewModel: playerViewModel ) .rotationEffect(Angle(degrees: -90)) .frame(width: geometry.size.width) .foregroundStyle(Color(UIColor.textOnFill)) .ignoresSafeArea(.all, edges: .top) .tag(playerViewModel.id) } } .rotationEffect(Angle(degrees: 90)) .frame(width: geometry.size.height) .tabViewStyle(.page(indexDisplayMode: .never)) .frame(width: geometry.size.width) } .ignoresSafeArea(.all, edges: .top) ……
縦フリックのできる動画画面の実装 var body: some View { ZStack { GeometryReader { geometry in TabView(selection: $viewModel.currentPlayerViewModelId) { ForEach(viewModel.videos) { playerViewModel in ReelVideoPlayerContainerView( isMuted: $viewModel.isMuted, playerViewModel: playerViewModel ) .rotationEffect(Angle(degrees: -90)) .frame(width: geometry.size.width) .foregroundStyle(Color(UIColor.textOnFill)) .ignoresSafeArea(.all, edges: .top) .tag(playerViewModel.id) } } .rotationEffect(Angle(degrees: 90)) .frame(width: geometry.size.height) .tabViewStyle(.page(indexDisplayMode: .never)) .frame(width: geometry.size.width) } .ignoresSafeArea(.all, edges: .top) ……
縦フリックのできる動画画面の実装
struct ReelVideoPlayerView: UIViewControllerRepresentable {
@ObservedObject var playerViewModel: ReelVideoPlayerViewModel
func makeUIViewController(context: Context) -> ReelVideoPlayerViewController {
DebugLogger.print("生成_\(playerViewModel.video.id)")
let controller = ReelVideoPlayerViewController.instantiate(
video: playerViewModel.video,
referrer: playerViewModel.referrer,
contentType: playerViewModel.contentType
)
return controller
}
func updateUIViewController(_ uiViewController: ReelVideoPlayerViewController, context: Context)
{
guard let videoControlEvent = playerViewModel.videoControlEvent else { return }
switch videoControlEvent {
case .videoPlay:
uiViewController.play()
……
}
static func dismantleUIViewController(
_ uiViewController: ReelVideoPlayerViewController,
coordinator: Coordinator
) {
DebugLogger.print("解放_\(uiViewController.video?.id ?? 0)")
}
}
Playerの生成と破棄 解放 コンテンツ コンテンツ TabView ・・・・・ コンテンツ コンテンツ コンテンツ 生成 コンテンツ
まとめ • SwiftUIのTabViewを使ったことで簡単に縦フリックできる動画画面が実装で きました • 今後TabViewでverticalPageが使えるようになれば、シンプルな実装に置き 換えられるようになる
参考 • https://github.com/dervisyilm/inReels/blob/main/inReels/inReels/ View/Home.swift
ご清聴ありがとうございました