ContextMenuController.swift 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import AVKit
  2. import AVFoundation
  3. import SDWebImage
  4. import DcCore
  5. class ContextMenuController: UIViewController {
  6. let item: GalleryItem
  7. init(item: GalleryItem) {
  8. self.item = item
  9. super.init(nibName: nil, bundle: nil)
  10. }
  11. required init?(coder: NSCoder) {
  12. fatalError("init(coder:) has not been implemented")
  13. }
  14. // MARK: - lifecycle
  15. override func viewDidLoad() {
  16. super.viewDidLoad()
  17. let viewType = item.msg.viewtype
  18. var thumbnailView: UIView?
  19. switch viewType {
  20. case .image:
  21. thumbnailView = makeImageView(image: item.msg.image)
  22. case .video:
  23. thumbnailView = makeVideoView(videoUrl: item.msg.fileURL)
  24. case .gif:
  25. thumbnailView = makeGifView(gifImage: item.thumbnailImage)
  26. default:
  27. return
  28. }
  29. guard let contentView = thumbnailView else {
  30. return
  31. }
  32. view.addSubview(contentView)
  33. contentView.translatesAutoresizingMaskIntoConstraints = false
  34. NSLayoutConstraint.activate([
  35. contentView.leftAnchor.constraint(equalTo: view.leftAnchor),
  36. contentView.rightAnchor.constraint(equalTo: view.rightAnchor),
  37. contentView.topAnchor.constraint(equalTo: view.topAnchor),
  38. contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
  39. ])
  40. }
  41. private func makeGifView(gifImage: UIImage?) -> UIView? {
  42. let view = SDAnimatedImageView()
  43. view.contentMode = .scaleAspectFill
  44. view.clipsToBounds = true
  45. view.backgroundColor = DcColors.defaultBackgroundColor
  46. if let image = gifImage {
  47. setPreferredContentSize(for: image)
  48. }
  49. view.image = gifImage
  50. return view
  51. }
  52. private func makeImageView(image: UIImage?) -> UIView? {
  53. guard let image = image else {
  54. safe_fatalError("unexpected nil value")
  55. return nil
  56. }
  57. let imageView = UIImageView()
  58. imageView.clipsToBounds = true
  59. imageView.contentMode = .scaleAspectFill
  60. imageView.image = image
  61. setPreferredContentSize(for: image)
  62. return imageView
  63. }
  64. private func makeVideoView(videoUrl: URL?) -> UIView? {
  65. guard let videoUrl = videoUrl, let videoSize = item.thumbnailImage?.size else { return nil }
  66. let player = AVPlayer(url: videoUrl)
  67. let playerController = AVPlayerViewController()
  68. addChild(playerController)
  69. view.addSubview(playerController.view)
  70. playerController.didMove(toParent: self)
  71. playerController.view.backgroundColor = .darkGray
  72. playerController.view.clipsToBounds = true
  73. player.play()
  74. playerController.player = player
  75. // truncate edges on top/bottom or sides
  76. let resizedHeightFactor = view.frame.height / videoSize.height
  77. let resizedWidthFactor = view.frame.width / videoSize.width
  78. let effectiveResizeFactor = min(resizedWidthFactor, resizedHeightFactor)
  79. let maxHeight = videoSize.height * effectiveResizeFactor
  80. let maxWidth = videoSize.width * effectiveResizeFactor
  81. let size = CGSize(width: maxWidth, height: maxHeight)
  82. preferredContentSize = size
  83. return playerController.view
  84. }
  85. private func setPreferredContentSize(for image: UIImage) {
  86. let width = view.bounds.width
  87. let height = image.size.height * (width / image.size.width)
  88. self.preferredContentSize = CGSize(width: width, height: height)
  89. }
  90. }