Tusker/Tusker/Screens/Gallery/GalleryViewController.swift

141 lines
4.7 KiB
Swift

// GalleryViewController.swift
// Tusker
//
// Created by Shadowfacts on 6/13/19.
// Copyright © 2019 Shadowfacts. All rights reserved.
//
import UIKit
import Pachyderm
import AVFoundation
import AVKit
class GalleryViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var dismissInteractionController: LargeImageInteractionController?
let attachments: [Attachment]
let sourcesInfo: [LargeImageViewController.SourceInfo?]
let startIndex: Int
let pages: [UIViewController]
var currentIndex: Int {
guard let vc = viewControllers?.first,
let index = pages.firstIndex(of: vc) else {
fatalError()
}
return index
}
override var prefersStatusBarHidden: Bool {
return true
}
override var childForHomeIndicatorAutoHidden: UIViewController? {
return viewControllers?.first
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .phone {
return .allButUpsideDown
} else {
return .all
}
}
init(attachments: [Attachment], sourcesInfo: [LargeImageViewController.SourceInfo?], startIndex: Int) {
self.attachments = attachments
self.sourcesInfo = sourcesInfo
self.startIndex = startIndex
self.pages = attachments.map {
switch $0.kind {
case .image:
return AttachmentViewController(attachment: $0)
case .video, .audio:
let vc = AVPlayerViewController()
vc.player = AVPlayer(url: $0.url)
return vc
default:
fatalError()
}
}
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal)
setViewControllers([pages[startIndex]], direction: .forward, animated: false)
modalPresentationStyle = .fullScreen
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
self.delegate = self
overrideUserInterfaceStyle = .dark
dismissInteractionController = LargeImageInteractionController(viewController: self)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let vc = pages[currentIndex] as? AVPlayerViewController {
// when the gallery is first shown, after the transition finishes, the controls for the player controller appear semi-transparent
// hiding the controls and then immediately reshowing them makes sure they're visible when the gallery is presented
vc.showsPlaybackControls = false
vc.showsPlaybackControls = true
// begin playing the video as soon as we appear
vc.player?.play()
}
}
func imageForDismissalAnimation() -> UIImage? {
if let sourceImage = sourcesInfo[currentIndex]?.image {
return sourceImage
} else {
return (pages[currentIndex] as? AttachmentViewController)?.largeImageVC?.image
}
}
// MARK: - Page View Controller Data Source
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let index = pages.firstIndex(of: viewController),
index > 0 else {
return nil
}
return pages[index - 1]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let index = pages.firstIndex(of: viewController),
index < pages.count - 1 else {
return nil
}
return pages[index + 1]
}
// MARK: - Page View Controller Delegate
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
if let pending = pendingViewControllers.first as? AttachmentViewController,
let current = viewControllers!.first as? AttachmentViewController {
pending.controlsVisible = current.controlsVisible
}
if let pending = pendingViewControllers.first as? AVPlayerViewController {
// show controls and begin playing when the player page becomes visible
pending.showsPlaybackControls = true
pending.player?.play()
}
}
}