Add compose attachments preview

This commit is contained in:
Shadowfacts 2020-03-15 14:25:02 -04:00
parent 64f41ea2b7
commit 9ed05de3ee
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
3 changed files with 80 additions and 30 deletions

View File

@ -177,10 +177,11 @@ class AssetCollectionViewController: UICollectionViewController {
}
override func collectionView(_ collectionView: UICollectionView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
if let indexPath = (configuration.identifier as? NSIndexPath) as IndexPath?, let cell = collectionView.cellForItem(at: indexPath) {
if let indexPath = (configuration.identifier as? NSIndexPath) as IndexPath?,
let cell = collectionView.cellForItem(at: indexPath) as? AssetCollectionViewCell {
let parameters = UIPreviewParameters()
parameters.backgroundColor = .black
return UITargetedPreview(view: cell, parameters: parameters)
return UITargetedPreview(view: cell.imageView, parameters: parameters)
} else {
return nil
}

View File

@ -13,14 +13,18 @@ import AVKit
class AssetPreviewViewController: UIViewController {
let asset: PHAsset
let attachment: CompositionAttachmentData
init(asset: PHAsset) {
self.asset = asset
init(attachment: CompositionAttachmentData) {
self.attachment = attachment
super.init(nibName: nil, bundle: nil)
}
convenience init(asset: PHAsset) {
self.init(attachment: .asset(asset))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@ -30,21 +34,29 @@ class AssetPreviewViewController: UIViewController {
view.backgroundColor = .black
if asset.mediaType == .image {
if asset.mediaSubtypes.contains(.photoLive) {
showLivePhoto()
} else {
showImage()
switch attachment {
case let .image(image):
showImage(image)
case let .video(url):
showVideo(asset: AVURLAsset(url: url))
case let .asset(asset):
switch asset.mediaType {
case .image:
if asset.mediaSubtypes.contains(.photoLive) {
showLivePhoto(asset)
} else {
showAssetImage(asset)
}
case .video:
showAssetVideo(asset)
default:
fatalError("asset mediaType must be image or video")
}
} else if asset.mediaType == .video {
playVideo()
} else {
fatalError("asset mediaType must be image or video")
}
}
func showImage() {
let imageView = UIImageView()
func showImage(_ image: UIImage) {
let imageView = UIImageView(image: image)
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
view.addSubview(imageView)
@ -54,7 +66,10 @@ class AssetPreviewViewController: UIViewController {
imageView.topAnchor.constraint(equalTo: view.topAnchor),
imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
preferredContentSize = image.size
}
func showAssetImage(_ asset: PHAsset) {
let options = PHImageRequestOptions()
options.version = .current
options.deliveryMode = .opportunistic
@ -62,13 +77,12 @@ class AssetPreviewViewController: UIViewController {
options.isNetworkAccessAllowed = true
PHImageManager.default().requestImage(for: asset, targetSize: view.bounds.size, contentMode: .aspectFit, options: options) { (image, _) in
DispatchQueue.main.async {
imageView.image = image
self.preferredContentSize = image!.size
self.showImage(image!)
}
}
}
func showLivePhoto() {
func showLivePhoto(_ asset: PHAsset) {
let options = PHLivePhotoRequestOptions()
options.deliveryMode = .opportunistic
options.version = .current
@ -96,7 +110,18 @@ class AssetPreviewViewController: UIViewController {
}
}
func playVideo() {
func showVideo(asset: AVAsset) {
let playerController = AVPlayerViewController()
let item = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: item)
player.isMuted = true
player.play()
playerController.player = player
self.embedChild(playerController)
self.preferredContentSize = item.presentationSize
}
func showAssetVideo(_ asset: PHAsset) {
let options = PHVideoRequestOptions()
options.deliveryMode = .automatic
options.isNetworkAccessAllowed = true
@ -106,14 +131,7 @@ class AssetPreviewViewController: UIViewController {
fatalError("failed to get AVAsset")
}
DispatchQueue.main.async {
let playerController = AVPlayerViewController()
let item = AVPlayerItem(asset: avAsset)
let player = AVPlayer(playerItem: item)
player.isMuted = true
player.play()
playerController.player = player
self.embedChild(playerController)
self.preferredContentSize = item.presentationSize
self.showVideo(asset: avAsset)
}
}
}

View File

@ -265,6 +265,37 @@ class ComposeAttachmentsViewController: UITableViewController {
}
}
override func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
let attachment = attachments[indexPath.row]
// cast to NSIndexPath because identifier needs to conform to NSCopying
return UIContextMenuConfiguration(identifier: indexPath as NSIndexPath, previewProvider: { () -> UIViewController? in
return AssetPreviewViewController(attachment: attachment.data)
}) { (_) -> UIMenu? in
return nil
}
}
private func targetedPreview(forConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
if let indexPath = (configuration.identifier as? NSIndexPath) as IndexPath?,
let cell = tableView.cellForRow(at: indexPath) as? ComposeAttachmentTableViewCell {
let parameters = UIPreviewParameters()
parameters.backgroundColor = .black
return UITargetedPreview(view: cell.assetImageView, parameters: parameters)
} else {
return nil
}
}
override func tableView(_ tableView: UITableView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
return targetedPreview(forConfiguration: configuration)
}
override func tableView(_ tableView: UITableView, previewForDismissingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
return targetedPreview(forConfiguration: configuration)
}
// MARK: Interaction
func addAttachmentPressed() {
let sheetContainer = AssetPickerSheetContainerViewController()
sheetContainer.assetPicker.assetPickerDelegate = self